From 7a6e793813203238379ba42bf5490df558809641 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Sat, 5 Jul 2014 00:28:24 +0200 Subject: [PATCH 01/18] Regex: Add PCRE 8.32 in tools directory. --- tools/pcre/132html | 313 + tools/pcre/AUTHORS | 45 + tools/pcre/CMakeLists.txt | 959 + tools/pcre/COPYING | 5 + tools/pcre/ChangeLog | 4981 ++++ tools/pcre/CheckMan | 67 + tools/pcre/CleanTxt | 113 + tools/pcre/Detrail | 35 + tools/pcre/HACKING | 473 + tools/pcre/INSTALL | 370 + tools/pcre/LICENCE | 92 + tools/pcre/Makefile.am | 877 + tools/pcre/Makefile.in | 2917 +++ tools/pcre/NEWS | 611 + tools/pcre/NON-AUTOTOOLS-BUILD | 639 + tools/pcre/NON-UNIX-USE | 7 + tools/pcre/PrepareRelease | 253 + tools/pcre/README | 935 + tools/pcre/RunGrepTest | 551 + tools/pcre/RunTest | 1015 + tools/pcre/RunTest.bat | 616 + tools/pcre/aclocal.m4 | 1270 + tools/pcre/cmake/COPYING-CMAKE-SCRIPTS | 22 + tools/pcre/cmake/FindEditline.cmake | 17 + .../cmake/FindPackageHandleStandardArgs.cmake | 58 + tools/pcre/cmake/FindReadline.cmake | 29 + tools/pcre/compile | 343 + tools/pcre/config-cmake.h.in | 54 + tools/pcre/config.guess | 1552 ++ tools/pcre/config.h.generic | 392 + tools/pcre/config.h.in | 343 + tools/pcre/config.sub | 1804 ++ tools/pcre/configure | 21272 ++++++++++++++++ tools/pcre/configure.ac | 1082 + tools/pcre/depcomp | 708 + tools/pcre/dftables.c | 212 + tools/pcre/doc/html/index.html | 180 + tools/pcre/doc/html/pcre-config.html | 109 + tools/pcre/doc/html/pcre.html | 204 + tools/pcre/doc/html/pcre16.html | 383 + .../pcre/doc/html/pcre_assign_jit_stack.html | 76 + tools/pcre/doc/html/pcre_compile.html | 108 + tools/pcre/doc/html/pcre_compile2.html | 112 + tools/pcre/doc/html/pcre_config.html | 91 + .../doc/html/pcre_copy_named_substring.html | 65 + tools/pcre/doc/html/pcre_copy_substring.html | 61 + tools/pcre/doc/html/pcre_dfa_exec.html | 128 + tools/pcre/doc/html/pcre_exec.html | 110 + tools/pcre/doc/html/pcre_free_study.html | 46 + tools/pcre/doc/html/pcre_free_substring.html | 46 + .../doc/html/pcre_free_substring_list.html | 46 + tools/pcre/doc/html/pcre_fullinfo.html | 108 + .../doc/html/pcre_get_named_substring.html | 68 + .../pcre/doc/html/pcre_get_stringnumber.html | 57 + .../html/pcre_get_stringtable_entries.html | 60 + tools/pcre/doc/html/pcre_get_substring.html | 64 + .../doc/html/pcre_get_substring_list.html | 61 + tools/pcre/doc/html/pcre_jit_exec.html | 108 + tools/pcre/doc/html/pcre_jit_stack_alloc.html | 55 + tools/pcre/doc/html/pcre_jit_stack_free.html | 48 + tools/pcre/doc/html/pcre_maketables.html | 48 + .../html/pcre_pattern_to_host_byte_order.html | 58 + tools/pcre/doc/html/pcre_refcount.html | 51 + tools/pcre/doc/html/pcre_study.html | 68 + .../html/pcre_utf16_to_host_byte_order.html | 57 + tools/pcre/doc/html/pcre_version.html | 46 + tools/pcre/doc/html/pcreapi.html | 2786 ++ tools/pcre/doc/html/pcrebuild.html | 517 + tools/pcre/doc/html/pcrecallout.html | 243 + tools/pcre/doc/html/pcrecompat.html | 216 + tools/pcre/doc/html/pcrecpp.html | 368 + tools/pcre/doc/html/pcredemo.html | 426 + tools/pcre/doc/html/pcregrep.html | 757 + tools/pcre/doc/html/pcrejit.html | 458 + tools/pcre/doc/html/pcrelimits.html | 86 + tools/pcre/doc/html/pcrematching.html | 233 + tools/pcre/doc/html/pcrepartial.html | 474 + tools/pcre/doc/html/pcrepattern.html | 2953 +++ tools/pcre/doc/html/pcreperform.html | 195 + tools/pcre/doc/html/pcreposix.html | 292 + tools/pcre/doc/html/pcreprecompile.html | 158 + tools/pcre/doc/html/pcresample.html | 110 + tools/pcre/doc/html/pcrestack.html | 225 + tools/pcre/doc/html/pcresyntax.html | 521 + tools/pcre/doc/html/pcretest.html | 1082 + tools/pcre/doc/html/pcreunicode.html | 270 + tools/pcre/doc/index.html.src | 180 + tools/pcre/doc/pcre-config.1 | 92 + tools/pcre/doc/pcre-config.txt | 86 + tools/pcre/doc/pcre.3 | 202 + tools/pcre/doc/pcre.txt | 9909 +++++++ tools/pcre/doc/pcre16.3 | 390 + tools/pcre/doc/pcre32.3 | 389 + tools/pcre/doc/pcre_assign_jit_stack.3 | 61 + tools/pcre/doc/pcre_compile.3 | 98 + tools/pcre/doc/pcre_compile2.3 | 106 + tools/pcre/doc/pcre_config.3 | 76 + tools/pcre/doc/pcre_copy_named_substring.3 | 59 + tools/pcre/doc/pcre_copy_substring.3 | 52 + tools/pcre/doc/pcre_dfa_exec.3 | 125 + tools/pcre/doc/pcre_exec.3 | 103 + tools/pcre/doc/pcre_free_study.3 | 31 + tools/pcre/doc/pcre_free_substring.3 | 31 + tools/pcre/doc/pcre_free_substring_list.3 | 31 + tools/pcre/doc/pcre_fullinfo.3 | 95 + tools/pcre/doc/pcre_get_named_substring.3 | 62 + tools/pcre/doc/pcre_get_stringnumber.3 | 45 + tools/pcre/doc/pcre_get_stringtable_entries.3 | 48 + tools/pcre/doc/pcre_get_substring.3 | 55 + tools/pcre/doc/pcre_get_substring_list.3 | 49 + tools/pcre/doc/pcre_jit_exec.3 | 104 + tools/pcre/doc/pcre_jit_stack_alloc.3 | 45 + tools/pcre/doc/pcre_jit_stack_free.3 | 35 + tools/pcre/doc/pcre_maketables.3 | 33 + .../doc/pcre_pattern_to_host_byte_order.3 | 46 + tools/pcre/doc/pcre_refcount.3 | 36 + tools/pcre/doc/pcre_study.3 | 56 + .../pcre/doc/pcre_utf16_to_host_byte_order.3 | 46 + .../pcre/doc/pcre_utf32_to_host_byte_order.3 | 46 + tools/pcre/doc/pcre_version.3 | 31 + tools/pcre/doc/pcreapi.3 | 2823 ++ tools/pcre/doc/pcrebuild.3 | 520 + tools/pcre/doc/pcrecallout.3 | 214 + tools/pcre/doc/pcrecompat.3 | 185 + tools/pcre/doc/pcrecpp.3 | 348 + tools/pcre/doc/pcregrep.1 | 679 + tools/pcre/doc/pcregrep.txt | 740 + tools/pcre/doc/pcrejit.3 | 437 + tools/pcre/doc/pcrelimits.3 | 67 + tools/pcre/doc/pcrematching.3 | 206 + tools/pcre/doc/pcrepartial.3 | 445 + tools/pcre/doc/pcrepattern.3 | 2983 +++ tools/pcre/doc/pcreperform.3 | 177 + tools/pcre/doc/pcreposix.3 | 270 + tools/pcre/doc/pcreprecompile.3 | 151 + tools/pcre/doc/pcresample.3 | 99 + tools/pcre/doc/pcrestack.3 | 215 + tools/pcre/doc/pcresyntax.3 | 496 + tools/pcre/doc/pcretest.1 | 1079 + tools/pcre/doc/pcretest.txt | 1012 + tools/pcre/doc/pcreunicode.3 | 255 + tools/pcre/doc/perltest.txt | 42 + tools/pcre/install-sh | 527 + tools/pcre/libpcre.pc.in | 12 + tools/pcre/libpcre16.pc.in | 12 + tools/pcre/libpcre32.pc.in | 12 + tools/pcre/libpcrecpp.pc.in | 12 + tools/pcre/libpcreposix.pc.in | 13 + tools/pcre/ltmain.sh | 9636 +++++++ tools/pcre/m4/ax_pthread.m4 | 309 + tools/pcre/m4/libtool.m4 | 7844 ++++++ tools/pcre/m4/ltoptions.m4 | 369 + tools/pcre/m4/ltsugar.m4 | 123 + tools/pcre/m4/ltversion.m4 | 23 + tools/pcre/m4/lt~obsolete.m4 | 98 + tools/pcre/m4/pcre_visibility.m4 | 89 + tools/pcre/makevp.bat | 66 + tools/pcre/makevp_c.txt | 20 + tools/pcre/makevp_l.txt | 20 + tools/pcre/missing | 331 + tools/pcre/pcre-config.in | 133 + tools/pcre/pcre.h.generic | 653 + tools/pcre/pcre.h.in | 653 + tools/pcre/pcre16_byte_order.c | 45 + tools/pcre/pcre16_chartables.c | 45 + tools/pcre/pcre16_compile.c | 45 + tools/pcre/pcre16_config.c | 45 + tools/pcre/pcre16_dfa_exec.c | 45 + tools/pcre/pcre16_exec.c | 45 + tools/pcre/pcre16_fullinfo.c | 45 + tools/pcre/pcre16_get.c | 45 + tools/pcre/pcre16_globals.c | 45 + tools/pcre/pcre16_jit_compile.c | 45 + tools/pcre/pcre16_maketables.c | 45 + tools/pcre/pcre16_newline.c | 45 + tools/pcre/pcre16_ord2utf16.c | 90 + tools/pcre/pcre16_printint.c | 45 + tools/pcre/pcre16_refcount.c | 45 + tools/pcre/pcre16_string_utils.c | 45 + tools/pcre/pcre16_study.c | 45 + tools/pcre/pcre16_tables.c | 45 + tools/pcre/pcre16_ucd.c | 45 + tools/pcre/pcre16_utf16_utils.c | 130 + tools/pcre/pcre16_valid_utf16.c | 156 + tools/pcre/pcre16_version.c | 45 + tools/pcre/pcre16_xclass.c | 45 + tools/pcre/pcre32_byte_order.c | 45 + tools/pcre/pcre32_chartables.c | 45 + tools/pcre/pcre32_compile.c | 45 + tools/pcre/pcre32_config.c | 45 + tools/pcre/pcre32_dfa_exec.c | 45 + tools/pcre/pcre32_exec.c | 45 + tools/pcre/pcre32_fullinfo.c | 45 + tools/pcre/pcre32_get.c | 45 + tools/pcre/pcre32_globals.c | 45 + tools/pcre/pcre32_jit_compile.c | 45 + tools/pcre/pcre32_maketables.c | 45 + tools/pcre/pcre32_newline.c | 45 + tools/pcre/pcre32_ord2utf32.c | 82 + tools/pcre/pcre32_printint.c | 45 + tools/pcre/pcre32_refcount.c | 45 + tools/pcre/pcre32_string_utils.c | 45 + tools/pcre/pcre32_study.c | 45 + tools/pcre/pcre32_tables.c | 45 + tools/pcre/pcre32_ucd.c | 45 + tools/pcre/pcre32_utf32_utils.c | 141 + tools/pcre/pcre32_valid_utf32.c | 131 + tools/pcre/pcre32_version.c | 45 + tools/pcre/pcre32_xclass.c | 45 + tools/pcre/pcre_byte_order.c | 318 + tools/pcre/pcre_chartables.c.dist | 198 + tools/pcre/pcre_compile.c | 8386 ++++++ tools/pcre/pcre_config.c | 186 + tools/pcre/pcre_dfa_exec.c | 3582 +++ tools/pcre/pcre_exec.c | 7049 +++++ tools/pcre/pcre_fullinfo.c | 231 + tools/pcre/pcre_get.c | 662 + tools/pcre/pcre_globals.c | 84 + tools/pcre/pcre_internal.h | 2744 ++ tools/pcre/pcre_jit_compile.c | 8560 +++++++ tools/pcre/pcre_jit_test.c | 1614 ++ tools/pcre/pcre_maketables.c | 151 + tools/pcre/pcre_newline.c | 210 + tools/pcre/pcre_ord2utf8.c | 94 + tools/pcre/pcre_printint.c | 766 + tools/pcre/pcre_refcount.c | 92 + tools/pcre/pcre_scanner.cc | 199 + tools/pcre/pcre_scanner.h | 172 + tools/pcre/pcre_scanner_unittest.cc | 159 + tools/pcre/pcre_string_utils.c | 211 + tools/pcre/pcre_stringpiece.cc | 43 + tools/pcre/pcre_stringpiece.h.in | 179 + tools/pcre/pcre_stringpiece_unittest.cc | 150 + tools/pcre/pcre_study.c | 1562 ++ tools/pcre/pcre_tables.c | 655 + tools/pcre/pcre_ucd.c | 3298 +++ tools/pcre/pcre_valid_utf8.c | 312 + tools/pcre/pcre_version.c | 98 + tools/pcre/pcre_xclass.c | 198 + tools/pcre/pcrecpp.cc | 922 + tools/pcre/pcrecpp.h | 710 + tools/pcre/pcrecpp_internal.h | 71 + tools/pcre/pcrecpp_unittest.cc | 1291 + tools/pcre/pcrecpparg.h.in | 174 + tools/pcre/pcredemo.c | 406 + tools/pcre/pcregexp.pas | 845 + tools/pcre/pcregrep.c | 3180 +++ tools/pcre/pcreposix.c | 419 + tools/pcre/pcreposix.h | 146 + tools/pcre/pcretest.c | 5488 ++++ tools/pcre/perltest.pl | 237 + tools/pcre/sljit/sljitConfig.h | 110 + tools/pcre/sljit/sljitConfigInternal.h | 484 + tools/pcre/sljit/sljitExecAllocator.c | 289 + tools/pcre/sljit/sljitLir.c | 1766 ++ tools/pcre/sljit/sljitLir.h | 985 + tools/pcre/sljit/sljitNativeARM_Thumb2.c | 2008 ++ tools/pcre/sljit/sljitNativeARM_v5.c | 2515 ++ tools/pcre/sljit/sljitNativeMIPS_32.c | 404 + tools/pcre/sljit/sljitNativeMIPS_common.c | 1881 ++ tools/pcre/sljit/sljitNativePPC_32.c | 269 + tools/pcre/sljit/sljitNativePPC_64.c | 421 + tools/pcre/sljit/sljitNativePPC_common.c | 2014 ++ tools/pcre/sljit/sljitNativeSPARC_32.c | 164 + tools/pcre/sljit/sljitNativeSPARC_common.c | 1348 + tools/pcre/sljit/sljitNativeX86_32.c | 547 + tools/pcre/sljit/sljitNativeX86_64.c | 810 + tools/pcre/sljit/sljitNativeX86_common.c | 2836 ++ tools/pcre/sljit/sljitUtils.c | 332 + tools/pcre/testdata/grepbinary | Bin 0 -> 45 bytes tools/pcre/testdata/grepfilelist | 3 + tools/pcre/testdata/grepinput | 611 + tools/pcre/testdata/grepinput3 | 15 + tools/pcre/testdata/grepinput8 | 11 + tools/pcre/testdata/grepinputv | 4 + tools/pcre/testdata/grepinputx | 43 + tools/pcre/testdata/greplist | 7 + tools/pcre/testdata/grepoutput | 707 + tools/pcre/testdata/grepoutput8 | 12 + tools/pcre/testdata/grepoutputN | 16 + tools/pcre/testdata/greppatN4 | 2 + tools/pcre/testdata/saved16 | Bin 0 -> 70 bytes tools/pcre/testdata/saved16BE-1 | Bin 0 -> 402 bytes tools/pcre/testdata/saved16BE-2 | Bin 0 -> 336 bytes tools/pcre/testdata/saved16LE-1 | Bin 0 -> 402 bytes tools/pcre/testdata/saved16LE-2 | Bin 0 -> 336 bytes tools/pcre/testdata/saved32 | Bin 0 -> 100 bytes tools/pcre/testdata/saved32BE-1 | Bin 0 -> 544 bytes tools/pcre/testdata/saved32BE-2 | Bin 0 -> 448 bytes tools/pcre/testdata/saved32LE-1 | Bin 0 -> 544 bytes tools/pcre/testdata/saved32LE-2 | Bin 0 -> 448 bytes tools/pcre/testdata/saved8 | Bin 0 -> 61 bytes tools/pcre/testdata/testinput1 | 5306 ++++ tools/pcre/testdata/testinput10 | 1337 + tools/pcre/testdata/testinput11 | 135 + tools/pcre/testdata/testinput12 | 89 + tools/pcre/testdata/testinput13 | 9 + tools/pcre/testdata/testinput14 | 329 + tools/pcre/testdata/testinput15 | 430 + tools/pcre/testdata/testinput16 | 35 + tools/pcre/testdata/testinput17 | 296 + tools/pcre/testdata/testinput18 | 296 + tools/pcre/testdata/testinput19 | 22 + tools/pcre/testdata/testinput2 | 3813 +++ tools/pcre/testdata/testinput20 | 19 + tools/pcre/testdata/testinput21 | 16 + tools/pcre/testdata/testinput22 | 13 + tools/pcre/testdata/testinput23 | 16 + tools/pcre/testdata/testinput24 | 77 + tools/pcre/testdata/testinput25 | 32 + tools/pcre/testdata/testinput26 | 80 + tools/pcre/testdata/testinput3 | 95 + tools/pcre/testdata/testinput4 | 624 + tools/pcre/testdata/testinput5 | 772 + tools/pcre/testdata/testinput6 | 1319 + tools/pcre/testdata/testinput7 | 672 + tools/pcre/testdata/testinput8 | 4801 ++++ tools/pcre/testdata/testinput9 | 717 + tools/pcre/testdata/testinputEBC | 121 + tools/pcre/testdata/testoutput1 | 8798 +++++++ tools/pcre/testdata/testoutput10 | 2726 ++ tools/pcre/testdata/testoutput11-16 | 713 + tools/pcre/testdata/testoutput11-32 | 713 + tools/pcre/testdata/testoutput11-8 | 713 + tools/pcre/testdata/testoutput12 | 181 + tools/pcre/testdata/testoutput13 | 21 + tools/pcre/testdata/testoutput14 | 476 + tools/pcre/testdata/testoutput15 | 1269 + tools/pcre/testdata/testoutput16 | 121 + tools/pcre/testdata/testoutput17 | 505 + tools/pcre/testdata/testoutput18-16 | 1022 + tools/pcre/testdata/testoutput18-32 | 1019 + tools/pcre/testdata/testoutput19 | 88 + tools/pcre/testdata/testoutput2 | 12484 +++++++++ tools/pcre/testdata/testoutput20 | 27 + tools/pcre/testdata/testoutput21-16 | 90 + tools/pcre/testdata/testoutput21-32 | 90 + tools/pcre/testdata/testoutput22-16 | 71 + tools/pcre/testdata/testoutput22-32 | 71 + tools/pcre/testdata/testoutput23 | 42 + tools/pcre/testdata/testoutput24 | 145 + tools/pcre/testdata/testoutput25 | 79 + tools/pcre/testdata/testoutput26 | 148 + tools/pcre/testdata/testoutput3 | 169 + tools/pcre/testdata/testoutput4 | 1094 + tools/pcre/testdata/testoutput5 | 1849 ++ tools/pcre/testdata/testoutput6 | 2137 ++ tools/pcre/testdata/testoutput7 | 1473 ++ tools/pcre/testdata/testoutput8 | 8019 ++++++ tools/pcre/testdata/testoutput9 | 1371 + tools/pcre/testdata/testoutputEBC | 182 + tools/pcre/testdata/wintestinput3 | 91 + tools/pcre/testdata/wintestoutput3 | 166 + tools/pcre/ucp.h | 197 + 354 files changed, 256402 insertions(+) create mode 100644 tools/pcre/132html create mode 100644 tools/pcre/AUTHORS create mode 100644 tools/pcre/CMakeLists.txt create mode 100644 tools/pcre/COPYING create mode 100644 tools/pcre/ChangeLog create mode 100644 tools/pcre/CheckMan create mode 100644 tools/pcre/CleanTxt create mode 100644 tools/pcre/Detrail create mode 100644 tools/pcre/HACKING create mode 100644 tools/pcre/INSTALL create mode 100644 tools/pcre/LICENCE create mode 100644 tools/pcre/Makefile.am create mode 100644 tools/pcre/Makefile.in create mode 100644 tools/pcre/NEWS create mode 100644 tools/pcre/NON-AUTOTOOLS-BUILD create mode 100644 tools/pcre/NON-UNIX-USE create mode 100644 tools/pcre/PrepareRelease create mode 100644 tools/pcre/README create mode 100644 tools/pcre/RunGrepTest create mode 100644 tools/pcre/RunTest create mode 100644 tools/pcre/RunTest.bat create mode 100644 tools/pcre/aclocal.m4 create mode 100644 tools/pcre/cmake/COPYING-CMAKE-SCRIPTS create mode 100644 tools/pcre/cmake/FindEditline.cmake create mode 100644 tools/pcre/cmake/FindPackageHandleStandardArgs.cmake create mode 100644 tools/pcre/cmake/FindReadline.cmake create mode 100644 tools/pcre/compile create mode 100644 tools/pcre/config-cmake.h.in create mode 100644 tools/pcre/config.guess create mode 100644 tools/pcre/config.h.generic create mode 100644 tools/pcre/config.h.in create mode 100644 tools/pcre/config.sub create mode 100644 tools/pcre/configure create mode 100644 tools/pcre/configure.ac create mode 100644 tools/pcre/depcomp create mode 100644 tools/pcre/dftables.c create mode 100644 tools/pcre/doc/html/index.html create mode 100644 tools/pcre/doc/html/pcre-config.html create mode 100644 tools/pcre/doc/html/pcre.html create mode 100644 tools/pcre/doc/html/pcre16.html create mode 100644 tools/pcre/doc/html/pcre_assign_jit_stack.html create mode 100644 tools/pcre/doc/html/pcre_compile.html create mode 100644 tools/pcre/doc/html/pcre_compile2.html create mode 100644 tools/pcre/doc/html/pcre_config.html create mode 100644 tools/pcre/doc/html/pcre_copy_named_substring.html create mode 100644 tools/pcre/doc/html/pcre_copy_substring.html create mode 100644 tools/pcre/doc/html/pcre_dfa_exec.html create mode 100644 tools/pcre/doc/html/pcre_exec.html create mode 100644 tools/pcre/doc/html/pcre_free_study.html create mode 100644 tools/pcre/doc/html/pcre_free_substring.html create mode 100644 tools/pcre/doc/html/pcre_free_substring_list.html create mode 100644 tools/pcre/doc/html/pcre_fullinfo.html create mode 100644 tools/pcre/doc/html/pcre_get_named_substring.html create mode 100644 tools/pcre/doc/html/pcre_get_stringnumber.html create mode 100644 tools/pcre/doc/html/pcre_get_stringtable_entries.html create mode 100644 tools/pcre/doc/html/pcre_get_substring.html create mode 100644 tools/pcre/doc/html/pcre_get_substring_list.html create mode 100644 tools/pcre/doc/html/pcre_jit_exec.html create mode 100644 tools/pcre/doc/html/pcre_jit_stack_alloc.html create mode 100644 tools/pcre/doc/html/pcre_jit_stack_free.html create mode 100644 tools/pcre/doc/html/pcre_maketables.html create mode 100644 tools/pcre/doc/html/pcre_pattern_to_host_byte_order.html create mode 100644 tools/pcre/doc/html/pcre_refcount.html create mode 100644 tools/pcre/doc/html/pcre_study.html create mode 100644 tools/pcre/doc/html/pcre_utf16_to_host_byte_order.html create mode 100644 tools/pcre/doc/html/pcre_version.html create mode 100644 tools/pcre/doc/html/pcreapi.html create mode 100644 tools/pcre/doc/html/pcrebuild.html create mode 100644 tools/pcre/doc/html/pcrecallout.html create mode 100644 tools/pcre/doc/html/pcrecompat.html create mode 100644 tools/pcre/doc/html/pcrecpp.html create mode 100644 tools/pcre/doc/html/pcredemo.html create mode 100644 tools/pcre/doc/html/pcregrep.html create mode 100644 tools/pcre/doc/html/pcrejit.html create mode 100644 tools/pcre/doc/html/pcrelimits.html create mode 100644 tools/pcre/doc/html/pcrematching.html create mode 100644 tools/pcre/doc/html/pcrepartial.html create mode 100644 tools/pcre/doc/html/pcrepattern.html create mode 100644 tools/pcre/doc/html/pcreperform.html create mode 100644 tools/pcre/doc/html/pcreposix.html create mode 100644 tools/pcre/doc/html/pcreprecompile.html create mode 100644 tools/pcre/doc/html/pcresample.html create mode 100644 tools/pcre/doc/html/pcrestack.html create mode 100644 tools/pcre/doc/html/pcresyntax.html create mode 100644 tools/pcre/doc/html/pcretest.html create mode 100644 tools/pcre/doc/html/pcreunicode.html create mode 100644 tools/pcre/doc/index.html.src create mode 100644 tools/pcre/doc/pcre-config.1 create mode 100644 tools/pcre/doc/pcre-config.txt create mode 100644 tools/pcre/doc/pcre.3 create mode 100644 tools/pcre/doc/pcre.txt create mode 100644 tools/pcre/doc/pcre16.3 create mode 100644 tools/pcre/doc/pcre32.3 create mode 100644 tools/pcre/doc/pcre_assign_jit_stack.3 create mode 100644 tools/pcre/doc/pcre_compile.3 create mode 100644 tools/pcre/doc/pcre_compile2.3 create mode 100644 tools/pcre/doc/pcre_config.3 create mode 100644 tools/pcre/doc/pcre_copy_named_substring.3 create mode 100644 tools/pcre/doc/pcre_copy_substring.3 create mode 100644 tools/pcre/doc/pcre_dfa_exec.3 create mode 100644 tools/pcre/doc/pcre_exec.3 create mode 100644 tools/pcre/doc/pcre_free_study.3 create mode 100644 tools/pcre/doc/pcre_free_substring.3 create mode 100644 tools/pcre/doc/pcre_free_substring_list.3 create mode 100644 tools/pcre/doc/pcre_fullinfo.3 create mode 100644 tools/pcre/doc/pcre_get_named_substring.3 create mode 100644 tools/pcre/doc/pcre_get_stringnumber.3 create mode 100644 tools/pcre/doc/pcre_get_stringtable_entries.3 create mode 100644 tools/pcre/doc/pcre_get_substring.3 create mode 100644 tools/pcre/doc/pcre_get_substring_list.3 create mode 100644 tools/pcre/doc/pcre_jit_exec.3 create mode 100644 tools/pcre/doc/pcre_jit_stack_alloc.3 create mode 100644 tools/pcre/doc/pcre_jit_stack_free.3 create mode 100644 tools/pcre/doc/pcre_maketables.3 create mode 100644 tools/pcre/doc/pcre_pattern_to_host_byte_order.3 create mode 100644 tools/pcre/doc/pcre_refcount.3 create mode 100644 tools/pcre/doc/pcre_study.3 create mode 100644 tools/pcre/doc/pcre_utf16_to_host_byte_order.3 create mode 100644 tools/pcre/doc/pcre_utf32_to_host_byte_order.3 create mode 100644 tools/pcre/doc/pcre_version.3 create mode 100644 tools/pcre/doc/pcreapi.3 create mode 100644 tools/pcre/doc/pcrebuild.3 create mode 100644 tools/pcre/doc/pcrecallout.3 create mode 100644 tools/pcre/doc/pcrecompat.3 create mode 100644 tools/pcre/doc/pcrecpp.3 create mode 100644 tools/pcre/doc/pcregrep.1 create mode 100644 tools/pcre/doc/pcregrep.txt create mode 100644 tools/pcre/doc/pcrejit.3 create mode 100644 tools/pcre/doc/pcrelimits.3 create mode 100644 tools/pcre/doc/pcrematching.3 create mode 100644 tools/pcre/doc/pcrepartial.3 create mode 100644 tools/pcre/doc/pcrepattern.3 create mode 100644 tools/pcre/doc/pcreperform.3 create mode 100644 tools/pcre/doc/pcreposix.3 create mode 100644 tools/pcre/doc/pcreprecompile.3 create mode 100644 tools/pcre/doc/pcresample.3 create mode 100644 tools/pcre/doc/pcrestack.3 create mode 100644 tools/pcre/doc/pcresyntax.3 create mode 100644 tools/pcre/doc/pcretest.1 create mode 100644 tools/pcre/doc/pcretest.txt create mode 100644 tools/pcre/doc/pcreunicode.3 create mode 100644 tools/pcre/doc/perltest.txt create mode 100644 tools/pcre/install-sh create mode 100644 tools/pcre/libpcre.pc.in create mode 100644 tools/pcre/libpcre16.pc.in create mode 100644 tools/pcre/libpcre32.pc.in create mode 100644 tools/pcre/libpcrecpp.pc.in create mode 100644 tools/pcre/libpcreposix.pc.in create mode 100644 tools/pcre/ltmain.sh create mode 100644 tools/pcre/m4/ax_pthread.m4 create mode 100644 tools/pcre/m4/libtool.m4 create mode 100644 tools/pcre/m4/ltoptions.m4 create mode 100644 tools/pcre/m4/ltsugar.m4 create mode 100644 tools/pcre/m4/ltversion.m4 create mode 100644 tools/pcre/m4/lt~obsolete.m4 create mode 100644 tools/pcre/m4/pcre_visibility.m4 create mode 100644 tools/pcre/makevp.bat create mode 100644 tools/pcre/makevp_c.txt create mode 100644 tools/pcre/makevp_l.txt create mode 100644 tools/pcre/missing create mode 100644 tools/pcre/pcre-config.in create mode 100644 tools/pcre/pcre.h.generic create mode 100644 tools/pcre/pcre.h.in create mode 100644 tools/pcre/pcre16_byte_order.c create mode 100644 tools/pcre/pcre16_chartables.c create mode 100644 tools/pcre/pcre16_compile.c create mode 100644 tools/pcre/pcre16_config.c create mode 100644 tools/pcre/pcre16_dfa_exec.c create mode 100644 tools/pcre/pcre16_exec.c create mode 100644 tools/pcre/pcre16_fullinfo.c create mode 100644 tools/pcre/pcre16_get.c create mode 100644 tools/pcre/pcre16_globals.c create mode 100644 tools/pcre/pcre16_jit_compile.c create mode 100644 tools/pcre/pcre16_maketables.c create mode 100644 tools/pcre/pcre16_newline.c create mode 100644 tools/pcre/pcre16_ord2utf16.c create mode 100644 tools/pcre/pcre16_printint.c create mode 100644 tools/pcre/pcre16_refcount.c create mode 100644 tools/pcre/pcre16_string_utils.c create mode 100644 tools/pcre/pcre16_study.c create mode 100644 tools/pcre/pcre16_tables.c create mode 100644 tools/pcre/pcre16_ucd.c create mode 100644 tools/pcre/pcre16_utf16_utils.c create mode 100644 tools/pcre/pcre16_valid_utf16.c create mode 100644 tools/pcre/pcre16_version.c create mode 100644 tools/pcre/pcre16_xclass.c create mode 100644 tools/pcre/pcre32_byte_order.c create mode 100644 tools/pcre/pcre32_chartables.c create mode 100644 tools/pcre/pcre32_compile.c create mode 100644 tools/pcre/pcre32_config.c create mode 100644 tools/pcre/pcre32_dfa_exec.c create mode 100644 tools/pcre/pcre32_exec.c create mode 100644 tools/pcre/pcre32_fullinfo.c create mode 100644 tools/pcre/pcre32_get.c create mode 100644 tools/pcre/pcre32_globals.c create mode 100644 tools/pcre/pcre32_jit_compile.c create mode 100644 tools/pcre/pcre32_maketables.c create mode 100644 tools/pcre/pcre32_newline.c create mode 100644 tools/pcre/pcre32_ord2utf32.c create mode 100644 tools/pcre/pcre32_printint.c create mode 100644 tools/pcre/pcre32_refcount.c create mode 100644 tools/pcre/pcre32_string_utils.c create mode 100644 tools/pcre/pcre32_study.c create mode 100644 tools/pcre/pcre32_tables.c create mode 100644 tools/pcre/pcre32_ucd.c create mode 100644 tools/pcre/pcre32_utf32_utils.c create mode 100644 tools/pcre/pcre32_valid_utf32.c create mode 100644 tools/pcre/pcre32_version.c create mode 100644 tools/pcre/pcre32_xclass.c create mode 100644 tools/pcre/pcre_byte_order.c create mode 100644 tools/pcre/pcre_chartables.c.dist create mode 100644 tools/pcre/pcre_compile.c create mode 100644 tools/pcre/pcre_config.c create mode 100644 tools/pcre/pcre_dfa_exec.c create mode 100644 tools/pcre/pcre_exec.c create mode 100644 tools/pcre/pcre_fullinfo.c create mode 100644 tools/pcre/pcre_get.c create mode 100644 tools/pcre/pcre_globals.c create mode 100644 tools/pcre/pcre_internal.h create mode 100644 tools/pcre/pcre_jit_compile.c create mode 100644 tools/pcre/pcre_jit_test.c create mode 100644 tools/pcre/pcre_maketables.c create mode 100644 tools/pcre/pcre_newline.c create mode 100644 tools/pcre/pcre_ord2utf8.c create mode 100644 tools/pcre/pcre_printint.c create mode 100644 tools/pcre/pcre_refcount.c create mode 100644 tools/pcre/pcre_scanner.cc create mode 100644 tools/pcre/pcre_scanner.h create mode 100644 tools/pcre/pcre_scanner_unittest.cc create mode 100644 tools/pcre/pcre_string_utils.c create mode 100644 tools/pcre/pcre_stringpiece.cc create mode 100644 tools/pcre/pcre_stringpiece.h.in create mode 100644 tools/pcre/pcre_stringpiece_unittest.cc create mode 100644 tools/pcre/pcre_study.c create mode 100644 tools/pcre/pcre_tables.c create mode 100644 tools/pcre/pcre_ucd.c create mode 100644 tools/pcre/pcre_valid_utf8.c create mode 100644 tools/pcre/pcre_version.c create mode 100644 tools/pcre/pcre_xclass.c create mode 100644 tools/pcre/pcrecpp.cc create mode 100644 tools/pcre/pcrecpp.h create mode 100644 tools/pcre/pcrecpp_internal.h create mode 100644 tools/pcre/pcrecpp_unittest.cc create mode 100644 tools/pcre/pcrecpparg.h.in create mode 100644 tools/pcre/pcredemo.c create mode 100644 tools/pcre/pcregexp.pas create mode 100644 tools/pcre/pcregrep.c create mode 100644 tools/pcre/pcreposix.c create mode 100644 tools/pcre/pcreposix.h create mode 100644 tools/pcre/pcretest.c create mode 100644 tools/pcre/perltest.pl create mode 100644 tools/pcre/sljit/sljitConfig.h create mode 100644 tools/pcre/sljit/sljitConfigInternal.h create mode 100644 tools/pcre/sljit/sljitExecAllocator.c create mode 100644 tools/pcre/sljit/sljitLir.c create mode 100644 tools/pcre/sljit/sljitLir.h create mode 100644 tools/pcre/sljit/sljitNativeARM_Thumb2.c create mode 100644 tools/pcre/sljit/sljitNativeARM_v5.c create mode 100644 tools/pcre/sljit/sljitNativeMIPS_32.c create mode 100644 tools/pcre/sljit/sljitNativeMIPS_common.c create mode 100644 tools/pcre/sljit/sljitNativePPC_32.c create mode 100644 tools/pcre/sljit/sljitNativePPC_64.c create mode 100644 tools/pcre/sljit/sljitNativePPC_common.c create mode 100644 tools/pcre/sljit/sljitNativeSPARC_32.c create mode 100644 tools/pcre/sljit/sljitNativeSPARC_common.c create mode 100644 tools/pcre/sljit/sljitNativeX86_32.c create mode 100644 tools/pcre/sljit/sljitNativeX86_64.c create mode 100644 tools/pcre/sljit/sljitNativeX86_common.c create mode 100644 tools/pcre/sljit/sljitUtils.c create mode 100644 tools/pcre/testdata/grepbinary create mode 100644 tools/pcre/testdata/grepfilelist create mode 100644 tools/pcre/testdata/grepinput create mode 100644 tools/pcre/testdata/grepinput3 create mode 100644 tools/pcre/testdata/grepinput8 create mode 100644 tools/pcre/testdata/grepinputv create mode 100644 tools/pcre/testdata/grepinputx create mode 100644 tools/pcre/testdata/greplist create mode 100644 tools/pcre/testdata/grepoutput create mode 100644 tools/pcre/testdata/grepoutput8 create mode 100644 tools/pcre/testdata/grepoutputN create mode 100644 tools/pcre/testdata/greppatN4 create mode 100644 tools/pcre/testdata/saved16 create mode 100644 tools/pcre/testdata/saved16BE-1 create mode 100644 tools/pcre/testdata/saved16BE-2 create mode 100644 tools/pcre/testdata/saved16LE-1 create mode 100644 tools/pcre/testdata/saved16LE-2 create mode 100644 tools/pcre/testdata/saved32 create mode 100644 tools/pcre/testdata/saved32BE-1 create mode 100644 tools/pcre/testdata/saved32BE-2 create mode 100644 tools/pcre/testdata/saved32LE-1 create mode 100644 tools/pcre/testdata/saved32LE-2 create mode 100644 tools/pcre/testdata/saved8 create mode 100644 tools/pcre/testdata/testinput1 create mode 100644 tools/pcre/testdata/testinput10 create mode 100644 tools/pcre/testdata/testinput11 create mode 100644 tools/pcre/testdata/testinput12 create mode 100644 tools/pcre/testdata/testinput13 create mode 100644 tools/pcre/testdata/testinput14 create mode 100644 tools/pcre/testdata/testinput15 create mode 100644 tools/pcre/testdata/testinput16 create mode 100644 tools/pcre/testdata/testinput17 create mode 100644 tools/pcre/testdata/testinput18 create mode 100644 tools/pcre/testdata/testinput19 create mode 100644 tools/pcre/testdata/testinput2 create mode 100644 tools/pcre/testdata/testinput20 create mode 100644 tools/pcre/testdata/testinput21 create mode 100644 tools/pcre/testdata/testinput22 create mode 100644 tools/pcre/testdata/testinput23 create mode 100644 tools/pcre/testdata/testinput24 create mode 100644 tools/pcre/testdata/testinput25 create mode 100644 tools/pcre/testdata/testinput26 create mode 100644 tools/pcre/testdata/testinput3 create mode 100644 tools/pcre/testdata/testinput4 create mode 100644 tools/pcre/testdata/testinput5 create mode 100644 tools/pcre/testdata/testinput6 create mode 100644 tools/pcre/testdata/testinput7 create mode 100644 tools/pcre/testdata/testinput8 create mode 100644 tools/pcre/testdata/testinput9 create mode 100644 tools/pcre/testdata/testinputEBC create mode 100644 tools/pcre/testdata/testoutput1 create mode 100644 tools/pcre/testdata/testoutput10 create mode 100644 tools/pcre/testdata/testoutput11-16 create mode 100644 tools/pcre/testdata/testoutput11-32 create mode 100644 tools/pcre/testdata/testoutput11-8 create mode 100644 tools/pcre/testdata/testoutput12 create mode 100644 tools/pcre/testdata/testoutput13 create mode 100644 tools/pcre/testdata/testoutput14 create mode 100644 tools/pcre/testdata/testoutput15 create mode 100644 tools/pcre/testdata/testoutput16 create mode 100644 tools/pcre/testdata/testoutput17 create mode 100644 tools/pcre/testdata/testoutput18-16 create mode 100644 tools/pcre/testdata/testoutput18-32 create mode 100644 tools/pcre/testdata/testoutput19 create mode 100644 tools/pcre/testdata/testoutput2 create mode 100644 tools/pcre/testdata/testoutput20 create mode 100644 tools/pcre/testdata/testoutput21-16 create mode 100644 tools/pcre/testdata/testoutput21-32 create mode 100644 tools/pcre/testdata/testoutput22-16 create mode 100644 tools/pcre/testdata/testoutput22-32 create mode 100644 tools/pcre/testdata/testoutput23 create mode 100644 tools/pcre/testdata/testoutput24 create mode 100644 tools/pcre/testdata/testoutput25 create mode 100644 tools/pcre/testdata/testoutput26 create mode 100644 tools/pcre/testdata/testoutput3 create mode 100644 tools/pcre/testdata/testoutput4 create mode 100644 tools/pcre/testdata/testoutput5 create mode 100644 tools/pcre/testdata/testoutput6 create mode 100644 tools/pcre/testdata/testoutput7 create mode 100644 tools/pcre/testdata/testoutput8 create mode 100644 tools/pcre/testdata/testoutput9 create mode 100644 tools/pcre/testdata/testoutputEBC create mode 100644 tools/pcre/testdata/wintestinput3 create mode 100644 tools/pcre/testdata/wintestoutput3 create mode 100644 tools/pcre/ucp.h diff --git a/tools/pcre/132html b/tools/pcre/132html new file mode 100644 index 00000000..ccfbfd91 --- /dev/null +++ b/tools/pcre/132html @@ -0,0 +1,313 @@ +#! /usr/bin/perl -w + +# Script to turn PCRE man pages into HTML + + +# Subroutine to handle font changes and other escapes + +sub do_line { +my($s) = $_[0]; + +$s =~ s/ +$s =~ s/>/>/g; +$s =~ s"\\fI(.*?)\\f[RP]"$1"g; +$s =~ s"\\fB(.*?)\\f[RP]"$1"g; +$s =~ s"\\e"\\"g; +$s =~ s/(?<=Copyright )\(c\)/©/g; +$s; +} + +# Subroutine to ensure not in a paragraph + +sub end_para { +if ($inpara) + { + print TEMP "\n" if ($inpre); + print TEMP "

\n"; + } +$inpara = $inpre = 0; +$wrotetext = 0; +} + +# Subroutine to start a new paragraph + +sub new_para { +&end_para(); +print TEMP "

\n"; +$inpara = 1; +} + + +# Main program + +$innf = 0; +$inpara = 0; +$inpre = 0; +$wrotetext = 0; +$toc = 0; +$ref = 1; + +while ($#ARGV >= 0 && $ARGV[0] =~ /^-/) + { + $toc = 1 if $ARGV[0] eq "-toc"; + shift; + } + +# Initial output to STDOUT + +print < + +$ARGV[0] specification + + +

$ARGV[0] 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. +
+End + +print "

\n" if ($toc); + +# Copy the remainder to the standard output + +close(TEMP); +open(TEMP, "/tmp/$$") || die "Can't open /tmp/$$ for input\n"; + +print while (); + +print < +Return to the PCRE index page. +

+End + +close(TEMP); +unlink("/tmp/$$"); + +# End diff --git a/tools/pcre/AUTHORS b/tools/pcre/AUTHORS new file mode 100644 index 00000000..ba4753d8 --- /dev/null +++ b/tools/pcre/AUTHORS @@ -0,0 +1,45 @@ +THE MAIN PCRE LIBRARY +--------------------- + +Written by: Philip Hazel +Email local part: ph10 +Email domain: cam.ac.uk + +University of Cambridge Computing Service, +Cambridge, England. + +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-2012 Google Inc +All rights reserved + +#### diff --git a/tools/pcre/CMakeLists.txt b/tools/pcre/CMakeLists.txt new file mode 100644 index 00000000..17d50b7a --- /dev/null +++ b/tools/pcre/CMakeLists.txt @@ -0,0 +1,959 @@ +# CMakeLists.txt +# +# +# This file allows building PCRE with the CMake configuration and build +# tool. Download CMake in source or binary form from http://www.cmake.org/ +# +# Original listfile by Christian Ehrlicher +# Refined and expanded by Daniel Richard G. +# 2007-09-14 mod by Sheri so 7.4 supported configuration options can be entered +# 2007-09-19 Adjusted by PH to retain previous default settings +# 2007-12-26 (a) On UNIX, use names libpcre instead of just pcre +# (b) Ensure pcretest and pcregrep link with the local library, +# not a previously-installed one. +# (c) Add PCRE_SUPPORT_LIBREADLINE, PCRE_SUPPORT_LIBZ, and +# PCRE_SUPPORT_LIBBZ2. +# 2008-01-20 Brought up to date to include several new features by Christian +# Ehrlicher. +# 2008-01-22 Sheri added options for backward compatibility of library names +# when building with minGW: +# if "ON", NON_STANDARD_LIB_PREFIX causes shared libraries to +# be built without "lib" as prefix. (The libraries will be named +# pcre.dll, pcreposix.dll and pcrecpp.dll). +# if "ON", NON_STANDARD_LIB_SUFFIX causes shared libraries to +# be built with suffix of "-0.dll". (The libraries will be named +# libpcre-0.dll, libpcreposix-0.dll and libpcrecpp-0.dll - same names +# built by default with Configure and Make. +# 2008-01-23 PH removed the automatic build of pcredemo. +# 2008-04-22 PH modified READLINE support so it finds NCURSES when needed. +# 2008-07-03 PH updated for revised UCP property support (change of files) +# 2009-03-23 PH applied Steven Van Ingelgem's patch to change the name +# CMAKE_BINARY_DIR to PROJECT_BINARY_DIR so that it works when PCRE +# is included within another project. +# 2009-03-23 PH applied a modified version of Steven Van Ingelgem's patches to +# add options to stop the building of pcregrep and the tests, and +# to disable the final configuration report. +# 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 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 +# 2012-09-06 PH added support for PCRE_EBCDIC_NL25 +# 2012-09-08 ChPe added PCRE32 support +# 2012-10-23 PH added support for VALGRIND and GCOV + +PROJECT(PCRE C CXX) + +# 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 + +# external packages +FIND_PACKAGE( BZip2 ) +FIND_PACKAGE( ZLIB ) +FIND_PACKAGE( Readline ) +FIND_PACKAGE( Editline ) + +# Configuration checks + +INCLUDE(CheckIncludeFile) +INCLUDE(CheckIncludeFileCXX) +INCLUDE(CheckFunctionExists) +INCLUDE(CheckTypeSize) + +CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H) +CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H) +CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H) +CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H) +CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H) +CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) +CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H) + +CHECK_INCLUDE_FILE_CXX(type_traits.h HAVE_TYPE_TRAITS_H) +CHECK_INCLUDE_FILE_CXX(bits/type_traits.h HAVE_BITS_TYPE_TRAITS_H) + +CHECK_FUNCTION_EXISTS(bcopy HAVE_BCOPY) +CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE) +CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR) +CHECK_FUNCTION_EXISTS(strtoll HAVE_STRTOLL) +CHECK_FUNCTION_EXISTS(strtoq HAVE_STRTOQ) +CHECK_FUNCTION_EXISTS(_strtoi64 HAVE__STRTOI64) + +CHECK_TYPE_SIZE("long long" LONG_LONG) +CHECK_TYPE_SIZE("unsigned long long" UNSIGNED_LONG_LONG) + +# User-configurable options +# +# (Note: CMakeSetup displays these in alphabetical order, regardless of +# the order we use here) + +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_PCRE32 "Build 32 bit PCRE library" OFF) + +OPTION(PCRE_BUILD_PCRECPP "Build the PCRE C++ library (pcrecpp)." ON) + +SET(PCRE_EBCDIC OFF CACHE BOOL + "Use EBCDIC coding instead of ASCII. (This is rarely used outside of mainframe systems.)") + +SET(PCRE_EBCDIC_NL25 OFF CACHE BOOL + "Use 0x25 as EBCDIC NL character instead of 0x15; implies EBCDIC.") + +SET(PCRE_LINK_SIZE "2" CACHE STRING + "Internal link size (2, 3 or 4 allowed). See LINK_SIZE in config.h.in for details.") + +SET(PCRE_MATCH_LIMIT "10000000" CACHE STRING + "Default limit on internal looping. See MATCH_LIMIT in config.h.in for details.") + +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).") + +SET(PCRE_NO_RECURSE OFF CACHE BOOL + "If ON, then don't use stack recursion when matching. See NO_RECURSE in config.h.in for details.") + +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_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_UTF OFF CACHE BOOL + "Enable support for Unicode Transformation Format (UTF-8/UTF-16/UTF-32) 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") + +SET(PCRE_SUPPORT_VALGRIND OFF CACHE BOOL + "Enable Valgrind support.") + +SET(PCRE_SUPPORT_COVERAGE OFF CACHE BOOL + "Enable code coverage support using gcov.") + +OPTION(PCRE_SHOW_REPORT "Show the final configuration report" ON) +OPTION(PCRE_BUILD_PCREGREP "Build pcregrep" ON) +OPTION(PCRE_BUILD_TESTS "Build the tests" ON) + +IF (MINGW) + OPTION(NON_STANDARD_LIB_PREFIX + "ON=Shared libraries built in mingw will be named pcre.dll, etc., instead of libpcre.dll, etc." + OFF) + + OPTION(NON_STANDARD_LIB_SUFFIX + "ON=Shared libraries built in mingw will be named libpcre-0.dll, etc., instead of libpcre.dll, etc." + OFF) +ENDIF(MINGW) + +# bzip2 lib +IF(BZIP2_FOUND) + OPTION (PCRE_SUPPORT_LIBBZ2 "Enable support for linking pcregrep with libbz2." ON) +ENDIF(BZIP2_FOUND) +IF(PCRE_SUPPORT_LIBBZ2) + INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR}) +ENDIF(PCRE_SUPPORT_LIBBZ2) + +# zlib +IF(ZLIB_FOUND) + OPTION (PCRE_SUPPORT_LIBZ "Enable support for linking pcregrep with libz." ON) +ENDIF(ZLIB_FOUND) +IF(PCRE_SUPPORT_LIBZ) + 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) +ENDIF(READLINE_FOUND) +IF(PCRE_SUPPORT_LIBREADLINE) + INCLUDE_DIRECTORIES(${READLINE_INCLUDE_DIR}) +ENDIF(PCRE_SUPPORT_LIBREADLINE) + +# Prepare build configuration + +SET(pcre_have_type_traits 0) +SET(pcre_have_bits_type_traits 0) + +IF(HAVE_TYPE_TRAITS_H) + SET(pcre_have_type_traits 1) +ENDIF(HAVE_TYPE_TRAITS_H) + +IF(HAVE_BITS_TYPE_TRAITS_H) + SET(pcre_have_bits_type_traits 1) +ENDIF(HAVE_BITS_TYPE_TRAITS_H) + +SET(pcre_have_long_long 0) +SET(pcre_have_ulong_long 0) + +IF(HAVE_LONG_LONG) + SET(pcre_have_long_long 1) +ENDIF(HAVE_LONG_LONG) + +IF(HAVE_UNSIGNED_LONG_LONG) + SET(pcre_have_ulong_long 1) +ENDIF(HAVE_UNSIGNED_LONG_LONG) + +IF(NOT BUILD_SHARED_LIBS) + SET(PCRE_STATIC 1) +ENDIF(NOT BUILD_SHARED_LIBS) + +IF(NOT PCRE_BUILD_PCRE8 AND NOT PCRE_BUILD_PCRE16 AND NOT PCRE_BUILD_PCRE32) + MESSAGE(FATAL_ERROR "At least one of PCRE_BUILD_PCRE8, PCRE_BUILD_PCRE16 or PCRE_BUILD_PCRE32 must be enabled") +ENDIF(NOT PCRE_BUILD_PCRE8 AND NOT PCRE_BUILD_PCRE16 AND NOT PCRE_BUILD_PCRE32) + +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_PCRE32) + SET(SUPPORT_PCRE32 1) +ENDIF(PCRE_BUILD_PCRE32) + +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_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) + +IF(PCRE_SUPPORT_VALGRIND) + SET(SUPPORT_VALGRIND 1) +ENDIF(PCRE_SUPPORT_VALGRIND) + +IF(PCRE_SUPPORT_COVERAGE) + SET(SUPPORT_GCOV 1) + IF(NOT CMAKE_COMPILER_IS_GNUCC) + MESSAGE(FATAL_ERROR "Code coverage reports can only be generated when using GCC") + ENDIF(NOT CMAKE_COMPILER_IS_GNUCC) +ENDIF(PCRE_SUPPORT_COVERAGE) + +# This next one used to contain +# SET(PCRETEST_LIBS ${READLINE_LIBRARY}) +# but I was advised to add the NCURSES test as well, along with +# some modifications to cmake/FindReadline.cmake which should +# make it possible to override the default if necessary. PH + +IF(PCRE_SUPPORT_LIBREADLINE) + SET(SUPPORT_LIBREADLINE 1) + 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}) +ENDIF(PCRE_SUPPORT_LIBZ) + +IF(PCRE_SUPPORT_LIBBZ2) + SET(SUPPORT_LIBBZ2 1) + SET(PCREGREP_LIBS ${PCREGREP_LIBS} ${BZIP2_LIBRARIES}) +ENDIF(PCRE_SUPPORT_LIBBZ2) + +SET(NEWLINE "") + +IF(PCRE_NEWLINE STREQUAL "LF") + SET(NEWLINE "10") +ENDIF(PCRE_NEWLINE STREQUAL "LF") +IF(PCRE_NEWLINE STREQUAL "CR") + SET(NEWLINE "13") +ENDIF(PCRE_NEWLINE STREQUAL "CR") +IF(PCRE_NEWLINE STREQUAL "CRLF") + SET(NEWLINE "3338") +ENDIF(PCRE_NEWLINE STREQUAL "CRLF") +IF(PCRE_NEWLINE STREQUAL "ANY") + SET(NEWLINE "-1") +ENDIF(PCRE_NEWLINE STREQUAL "ANY") +IF(PCRE_NEWLINE STREQUAL "ANYCRLF") + SET(NEWLINE "-2") +ENDIF(PCRE_NEWLINE STREQUAL "ANYCRLF") + +IF(NEWLINE STREQUAL "") + MESSAGE(FATAL_ERROR "The PCRE_NEWLINE variable must be set to one of the following values: \"LF\", \"CR\", \"CRLF\", \"ANY\", \"ANYCRLF\".") +ENDIF(NEWLINE STREQUAL "") + +IF(PCRE_EBCDIC) + SET(EBCDIC 1) +IF(PCRE_NEWLINE STREQUAL "LF") + SET(NEWLINE "21") +ENDIF(PCRE_NEWLINE STREQUAL "LF") +IF(PCRE_NEWLINE STREQUAL "CRLF") + SET(NEWLINE "3349") +ENDIF(PCRE_NEWLINE STREQUAL "CRLF") +ENDIF(PCRE_EBCDIC) + +IF(PCRE_EBCDIC_NL25) + SET(EBCDIC 1) + SET(EBCDIC_NL25 1) +IF(PCRE_NEWLINE STREQUAL "LF") + SET(NEWLINE "37") +ENDIF(PCRE_NEWLINE STREQUAL "LF") +IF(PCRE_NEWLINE STREQUAL "CRLF") + SET(NEWLINE "3365") +ENDIF(PCRE_NEWLINE STREQUAL "CRLF") +ENDIF(PCRE_EBCDIC_NL25) + +IF(PCRE_NO_RECURSE) + SET(NO_RECURSE 1) +ENDIF(PCRE_NO_RECURSE) + +# Output files +CONFIGURE_FILE(config-cmake.h.in + ${PROJECT_BINARY_DIR}/config.h + @ONLY) + +# 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 + @ONLY) + +# What about pcre-config and libpcre.pc? + +IF(PCRE_BUILD_PCRECPP) + CONFIGURE_FILE(pcre_stringpiece.h.in + ${PROJECT_BINARY_DIR}/pcre_stringpiece.h + @ONLY) + + CONFIGURE_FILE(pcrecpparg.h.in + ${PROJECT_BINARY_DIR}/pcrecpparg.h + @ONLY) +ENDIF(PCRE_BUILD_PCRECPP) + +# Character table generation + +OPTION(PCRE_REBUILD_CHARTABLES "Rebuild char tables" OFF) +IF(PCRE_REBUILD_CHARTABLES) + ADD_EXECUTABLE(dftables dftables.c) + + GET_TARGET_PROPERTY(DFTABLES_EXE dftables LOCATION) + + ADD_CUSTOM_COMMAND( + COMMENT "Generating character tables (pcre_chartables.c) for current locale" + DEPENDS dftables + COMMAND ${DFTABLES_EXE} + ARGS ${PROJECT_BINARY_DIR}/pcre_chartables.c + OUTPUT ${PROJECT_BINARY_DIR}/pcre_chartables.c + ) +ELSE(PCRE_REBUILD_CHARTABLES) + CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/pcre_chartables.c.dist + ${PROJECT_BINARY_DIR}/pcre_chartables.c + COPYONLY) +ENDIF(PCRE_REBUILD_CHARTABLES) + +# Source code + +SET(PCRE_HEADERS ${PROJECT_BINARY_DIR}/pcre.h) + +IF(PCRE_BUILD_PCRE8) +SET(PCRE_SOURCES + 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_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 +) + +SET(PCREPOSIX_HEADERS pcreposix.h) + +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(PCRE_BUILD_PCRE32) +SET(PCRE32_SOURCES + pcre32_byte_order.c + pcre32_chartables.c + pcre32_compile.c + pcre32_config.c + pcre32_dfa_exec.c + pcre32_exec.c + pcre32_fullinfo.c + pcre32_get.c + pcre32_globals.c + pcre32_jit_compile.c + pcre32_maketables.c + pcre32_newline.c + pcre32_ord2utf32.c + pcre32_refcount.c + pcre32_string_utils.c + pcre32_study.c + pcre32_tables.c + pcre32_ucd.c + pcre32_utf32_utils.c + pcre32_valid_utf32.c + pcre32_version.c + pcre32_xclass.c +) +ENDIF(PCRE_BUILD_PCRE32) + +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 + ${PROJECT_BINARY_DIR}/pcrecpparg.h + ${PROJECT_BINARY_DIR}/pcre_stringpiece.h +) + +SET(PCRECPP_SOURCES + pcrecpp.cc + pcre_scanner.cc + pcre_stringpiece.cc +) + +# Build setup + +ADD_DEFINITIONS(-DHAVE_CONFIG_H) + +IF(MSVC) + ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE) +ENDIF(MSVC) + +SET(CMAKE_INCLUDE_CURRENT_DIR 1) +# needed to make sure to not link debug libs +# against release libs and vice versa +IF(WIN32) + SET(CMAKE_DEBUG_POSTFIX "d") +ENDIF(WIN32) + +SET(targets) + +# 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 + PROPERTIES PREFIX "" + ) + ENDIF(NON_STANDARD_LIB_PREFIX) + + IF(NON_STANDARD_LIB_SUFFIX) + SET_TARGET_PROPERTIES(pcre pcreposix + PROPERTIES SUFFIX "-0.dll" + ) + 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) + +IF(PCRE_BUILD_PCRE32) +ADD_LIBRARY(pcre32 ${PCRE_HEADERS} ${PCRE32_SOURCES} ${PROJECT_BINARY_DIR}/config.h) +SET(targets ${targets} pcre32) + +IF(MINGW AND NOT PCRE_STATIC) + IF(NON_STANDARD_LIB_PREFIX) + SET_TARGET_PROPERTIES(pcre32 + PROPERTIES PREFIX "" + ) + ENDIF(NON_STANDARD_LIB_PREFIX) + + IF(NON_STANDARD_LIB_SUFFIX) + SET_TARGET_PROPERTIES(pcre32 + PROPERTIES SUFFIX "-0.dll" + ) + ENDIF(NON_STANDARD_LIB_SUFFIX) +ENDIF(MINGW AND NOT PCRE_STATIC) + +ENDIF(PCRE_BUILD_PCRE32) + +# pcrecpp +IF(PCRE_BUILD_PCRECPP) +ADD_LIBRARY(pcrecpp ${PCRECPP_HEADERS} ${PCRECPP_SOURCES}) +SET(targets ${targets} pcrecpp) +TARGET_LINK_LIBRARIES(pcrecpp pcre) + + IF(MINGW AND NOT PCRE_STATIC) + IF(NON_STANDARD_LIB_PREFIX) + SET_TARGET_PROPERTIES(pcrecpp + PROPERTIES PREFIX "" + ) + ENDIF(NON_STANDARD_LIB_PREFIX) + + IF(NON_STANDARD_LIB_SUFFIX) + SET_TARGET_PROPERTIES(pcrecpp + PROPERTIES SUFFIX "-0.dll" + ) + ENDIF(NON_STANDARD_LIB_SUFFIX) + ENDIF(MINGW AND NOT PCRE_STATIC) +ENDIF(PCRE_BUILD_PCRECPP) + + +# Executables + +# Removed by PH (2008-01-23) because pcredemo shouldn't really be built +# automatically, and it gave trouble in some environments anyway. +# ADD_EXECUTABLE(pcredemo pcredemo.c) +# TARGET_LINK_LIBRARIES(pcredemo pcreposix) +# IF(NOT BUILD_SHARED_LIBS) +# # make sure to not use declspec(dllimport) in static mode on windows +# SET_TARGET_PROPERTIES(pcredemo PROPERTIES COMPILE_FLAGS "-DPCRE_STATIC") +# ENDIF(NOT BUILD_SHARED_LIBS) + +IF(PCRE_BUILD_PCREGREP) + ADD_EXECUTABLE(pcregrep pcregrep.c) + SET(targets ${targets} pcregrep) + TARGET_LINK_LIBRARIES(pcregrep pcreposix ${PCREGREP_LIBS}) +ENDIF(PCRE_BUILD_PCREGREP) + +# Testing +IF(PCRE_BUILD_TESTS) + ENABLE_TESTING() + + 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) + IF(PCRE_BUILD_PCRE32) + LIST(APPEND PCRETEST_SOURCES pcre32_printint.c) + ENDIF(PCRE_BUILD_PCRE32) + + ADD_EXECUTABLE(pcretest ${PCRETEST_SOURCES}) + SET(targets ${targets} pcretest) + 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) + IF(PCRE_BUILD_PCRE32) + LIST(APPEND PCRETEST_LIBS pcre32) + ENDIF(PCRE_BUILD_PCRE32) + 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) + IF(PCRE_BUILD_PCRE32) + LIST(APPEND PCRE_JIT_TEST_LIBS pcre32) + ENDIF(PCRE_BUILD_PCRE32) + 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) + SET(targets ${targets} pcrecpp_unittest) + TARGET_LINK_LIBRARIES(pcrecpp_unittest pcrecpp) + IF(MINGW AND NON_STANDARD_LIB_NAMES AND NOT PCRE_STATIC) + SET_TARGET_PROPERTIES(pcrecpp + PROPERTIES PREFIX "" + ) + 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) + + ADD_EXECUTABLE(pcre_stringpiece_unittest pcre_stringpiece_unittest.cc) + SET(targets ${targets} pcre_stringpiece_unittest) + TARGET_LINK_LIBRARIES(pcre_stringpiece_unittest pcrecpp) + ENDIF(PCRE_BUILD_PCRECPP) + + # 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 + # + FILE(WRITE ${PROJECT_BINARY_DIR}/CTestCustom.ctest + "# This is a generated file. +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 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) + # Provide environment for executing the bat file version of RunTest + FILE(TO_NATIVE_PATH ${PROJECT_SOURCE_DIR} winsrc) + FILE(TO_NATIVE_PATH ${PROJECT_BINARY_DIR} winbin) + FILE(TO_NATIVE_PATH ${PCRETEST_EXE} winexe) + + FILE(WRITE ${PROJECT_BINARY_DIR}/pcre_test.bat + "\@REM This is a generated file. +\@echo off +setlocal +SET srcdir=\"${winsrc}\" +SET pcretest=\"${winexe}\" +if not [%CMAKE_CONFIG_TYPE%]==[] SET pcretest=\"${winbin}\\%CMAKE_CONFIG_TYPE%\\pcretest.exe\" +call %srcdir%\\RunTest.Bat +if errorlevel 1 exit /b 1 +echo RunTest.bat tests successfully completed +") + + ADD_TEST(NAME pcre_test_bat + COMMAND pcre_test.bat) + 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) + + # 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 +SET(CMAKE_INSTALL_ALWAYS 1) + +INSTALL(TARGETS ${targets} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) + +INSTALL(FILES ${PCRE_HEADERS} ${PCREPOSIX_HEADERS} DESTINATION include) + +FILE(GLOB html ${PROJECT_SOURCE_DIR}/doc/html/*.html) +FILE(GLOB man1 ${PROJECT_SOURCE_DIR}/doc/*.1) +FILE(GLOB man3 ${PROJECT_SOURCE_DIR}/doc/*.3) + +IF(PCRE_BUILD_PCRECPP) + INSTALL(FILES ${PCRECPP_HEADERS} DESTINATION include) +ELSE(PCRE_BUILD_PCRECPP) + # Remove pcrecpp.3 + FOREACH(man ${man3}) + GET_FILENAME_COMPONENT(man_tmp ${man} NAME) + IF(NOT man_tmp STREQUAL "pcrecpp.3") + SET(man3_new ${man3} ${man}) + ENDIF(NOT man_tmp STREQUAL "pcrecpp.3") + ENDFOREACH(man ${man3}) + 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) + +# help, only for nice output +IF(BUILD_SHARED_LIBS) + SET(BUILD_STATIC_LIBS OFF) +ELSE(BUILD_SHARED_LIBS) + SET(BUILD_STATIC_LIBS ON) +ENDIF(BUILD_SHARED_LIBS) + +IF(PCRE_SHOW_REPORT) + STRING(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype) + IF (CMAKE_C_FLAGS) + SET(cfsp " ") + ENDIF(CMAKE_C_FLAGS) + IF (CMAKE_CXX_FLAGS) + SET(cxxfsp " ") + ENDIF(CMAKE_CXX_FLAGS) + MESSAGE(STATUS "") + MESSAGE(STATUS "") + MESSAGE(STATUS "PCRE configuration summary:") + MESSAGE(STATUS "") + MESSAGE(STATUS " Install prefix .................. : ${CMAKE_INSTALL_PREFIX}") + MESSAGE(STATUS " C compiler ...................... : ${CMAKE_C_COMPILER}") + MESSAGE(STATUS " C++ compiler .................... : ${CMAKE_CXX_COMPILER}") + 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 32 bit PCRE library ....... : ${PCRE_BUILD_PCRE32}") + MESSAGE(STATUS " Build C++ library ............... : ${PCRE_BUILD_PCRECPP}") + 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}") + MESSAGE(STATUS " EBCDIC coding ................... : ${PCRE_EBCDIC}") + MESSAGE(STATUS " EBCDIC coding with NL=0x25 ...... : ${PCRE_EBCDIC_NL25}") + MESSAGE(STATUS " Rebuild char tables ............. : ${PCRE_REBUILD_CHARTABLES}") + MESSAGE(STATUS " No stack recursion .............. : ${PCRE_NO_RECURSE}") + MESSAGE(STATUS " POSIX mem threshold ............. : ${PCRE_POSIX_MALLOC_THRESHOLD}") + MESSAGE(STATUS " Internal link size .............. : ${PCRE_LINK_SIZE}") + MESSAGE(STATUS " Match limit ..................... : ${PCRE_MATCH_LIMIT}") + MESSAGE(STATUS " Match limit recursion ........... : ${PCRE_MATCH_LIMIT_RECURSION}") + 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 " 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 ......... : 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 ....... : Library not found" ) + ENDIF(BZIP2_FOUND) + 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}") + ELSE(READLINE_FOUND) + MESSAGE(STATUS " Link pcretest with libreadline .. : Library not found" ) + ENDIF(READLINE_FOUND) + MESSAGE(STATUS " Support Valgrind .................: ${PCRE_SUPPORT_VALGRIND}") + MESSAGE(STATUS " Support coverage .................: ${PCRE_SUPPORT_COVERAGE}") + + 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}") + ENDIF(MINGW AND NOT PCRE_STATIC) + MESSAGE(STATUS "") +ENDIF(PCRE_SHOW_REPORT) + +# end CMakeLists.txt diff --git a/tools/pcre/COPYING b/tools/pcre/COPYING new file mode 100644 index 00000000..58eed01b --- /dev/null +++ b/tools/pcre/COPYING @@ -0,0 +1,5 @@ +PCRE LICENCE + +Please see the file LICENCE in the PCRE distribution for licensing details. + +End diff --git a/tools/pcre/ChangeLog b/tools/pcre/ChangeLog new file mode 100644 index 00000000..1b016ece --- /dev/null +++ b/tools/pcre/ChangeLog @@ -0,0 +1,4981 @@ +ChangeLog for PCRE +------------------ + +Version 8.32 30-November-2012 +----------------------------- + +1. Improved JIT compiler optimizations for first character search and single + character iterators. + +2. Supporting IBM XL C compilers for PPC architectures in the JIT compiler. + Patch by Daniel Richard G. + +3. Single character iterator optimizations in the JIT compiler. + +4. Improved JIT compiler optimizations for character ranges. + +5. Rename the "leave" variable names to "quit" to improve WinCE compatibility. + Reported by Giuseppe D'Angelo. + +6. The PCRE_STARTLINE bit, indicating that a match can occur only at the start + of a line, was being set incorrectly in cases where .* appeared inside + atomic brackets at the start of a pattern, or where there was a subsequent + *PRUNE or *SKIP. + +7. Improved instruction cache flush for POWER/PowerPC. + Patch by Daniel Richard G. + +8. Fixed a number of issues in pcregrep, making it more compatible with GNU + grep: + + (a) There is now no limit to the number of patterns to be matched. + + (b) An error is given if a pattern is too long. + + (c) Multiple uses of --exclude, --exclude-dir, --include, and --include-dir + are now supported. + + (d) --exclude-from and --include-from (multiple use) have been added. + + (e) Exclusions and inclusions now apply to all files and directories, not + just to those obtained from scanning a directory recursively. + + (f) Multiple uses of -f and --file-list are now supported. + + (g) In a Windows environment, the default for -d has been changed from + "read" (the GNU grep default) to "skip", because otherwise the presence + of a directory in the file list provokes an error. + + (h) The documentation has been revised and clarified in places. + +9. Improve the matching speed of capturing brackets. + +10. Changed the meaning of \X so that it now matches a Unicode extended + grapheme cluster. + +11. Patch by Daniel Richard G to the autoconf files to add a macro for sorting + out POSIX threads when JIT support is configured. + +12. Added support for PCRE_STUDY_EXTRA_NEEDED. + +13. In the POSIX wrapper regcomp() function, setting re_nsub field in the preg + structure could go wrong in environments where size_t is not the same size + as int. + +14. Applied user-supplied patch to pcrecpp.cc to allow PCRE_NO_UTF8_CHECK to be + set. + +15. The EBCDIC support had decayed; later updates to the code had included + explicit references to (e.g.) \x0a instead of CHAR_LF. There has been a + general tidy up of EBCDIC-related issues, and the documentation was also + not quite right. There is now a test that can be run on ASCII systems to + check some of the EBCDIC-related things (but is it not a full test). + +16. The new PCRE_STUDY_EXTRA_NEEDED option is now used by pcregrep, resulting + in a small tidy to the code. + +17. Fix JIT tests when UTF is disabled and both 8 and 16 bit mode are enabled. + +18. If the --only-matching (-o) option in pcregrep is specified multiple + times, each one causes appropriate output. For example, -o1 -o2 outputs the + substrings matched by the 1st and 2nd capturing parentheses. A separating + string can be specified by --om-separator (default empty). + +19. Improving the first n character searches. + +20. Turn case lists for horizontal and vertical white space into macros so that + they are defined only once. + +21. This set of changes together give more compatible Unicode case-folding + behaviour for characters that have more than one other case when UCP + support is available. + + (a) The Unicode property table now has offsets into a new table of sets of + three or more characters that are case-equivalent. The MultiStage2.py + script that generates these tables (the pcre_ucd.c file) now scans + CaseFolding.txt instead of UnicodeData.txt for character case + information. + + (b) The code for adding characters or ranges of characters to a character + class has been abstracted into a generalized function that also handles + case-independence. In UTF-mode with UCP support, this uses the new data + to handle characters with more than one other case. + + (c) A bug that is fixed as a result of (b) is that codepoints less than 256 + whose other case is greater than 256 are now correctly matched + caselessly. Previously, the high codepoint matched the low one, but not + vice versa. + + (d) The processing of \h, \H, \v, and \ in character classes now makes use + of the new class addition function, using character lists defined as + macros alongside the case definitions of 20 above. + + (e) Caseless back references now work with characters that have more than + one other case. + + (f) General caseless matching of characters with more than one other case + is supported. + +22. Unicode character properties were updated from Unicode 6.2.0 + +23. Improved CMake support under Windows. Patch by Daniel Richard G. + +24. Add support for 32-bit character strings, and UTF-32 + +25. Major JIT compiler update (code refactoring and bugfixing). + Experimental Sparc 32 support is added. + +26. Applied a modified version of Daniel Richard G's patch to create + pcre.h.generic and config.h.generic by "make" instead of in the + PrepareRelease script. + +27. Added a definition for CHAR_NULL (helpful for the z/OS port), and use it in + pcre_compile.c when checking for a zero character. + +28. Introducing a native interface for JIT. Through this interface, the compiled + machine code can be directly executed. The purpose of this interface is to + provide fast pattern matching, so several sanity checks are not performed. + However, feature tests are still performed. The new interface provides + 1.4x speedup compared to the old one. + +29. If pcre_exec() or pcre_dfa_exec() was called with a negative value for + the subject string length, the error given was PCRE_ERROR_BADOFFSET, which + was confusing. There is now a new error PCRE_ERROR_BADLENGTH for this case. + +30. In 8-bit UTF-8 mode, pcretest failed to give an error for data codepoints + greater than 0x7fffffff (which cannot be represented in UTF-8, even under + the "old" RFC 2279). Instead, it ended up passing a negative length to + pcre_exec(). + +31. Add support for GCC's visibility feature to hide internal functions. + +32. Running "pcretest -C pcre8" or "pcretest -C pcre16" gave a spurious error + "unknown -C option" after outputting 0 or 1. + +33. There is now support for generating a code coverage report for the test + suite in environments where gcc is the compiler and lcov is installed. This + is mainly for the benefit of the developers. + +34. If PCRE is built with --enable-valgrind, certain memory regions are marked + unaddressable using valgrind annotations, allowing valgrind to detect + invalid memory accesses. This is mainly for the benefit of the developers. + +25. (*UTF) can now be used to start a pattern in any of the three libraries. + +26. Give configure error if --enable-cpp but no C++ compiler found. + + +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 +------------------------ + +1. Fixed some typos in the markup of the man pages, and wrote a script that + checks for such things as part of the documentation building process. + +2. On a big-endian 64-bit system, pcregrep did not correctly process the + --match-limit and --recursion-limit options (added for 8.11). In + particular, this made one of the standard tests fail. (The integer value + went into the wrong half of a long int.) + +3. If the --colour option was given to pcregrep with -v (invert match), it + did strange things, either producing crazy output, or crashing. It should, + of course, ignore a request for colour when reporting lines that do not + match. + +4. Another pcregrep bug caused similar problems if --colour was specified with + -M (multiline) and the pattern match finished with a line ending. + +5. In pcregrep, when a pattern that ended with a literal newline sequence was + matched in multiline mode, the following line was shown as part of the + match. This seems wrong, so I have changed it. + +6. Another pcregrep bug in multiline mode, when --colour was specified, caused + the check for further matches in the same line (so they could be coloured) + to overrun the end of the current line. If another match was found, it was + incorrectly shown (and then shown again when found in the next line). + +7. If pcregrep was compiled under Windows, there was a reference to the + function pcregrep_exit() before it was defined. I am assuming this was + the cause of the "error C2371: 'pcregrep_exit' : redefinition;" that was + reported by a user. I've moved the definition above the reference. + + +Version 8.11 10-Dec-2010 +------------------------ + +1. (*THEN) was not working properly if there were untried alternatives prior + to it in the current branch. For example, in ((a|b)(*THEN)(*F)|c..) it + backtracked to try for "b" instead of moving to the next alternative branch + at the same level (in this case, to look for "c"). The Perl documentation + is clear that when (*THEN) is backtracked onto, it goes to the "next + alternative in the innermost enclosing group". + +2. (*COMMIT) was not overriding (*THEN), as it does in Perl. In a pattern + such as (A(*COMMIT)B(*THEN)C|D) any failure after matching A should + result in overall failure. Similarly, (*COMMIT) now overrides (*PRUNE) and + (*SKIP), (*SKIP) overrides (*PRUNE) and (*THEN), and (*PRUNE) overrides + (*THEN). + +3. If \s appeared in a character class, it removed the VT character from + the class, even if it had been included by some previous item, for example + in [\x00-\xff\s]. (This was a bug related to the fact that VT is not part + of \s, but is part of the POSIX "space" class.) + +4. A partial match never returns an empty string (because you can always + match an empty string at the end of the subject); however the checking for + an empty string was starting at the "start of match" point. This has been + changed to the "earliest inspected character" point, because the returned + data for a partial match starts at this character. This means that, for + example, /(?<=abc)def/ gives a partial match for the subject "abc" + (previously it gave "no match"). + +5. Changes have been made to the way PCRE_PARTIAL_HARD affects the matching + of $, \z, \Z, \b, and \B. If the match point is at the end of the string, + previously a full match would be given. However, setting PCRE_PARTIAL_HARD + has an implication that the given string is incomplete (because a partial + match is preferred over a full match). For this reason, these items now + give a partial match in this situation. [Aside: previously, the one case + /t\b/ matched against "cat" with PCRE_PARTIAL_HARD set did return a partial + match rather than a full match, which was wrong by the old rules, but is + now correct.] + +6. There was a bug in the handling of #-introduced comments, recognized when + PCRE_EXTENDED is set, when PCRE_NEWLINE_ANY and PCRE_UTF8 were also set. + If a UTF-8 multi-byte character included the byte 0x85 (e.g. +U0445, whose + UTF-8 encoding is 0xd1,0x85), this was misinterpreted as a newline when + scanning for the end of the comment. (*Character* 0x85 is an "any" newline, + but *byte* 0x85 is not, in UTF-8 mode). This bug was present in several + places in pcre_compile(). + +7. Related to (6) above, when pcre_compile() was skipping #-introduced + comments when looking ahead for named forward references to subpatterns, + the only newline sequence it recognized was NL. It now handles newlines + according to the set newline convention. + +8. SunOS4 doesn't have strerror() or strtoul(); pcregrep dealt with the + former, but used strtoul(), whereas pcretest avoided strtoul() but did not + cater for a lack of strerror(). These oversights have been fixed. + +9. Added --match-limit and --recursion-limit to pcregrep. + +10. Added two casts needed to build with Visual Studio when NO_RECURSE is set. + +11. When the -o option was used, pcregrep was setting a return code of 1, even + when matches were found, and --line-buffered was not being honoured. + +12. Added an optional parentheses number to the -o and --only-matching options + of pcregrep. + +13. Imitating Perl's /g action for multiple matches is tricky when the pattern + can match an empty string. The code to do it in pcretest and pcredemo + needed fixing: + + (a) When the newline convention was "crlf", pcretest got it wrong, skipping + only one byte after an empty string match just before CRLF (this case + just got forgotten; "any" and "anycrlf" were OK). + + (b) The pcretest code also had a bug, causing it to loop forever in UTF-8 + mode when an empty string match preceded an ASCII character followed by + a non-ASCII character. (The code for advancing by one character rather + than one byte was nonsense.) + + (c) The pcredemo.c sample program did not have any code at all to handle + the cases when CRLF is a valid newline sequence. + +14. Neither pcre_exec() nor pcre_dfa_exec() was checking that the value given + as a starting offset was within the subject string. There is now a new + error, PCRE_ERROR_BADOFFSET, which is returned if the starting offset is + negative or greater than the length of the string. In order to test this, + pcretest is extended to allow the setting of negative starting offsets. + +15. In both pcre_exec() and pcre_dfa_exec() the code for checking that the + starting offset points to the beginning of a UTF-8 character was + unnecessarily clumsy. I tidied it up. + +16. Added PCRE_ERROR_SHORTUTF8 to make it possible to distinguish between a + bad UTF-8 sequence and one that is incomplete when using PCRE_PARTIAL_HARD. + +17. Nobody had reported that the --include_dir option, which was added in + release 7.7 should have been called --include-dir (hyphen, not underscore) + for compatibility with GNU grep. I have changed it to --include-dir, but + left --include_dir as an undocumented synonym, and the same for + --exclude-dir, though that is not available in GNU grep, at least as of + release 2.5.4. + +18. At a user's suggestion, the macros GETCHAR and friends (which pick up UTF-8 + characters from a string of bytes) have been redefined so as not to use + loops, in order to improve performance in some environments. At the same + time, I abstracted some of the common code into auxiliary macros to save + repetition (this should not affect the compiled code). + +19. If \c was followed by a multibyte UTF-8 character, bad things happened. A + compile-time error is now given if \c is not followed by an ASCII + character, that is, a byte less than 128. (In EBCDIC mode, the code is + different, and any byte value is allowed.) + +20. Recognize (*NO_START_OPT) at the start of a pattern to set the PCRE_NO_ + START_OPTIMIZE option, which is now allowed at compile time - but just + passed through to pcre_exec() or pcre_dfa_exec(). This makes it available + to pcregrep and other applications that have no direct access to PCRE + options. The new /Y option in pcretest sets this option when calling + pcre_compile(). + +21. Change 18 of release 8.01 broke the use of named subpatterns for recursive + back references. Groups containing recursive back references were forced to + be atomic by that change, but in the case of named groups, the amount of + memory required was incorrectly computed, leading to "Failed: internal + error: code overflow". This has been fixed. + +22. Some patches to pcre_stringpiece.h, pcre_stringpiece_unittest.cc, and + pcretest.c, to avoid build problems in some Borland environments. + + +Version 8.10 25-Jun-2010 +------------------------ + +1. Added support for (*MARK:ARG) and for ARG additions to PRUNE, SKIP, and + THEN. + +2. (*ACCEPT) was not working when inside an atomic group. + +3. Inside a character class, \B is treated as a literal by default, but + faulted if PCRE_EXTRA is set. This mimics Perl's behaviour (the -w option + causes the error). The code is unchanged, but I tidied the documentation. + +4. Inside a character class, PCRE always treated \R and \X as literals, + whereas Perl faults them if its -w option is set. I have changed PCRE so + that it faults them when PCRE_EXTRA is set. + +5. Added support for \N, which always matches any character other than + newline. (It is the same as "." when PCRE_DOTALL is not set.) + +6. When compiling pcregrep with newer versions of gcc which may have + FORTIFY_SOURCE set, several warnings "ignoring return value of 'fwrite', + declared with attribute warn_unused_result" were given. Just casting the + result to (void) does not stop the warnings; a more elaborate fudge is + needed. I've used a macro to implement this. + +7. Minor change to pcretest.c to avoid a compiler warning. + +8. Added four artifical Unicode properties to help with an option to make + \s etc use properties (see next item). The new properties are: Xan + (alphanumeric), Xsp (Perl space), Xps (POSIX space), and Xwd (word). + +9. Added PCRE_UCP to make \b, \d, \s, \w, and certain POSIX character classes + use Unicode properties. (*UCP) at the start of a pattern can be used to set + this option. Modified pcretest to add /W to test this facility. Added + REG_UCP to make it available via the POSIX interface. + +10. Added --line-buffered to pcregrep. + +11. In UTF-8 mode, if a pattern that was compiled with PCRE_CASELESS was + studied, and the match started with a letter with a code point greater than + 127 whose first byte was different to the first byte of the other case of + the letter, the other case of this starting letter was not recognized + (#976). + +12. If a pattern that was studied started with a repeated Unicode property + test, for example, \p{Nd}+, there was the theoretical possibility of + setting up an incorrect bitmap of starting bytes, but fortunately it could + not have actually happened in practice until change 8 above was made (it + added property types that matched character-matching opcodes). + +13. pcre_study() now recognizes \h, \v, and \R when constructing a bit map of + possible starting bytes for non-anchored patterns. + +14. Extended the "auto-possessify" feature of pcre_compile(). It now recognizes + \R, and also a number of cases that involve Unicode properties, both + explicit and implicit when PCRE_UCP is set. + +15. If a repeated Unicode property match (e.g. \p{Lu}*) was used with non-UTF-8 + input, it could crash or give wrong results if characters with values + greater than 0xc0 were present in the subject string. (Detail: it assumed + UTF-8 input when processing these items.) + +16. Added a lot of (int) casts to avoid compiler warnings in systems where + size_t is 64-bit (#991). + +17. Added a check for running out of memory when PCRE is compiled with + --disable-stack-for-recursion (#990). + +18. If the last data line in a file for pcretest does not have a newline on + the end, a newline was missing in the output. + +19. The default pcre_chartables.c file recognizes only ASCII characters (values + less than 128) in its various bitmaps. However, there is a facility for + generating tables according to the current locale when PCRE is compiled. It + turns out that in some environments, 0x85 and 0xa0, which are Unicode space + characters, are recognized by isspace() and therefore were getting set in + these tables, and indeed these tables seem to approximate to ISO 8859. This + caused a problem in UTF-8 mode when pcre_study() was used to create a list + of bytes that can start a match. For \s, it was including 0x85 and 0xa0, + which of course cannot start UTF-8 characters. I have changed the code so + that only real ASCII characters (less than 128) and the correct starting + bytes for UTF-8 encodings are set for characters greater than 127 when in + UTF-8 mode. (When PCRE_UCP is set - see 9 above - the code is different + altogether.) + +20. Added the /T option to pcretest so as to be able to run tests with non- + standard character tables, thus making it possible to include the tests + used for 19 above in the standard set of tests. + +21. A pattern such as (?&t)(?#()(?(DEFINE)(?a)) which has a forward + reference to a subpattern the other side of a comment that contains an + opening parenthesis caused either an internal compiling error, or a + reference to the wrong subpattern. + + +Version 8.02 19-Mar-2010 +------------------------ + +1. The Unicode data tables have been updated to Unicode 5.2.0. + +2. Added the option --libs-cpp to pcre-config, but only when C++ support is + configured. + +3. Updated the licensing terms in the pcregexp.pas file, as agreed with the + original author of that file, following a query about its status. + +4. On systems that do not have stdint.h (e.g. Solaris), check for and include + inttypes.h instead. This fixes a bug that was introduced by change 8.01/8. + +5. A pattern such as (?&t)*+(?(DEFINE)(?.)) which has a possessive + quantifier applied to a forward-referencing subroutine call, could compile + incorrect code or give the error "internal error: previously-checked + referenced subpattern not found". + +6. Both MS Visual Studio and Symbian OS have problems with initializing + variables to point to external functions. For these systems, therefore, + pcre_malloc etc. are now initialized to local functions that call the + relevant global functions. + +7. There were two entries missing in the vectors called coptable and poptable + in pcre_dfa_exec.c. This could lead to memory accesses outsize the vectors. + I've fixed the data, and added a kludgy way of testing at compile time that + the lengths are correct (equal to the number of opcodes). + +8. Following on from 7, I added a similar kludge to check the length of the + eint vector in pcreposix.c. + +9. Error texts for pcre_compile() are held as one long string to avoid too + much relocation at load time. To find a text, the string is searched, + counting zeros. There was no check for running off the end of the string, + which could happen if a new error number was added without updating the + string. + +10. \K gave a compile-time error if it appeared in a lookbehind assersion. + +11. \K was not working if it appeared in an atomic group or in a group that + was called as a "subroutine", or in an assertion. Perl 5.11 documents that + \K is "not well defined" if used in an assertion. PCRE now accepts it if + the assertion is positive, but not if it is negative. + +12. Change 11 fortuitously reduced the size of the stack frame used in the + "match()" function of pcre_exec.c by one pointer. Forthcoming + implementation of support for (*MARK) will need an extra pointer on the + stack; I have reserved it now, so that the stack frame size does not + decrease. + +13. A pattern such as (?P(?P0)|(?P>L2)(?P>L1)) in which the only other + item in branch that calls a recursion is a subroutine call - as in the + second branch in the above example - was incorrectly given the compile- + time error "recursive call could loop indefinitely" because pcre_compile() + was not correctly checking the subroutine for matching a non-empty string. + +14. The checks for overrunning compiling workspace could trigger after an + overrun had occurred. This is a "should never occur" error, but it can be + triggered by pathological patterns such as hundreds of nested parentheses. + The checks now trigger 100 bytes before the end of the workspace. + +15. Fix typo in configure.ac: "srtoq" should be "strtoq". + + +Version 8.01 19-Jan-2010 +------------------------ + +1. If a pattern contained a conditional subpattern with only one branch (in + particular, this includes all (*DEFINE) patterns), a call to pcre_study() + computed the wrong minimum data length (which is of course zero for such + subpatterns). This could cause incorrect "no match" results. + +2. For patterns such as (?i)a(?-i)b|c where an option setting at the start of + the pattern is reset in the first branch, pcre_compile() failed with + "internal error: code overflow at offset...". This happened only when + the reset was to the original external option setting. (An optimization + abstracts leading options settings into an external setting, which was the + cause of this.) + +3. A pattern such as ^(?!a(*SKIP)b) where a negative assertion contained one + of the verbs SKIP, PRUNE, or COMMIT, did not work correctly. When the + assertion pattern did not match (meaning that the assertion was true), it + was incorrectly treated as false if the SKIP had been reached during the + matching. This also applied to assertions used as conditions. + +4. If an item that is not supported by pcre_dfa_exec() was encountered in an + assertion subpattern, including such a pattern used as a condition, + unpredictable results occurred, instead of the error return + PCRE_ERROR_DFA_UITEM. + +5. The C++ GlobalReplace function was not working like Perl for the special + situation when an empty string is matched. It now does the fancy magic + stuff that is necessary. + +6. In pcre_internal.h, obsolete includes to setjmp.h and stdarg.h have been + removed. (These were left over from very, very early versions of PCRE.) + +7. Some cosmetic changes to the code to make life easier when compiling it + as part of something else: + + (a) Change DEBUG to PCRE_DEBUG. + + (b) In pcre_compile(), rename the member of the "branch_chain" structure + called "current" as "current_branch", to prevent a collision with the + Linux macro when compiled as a kernel module. + + (c) In pcre_study(), rename the function set_bit() as set_table_bit(), to + prevent a collision with the Linux macro when compiled as a kernel + module. + +8. In pcre_compile() there are some checks for integer overflows that used to + cast potentially large values to (double). This has been changed to that + when building, a check for int64_t is made, and if it is found, it is used + instead, thus avoiding the use of floating point arithmetic. (There is no + other use of FP in PCRE.) If int64_t is not found, the fallback is to + double. + +9. Added two casts to avoid signed/unsigned warnings from VS Studio Express + 2005 (difference between two addresses compared to an unsigned value). + +10. Change the standard AC_CHECK_LIB test for libbz2 in configure.ac to a + custom one, because of the following reported problem in Windows: + + - libbz2 uses the Pascal calling convention (WINAPI) for the functions + under Win32. + - The standard autoconf AC_CHECK_LIB fails to include "bzlib.h", + therefore missing the function definition. + - The compiler thus generates a "C" signature for the test function. + - The linker fails to find the "C" function. + - PCRE fails to configure if asked to do so against libbz2. + +11. When running libtoolize from libtool-2.2.6b as part of autogen.sh, these + messages were output: + + Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.ac and + rerunning libtoolize, to keep the correct libtool macros in-tree. + Consider adding `-I m4' to ACLOCAL_AMFLAGS in Makefile.am. + + I have done both of these things. + +12. Although pcre_dfa_exec() does not use nearly as much stack as pcre_exec() + most of the time, it *can* run out if it is given a pattern that contains a + runaway infinite recursion. I updated the discussion in the pcrestack man + page. + +13. Now that we have gone to the x.xx style of version numbers, the minor + version may start with zero. Using 08 or 09 is a bad idea because users + might check the value of PCRE_MINOR in their code, and 08 or 09 may be + interpreted as invalid octal numbers. I've updated the previous comment in + configure.ac, and also added a check that gives an error if 08 or 09 are + used. + +14. Change 8.00/11 was not quite complete: code had been accidentally omitted, + causing partial matching to fail when the end of the subject matched \W + in a UTF-8 pattern where \W was quantified with a minimum of 3. + +15. There were some discrepancies between the declarations in pcre_internal.h + of _pcre_is_newline(), _pcre_was_newline(), and _pcre_valid_utf8() and + their definitions. The declarations used "const uschar *" and the + definitions used USPTR. Even though USPTR is normally defined as "const + unsigned char *" (and uschar is typedeffed as "unsigned char"), it was + reported that: "This difference in casting confuses some C++ compilers, for + example, SunCC recognizes above declarations as different functions and + generates broken code for hbpcre." I have changed the declarations to use + USPTR. + +16. GNU libtool is named differently on some systems. The autogen.sh script now + tries several variants such as glibtoolize (MacOSX) and libtoolize1x + (FreeBSD). + +17. Applied Craig's patch that fixes an HP aCC compile error in pcre 8.00 + (strtoXX undefined when compiling pcrecpp.cc). The patch contains this + comment: "Figure out how to create a longlong from a string: strtoll and + equivalent. It's not enough to call AC_CHECK_FUNCS: hpux has a strtoll, for + instance, but it only takes 2 args instead of 3!" + +18. A subtle bug concerned with back references has been fixed by a change of + specification, with a corresponding code fix. A pattern such as + ^(xa|=?\1a)+$ which contains a back reference inside the group to which it + refers, was giving matches when it shouldn't. For example, xa=xaaa would + match that pattern. Interestingly, Perl (at least up to 5.11.3) has the + same bug. Such groups have to be quantified to be useful, or contained + inside another quantified group. (If there's no repetition, the reference + can never match.) The problem arises because, having left the group and + moved on to the rest of the pattern, a later failure that backtracks into + the group uses the captured value from the final iteration of the group + rather than the correct earlier one. I have fixed this in PCRE by forcing + any group that contains a reference to itself to be an atomic group; that + is, there cannot be any backtracking into it once it has completed. This is + similar to recursive and subroutine calls. + + +Version 8.00 19-Oct-09 +---------------------- + +1. The table for translating pcre_compile() error codes into POSIX error codes + was out-of-date, and there was no check on the pcre_compile() error code + being within the table. This could lead to an OK return being given in + error. + +2. Changed the call to open a subject file in pcregrep from fopen(pathname, + "r") to fopen(pathname, "rb"), which fixed a problem with some of the tests + in a Windows environment. + +3. The pcregrep --count option prints the count for each file even when it is + zero, as does GNU grep. However, pcregrep was also printing all files when + --files-with-matches was added. Now, when both options are given, it prints + counts only for those files that have at least one match. (GNU grep just + prints the file name in this circumstance, but including the count seems + more useful - otherwise, why use --count?) Also ensured that the + combination -clh just lists non-zero counts, with no names. + +4. The long form of the pcregrep -F option was incorrectly implemented as + --fixed_strings instead of --fixed-strings. This is an incompatible change, + but it seems right to fix it, and I didn't think it was worth preserving + the old behaviour. + +5. The command line items --regex=pattern and --regexp=pattern were not + recognized by pcregrep, which required --regex pattern or --regexp pattern + (with a space rather than an '='). The man page documented the '=' forms, + which are compatible with GNU grep; these now work. + +6. No libpcreposix.pc file was created for pkg-config; there was just + libpcre.pc and libpcrecpp.pc. The omission has been rectified. + +7. Added #ifndef SUPPORT_UCP into the pcre_ucd.c module, to reduce its size + when UCP support is not needed, by modifying the Python script that + generates it from Unicode data files. This should not matter if the module + is correctly used as a library, but I received one complaint about 50K of + unwanted data. My guess is that the person linked everything into his + program rather than using a library. Anyway, it does no harm. + +8. A pattern such as /\x{123}{2,2}+/8 was incorrectly compiled; the trigger + was a minimum greater than 1 for a wide character in a possessive + repetition. The same bug could also affect patterns like /(\x{ff}{0,2})*/8 + which had an unlimited repeat of a nested, fixed maximum repeat of a wide + character. Chaos in the form of incorrect output or a compiling loop could + result. + +9. The restrictions on what a pattern can contain when partial matching is + requested for pcre_exec() have been removed. All patterns can now be + partially matched by this function. In addition, if there are at least two + slots in the offset vector, the offset of the earliest inspected character + for the match and the offset of the end of the subject are set in them when + PCRE_ERROR_PARTIAL is returned. + +10. Partial matching has been split into two forms: PCRE_PARTIAL_SOFT, which is + synonymous with PCRE_PARTIAL, for backwards compatibility, and + PCRE_PARTIAL_HARD, which causes a partial match to supersede a full match, + and may be more useful for multi-segment matching. + +11. Partial matching with pcre_exec() is now more intuitive. A partial match + used to be given if ever the end of the subject was reached; now it is + given only if matching could not proceed because another character was + needed. This makes a difference in some odd cases such as Z(*FAIL) with the + string "Z", which now yields "no match" instead of "partial match". In the + case of pcre_dfa_exec(), "no match" is given if every matching path for the + final character ended with (*FAIL). + +12. Restarting a match using pcre_dfa_exec() after a partial match did not work + if the pattern had a "must contain" character that was already found in the + earlier partial match, unless partial matching was again requested. For + example, with the pattern /dog.(body)?/, the "must contain" character is + "g". If the first part-match was for the string "dog", restarting with + "sbody" failed. This bug has been fixed. + +13. The string returned by pcre_dfa_exec() after a partial match has been + changed so that it starts at the first inspected character rather than the + first character of the match. This makes a difference only if the pattern + starts with a lookbehind assertion or \b or \B (\K is not supported by + pcre_dfa_exec()). It's an incompatible change, but it makes the two + matching functions compatible, and I think it's the right thing to do. + +14. Added a pcredemo man page, created automatically from the pcredemo.c file, + so that the demonstration program is easily available in environments where + PCRE has not been installed from source. + +15. Arranged to add -DPCRE_STATIC to cflags in libpcre.pc, libpcreposix.cp, + libpcrecpp.pc and pcre-config when PCRE is not compiled as a shared + library. + +16. Added REG_UNGREEDY to the pcreposix interface, at the request of a user. + It maps to PCRE_UNGREEDY. It is not, of course, POSIX-compatible, but it + is not the first non-POSIX option to be added. Clearly some people find + these options useful. + +17. If a caller to the POSIX matching function regexec() passes a non-zero + value for nmatch with a NULL value for pmatch, the value of + nmatch is forced to zero. + +18. RunGrepTest did not have a test for the availability of the -u option of + the diff command, as RunTest does. It now checks in the same way as + RunTest, and also checks for the -b option. + +19. If an odd number of negated classes containing just a single character + interposed, within parentheses, between a forward reference to a named + subpattern and the definition of the subpattern, compilation crashed with + an internal error, complaining that it could not find the referenced + subpattern. An example of a crashing pattern is /(?&A)(([^m])(?))/. + [The bug was that it was starting one character too far in when skipping + over the character class, thus treating the ] as data rather than + terminating the class. This meant it could skip too much.] + +20. Added PCRE_NOTEMPTY_ATSTART in order to be able to correctly implement the + /g option in pcretest when the pattern contains \K, which makes it possible + to have an empty string match not at the start, even when the pattern is + anchored. Updated pcretest and pcredemo to use this option. + +21. If the maximum number of capturing subpatterns in a recursion was greater + than the maximum at the outer level, the higher number was returned, but + with unset values at the outer level. The correct (outer level) value is + now given. + +22. If (*ACCEPT) appeared inside capturing parentheses, previous releases of + PCRE did not set those parentheses (unlike Perl). I have now found a way to + make it do so. The string so far is captured, making this feature + compatible with Perl. + +23. The tests have been re-organized, adding tests 11 and 12, to make it + possible to check the Perl 5.10 features against Perl 5.10. + +24. Perl 5.10 allows subroutine calls in lookbehinds, as long as the subroutine + pattern matches a fixed length string. PCRE did not allow this; now it + does. Neither allows recursion. + +25. I finally figured out how to implement a request to provide the minimum + length of subject string that was needed in order to match a given pattern. + (It was back references and recursion that I had previously got hung up + on.) This code has now been added to pcre_study(); it finds a lower bound + to the length of subject needed. It is not necessarily the greatest lower + bound, but using it to avoid searching strings that are too short does give + some useful speed-ups. The value is available to calling programs via + pcre_fullinfo(). + +26. While implementing 25, I discovered to my embarrassment that pcretest had + not been passing the result of pcre_study() to pcre_dfa_exec(), so the + study optimizations had never been tested with that matching function. + Oops. What is worse, even when it was passed study data, there was a bug in + pcre_dfa_exec() that meant it never actually used it. Double oops. There + were also very few tests of studied patterns with pcre_dfa_exec(). + +27. If (?| is used to create subpatterns with duplicate numbers, they are now + allowed to have the same name, even if PCRE_DUPNAMES is not set. However, + on the other side of the coin, they are no longer allowed to have different + names, because these cannot be distinguished in PCRE, and this has caused + confusion. (This is a difference from Perl.) + +28. When duplicate subpattern names are present (necessarily with different + numbers, as required by 27 above), and a test is made by name in a + conditional pattern, either for a subpattern having been matched, or for + recursion in such a pattern, all the associated numbered subpatterns are + tested, and the overall condition is true if the condition is true for any + one of them. This is the way Perl works, and is also more like the way + testing by number works. + + +Version 7.9 11-Apr-09 +--------------------- + +1. When building with support for bzlib/zlib (pcregrep) and/or readline + (pcretest), all targets were linked against these libraries. This included + libpcre, libpcreposix, and libpcrecpp, even though they do not use these + libraries. This caused unwanted dependencies to be created. This problem + has been fixed, and now only pcregrep is linked with bzlib/zlib and only + pcretest is linked with readline. + +2. The "typedef int BOOL" in pcre_internal.h that was included inside the + "#ifndef FALSE" condition by an earlier change (probably 7.8/18) has been + moved outside it again, because FALSE and TRUE are already defined in AIX, + but BOOL is not. + +3. The pcre_config() function was treating the PCRE_MATCH_LIMIT and + PCRE_MATCH_LIMIT_RECURSION values as ints, when they should be long ints. + +4. The pcregrep documentation said spaces were inserted as well as colons (or + hyphens) following file names and line numbers when outputting matching + lines. This is not true; no spaces are inserted. I have also clarified the + wording for the --colour (or --color) option. + +5. In pcregrep, when --colour was used with -o, the list of matching strings + was not coloured; this is different to GNU grep, so I have changed it to be + the same. + +6. When --colo(u)r was used in pcregrep, only the first matching substring in + each matching line was coloured. Now it goes on to look for further matches + of any of the test patterns, which is the same behaviour as GNU grep. + +7. A pattern that could match an empty string could cause pcregrep to loop; it + doesn't make sense to accept an empty string match in pcregrep, so I have + locked it out (using PCRE's PCRE_NOTEMPTY option). By experiment, this + seems to be how GNU grep behaves. + +8. The pattern (?(?=.*b)b|^) was incorrectly compiled as "match must be at + start or after a newline", because the conditional assertion was not being + correctly handled. The rule now is that both the assertion and what follows + in the first alternative must satisfy the test. + +9. If auto-callout was enabled in a pattern with a conditional group whose + condition was an assertion, PCRE could crash during matching, both with + pcre_exec() and pcre_dfa_exec(). + +10. The PCRE_DOLLAR_ENDONLY option was not working when pcre_dfa_exec() was + used for matching. + +11. Unicode property support in character classes was not working for + characters (bytes) greater than 127 when not in UTF-8 mode. + +12. Added the -M command line option to pcretest. + +14. Added the non-standard REG_NOTEMPTY option to the POSIX interface. + +15. Added the PCRE_NO_START_OPTIMIZE match-time option. + +16. Added comments and documentation about mis-use of no_arg in the C++ + wrapper. + +17. Implemented support for UTF-8 encoding in EBCDIC environments, a patch + from Martin Jerabek that uses macro names for all relevant character and + string constants. + +18. Added to pcre_internal.h two configuration checks: (a) If both EBCDIC and + SUPPORT_UTF8 are set, give an error; (b) If SUPPORT_UCP is set without + SUPPORT_UTF8, define SUPPORT_UTF8. The "configure" script handles both of + these, but not everybody uses configure. + +19. A conditional group that had only one branch was not being correctly + recognized as an item that could match an empty string. This meant that an + enclosing group might also not be so recognized, causing infinite looping + (and probably a segfault) for patterns such as ^"((?(?=[a])[^"])|b)*"$ + with the subject "ab", where knowledge that the repeated group can match + nothing is needed in order to break the loop. + +20. If a pattern that was compiled with callouts was matched using pcre_dfa_ + exec(), but without supplying a callout function, matching went wrong. + +21. If PCRE_ERROR_MATCHLIMIT occurred during a recursion, there was a memory + leak if the size of the offset vector was greater than 30. When the vector + is smaller, the saved offsets during recursion go onto a local stack + vector, but for larger vectors malloc() is used. It was failing to free + when the recursion yielded PCRE_ERROR_MATCH_LIMIT (or any other "abnormal" + error, in fact). + +22. There was a missing #ifdef SUPPORT_UTF8 round one of the variables in the + heapframe that is used only when UTF-8 support is enabled. This caused no + problem, but was untidy. + +23. Steven Van Ingelgem's patch to CMakeLists.txt to change the name + CMAKE_BINARY_DIR to PROJECT_BINARY_DIR so that it works when PCRE is + included within another project. + +24. Steven Van Ingelgem's patches to add more options to the CMake support, + slightly modified by me: + + (a) PCRE_BUILD_TESTS can be set OFF not to build the tests, including + not building pcregrep. + + (b) PCRE_BUILD_PCREGREP can be see OFF not to build pcregrep, but only + if PCRE_BUILD_TESTS is also set OFF, because the tests use pcregrep. + +25. Forward references, both numeric and by name, in patterns that made use of + duplicate group numbers, could behave incorrectly or give incorrect errors, + because when scanning forward to find the reference group, PCRE was not + taking into account the duplicate group numbers. A pattern such as + ^X(?3)(a)(?|(b)|(q))(Y) is an example. + +26. Changed a few more instances of "const unsigned char *" to USPTR, making + the feature of a custom pointer more persuasive (as requested by a user). + +27. Wrapped the definitions of fileno and isatty for Windows, which appear in + pcretest.c, inside #ifndefs, because it seems they are sometimes already + pre-defined. + +28. Added support for (*UTF8) at the start of a pattern. + +29. Arrange for flags added by the "release type" setting in CMake to be shown + in the configuration summary. + + +Version 7.8 05-Sep-08 +--------------------- + +1. Replaced UCP searching code with optimized version as implemented for Ad + Muncher (http://www.admuncher.com/) by Peter Kankowski. This uses a two- + stage table and inline lookup instead of a function, giving speed ups of 2 + to 5 times on some simple patterns that I tested. Permission was given to + distribute the MultiStage2.py script that generates the tables (it's not in + the tarball, but is in the Subversion repository). + +2. Updated the Unicode datatables to Unicode 5.1.0. This adds yet more + scripts. + +3. Change 12 for 7.7 introduced a bug in pcre_study() when a pattern contained + a group with a zero qualifier. The result of the study could be incorrect, + or the function might crash, depending on the pattern. + +4. Caseless matching was not working for non-ASCII characters in back + references. For example, /(\x{de})\1/8i was not matching \x{de}\x{fe}. + It now works when Unicode Property Support is available. + +5. In pcretest, an escape such as \x{de} in the data was always generating + a UTF-8 string, even in non-UTF-8 mode. Now it generates a single byte in + non-UTF-8 mode. If the value is greater than 255, it gives a warning about + truncation. + +6. Minor bugfix in pcrecpp.cc (change "" == ... to NULL == ...). + +7. Added two (int) casts to pcregrep when printing the difference of two + pointers, in case they are 64-bit values. + +8. Added comments about Mac OS X stack usage to the pcrestack man page and to + test 2 if it fails. + +9. Added PCRE_CALL_CONVENTION just before the names of all exported functions, + and a #define of that name to empty if it is not externally set. This is to + allow users of MSVC to set it if necessary. + +10. The PCRE_EXP_DEFN macro which precedes exported functions was missing from + the convenience functions in the pcre_get.c source file. + +11. An option change at the start of a pattern that had top-level alternatives + could cause overwriting and/or a crash. This command provoked a crash in + some environments: + + printf "/(?i)[\xc3\xa9\xc3\xbd]|[\xc3\xa9\xc3\xbdA]/8\n" | pcretest + + This potential security problem was recorded as CVE-2008-2371. + +12. For a pattern where the match had to start at the beginning or immediately + after a newline (e.g /.*anything/ without the DOTALL flag), pcre_exec() and + pcre_dfa_exec() could read past the end of the passed subject if there was + no match. To help with detecting such bugs (e.g. with valgrind), I modified + pcretest so that it places the subject at the end of its malloc-ed buffer. + +13. The change to pcretest in 12 above threw up a couple more cases when pcre_ + exec() might read past the end of the data buffer in UTF-8 mode. + +14. A similar bug to 7.3/2 existed when the PCRE_FIRSTLINE option was set and + the data contained the byte 0x85 as part of a UTF-8 character within its + first line. This applied both to normal and DFA matching. + +15. Lazy qualifiers were not working in some cases in UTF-8 mode. For example, + /^[^d]*?$/8 failed to match "abc". + +16. Added a missing copyright notice to pcrecpp_internal.h. + +17. Make it more clear in the documentation that values returned from + pcre_exec() in ovector are byte offsets, not character counts. + +18. Tidied a few places to stop certain compilers from issuing warnings. + +19. Updated the Virtual Pascal + BCC files to compile the latest v7.7, as + supplied by Stefan Weber. I made a further small update for 7.8 because + there is a change of source arrangements: the pcre_searchfuncs.c module is + replaced by pcre_ucd.c. + + +Version 7.7 07-May-08 +--------------------- + +1. Applied Craig's patch to sort out a long long problem: "If we can't convert + a string to a long long, pretend we don't even have a long long." This is + done by checking for the strtoq, strtoll, and _strtoi64 functions. + +2. Applied Craig's patch to pcrecpp.cc to restore ABI compatibility with + pre-7.6 versions, which defined a global no_arg variable instead of putting + it in the RE class. (See also #8 below.) + +3. Remove a line of dead code, identified by coverity and reported by Nuno + Lopes. + +4. Fixed two related pcregrep bugs involving -r with --include or --exclude: + + (1) The include/exclude patterns were being applied to the whole pathnames + of files, instead of just to the final components. + + (2) If there was more than one level of directory, the subdirectories were + skipped unless they satisfied the include/exclude conditions. This is + inconsistent with GNU grep (and could even be seen as contrary to the + pcregrep specification - which I improved to make it absolutely clear). + The action now is always to scan all levels of directory, and just + apply the include/exclude patterns to regular files. + +5. Added the --include_dir and --exclude_dir patterns to pcregrep, and used + --exclude_dir in the tests to avoid scanning .svn directories. + +6. Applied Craig's patch to the QuoteMeta function so that it escapes the + NUL character as backslash + 0 rather than backslash + NUL, because PCRE + doesn't support NULs in patterns. + +7. Added some missing "const"s to declarations of static tables in + pcre_compile.c and pcre_dfa_exec.c. + +8. Applied Craig's patch to pcrecpp.cc to fix a problem in OS X that was + caused by fix #2 above. (Subsequently also a second patch to fix the + first patch. And a third patch - this was a messy problem.) + +9. Applied Craig's patch to remove the use of push_back(). + +10. Applied Alan Lehotsky's patch to add REG_STARTEND support to the POSIX + matching function regexec(). + +11. Added support for the Oniguruma syntax \g, \g, \g'name', \g'n', + which, however, unlike Perl's \g{...}, are subroutine calls, not back + references. PCRE supports relative numbers with this syntax (I don't think + Oniguruma does). + +12. Previously, a group with a zero repeat such as (...){0} was completely + omitted from the compiled regex. However, this means that if the group + was called as a subroutine from elsewhere in the pattern, things went wrong + (an internal error was given). Such groups are now left in the compiled + pattern, with a new opcode that causes them to be skipped at execution + time. + +13. Added the PCRE_JAVASCRIPT_COMPAT option. This makes the following changes + to the way PCRE behaves: + + (a) A lone ] character is dis-allowed (Perl treats it as data). + + (b) A back reference to an unmatched subpattern matches an empty string + (Perl fails the current match path). + + (c) A data ] in a character class must be notated as \] because if the + first data character in a class is ], it defines an empty class. (In + Perl it is not possible to have an empty class.) The empty class [] + never matches; it forces failure and is equivalent to (*FAIL) or (?!). + The negative empty class [^] matches any one character, independently + of the DOTALL setting. + +14. A pattern such as /(?2)[]a()b](abc)/ which had a forward reference to a + non-existent subpattern following a character class starting with ']' and + containing () gave an internal compiling error instead of "reference to + non-existent subpattern". Fortunately, when the pattern did exist, the + compiled code was correct. (When scanning forwards to check for the + existencd of the subpattern, it was treating the data ']' as terminating + the class, so got the count wrong. When actually compiling, the reference + was subsequently set up correctly.) + +15. The "always fail" assertion (?!) is optimzed to (*FAIL) by pcre_compile; + it was being rejected as not supported by pcre_dfa_exec(), even though + other assertions are supported. I have made pcre_dfa_exec() support + (*FAIL). + +16. The implementation of 13c above involved the invention of a new opcode, + OP_ALLANY, which is like OP_ANY but doesn't check the /s flag. Since /s + cannot be changed at match time, I realized I could make a small + improvement to matching performance by compiling OP_ALLANY instead of + OP_ANY for "." when DOTALL was set, and then removing the runtime tests + on the OP_ANY path. + +17. Compiling pcretest on Windows with readline support failed without the + following two fixes: (1) Make the unistd.h include conditional on + HAVE_UNISTD_H; (2) #define isatty and fileno as _isatty and _fileno. + +18. Changed CMakeLists.txt and cmake/FindReadline.cmake to arrange for the + ncurses library to be included for pcretest when ReadLine support is + requested, but also to allow for it to be overridden. This patch came from + Daniel Bergström. + +19. There was a typo in the file ucpinternal.h where f0_rangeflag was defined + as 0x00f00000 instead of 0x00800000. Luckily, this would not have caused + any errors with the current Unicode tables. Thanks to Peter Kankowski for + spotting this. + + +Version 7.6 28-Jan-08 +--------------------- + +1. A character class containing a very large number of characters with + codepoints greater than 255 (in UTF-8 mode, of course) caused a buffer + overflow. + +2. Patch to cut out the "long long" test in pcrecpp_unittest when + HAVE_LONG_LONG is not defined. + +3. Applied Christian Ehrlicher's patch to update the CMake build files to + bring them up to date and include new features. This patch includes: + + - Fixed PH's badly added libz and libbz2 support. + - Fixed a problem with static linking. + - Added pcredemo. [But later removed - see 7 below.] + - Fixed dftables problem and added an option. + - Added a number of HAVE_XXX tests, including HAVE_WINDOWS_H and + HAVE_LONG_LONG. + - Added readline support for pcretest. + - Added an listing of the option settings after cmake has run. + +4. A user submitted a patch to Makefile that makes it easy to create + "pcre.dll" under mingw when using Configure/Make. I added stuff to + Makefile.am that cause it to include this special target, without + affecting anything else. Note that the same mingw target plus all + the other distribution libraries and programs are now supported + when configuring with CMake (see 6 below) instead of with + Configure/Make. + +5. Applied Craig's patch that moves no_arg into the RE class in the C++ code. + This is an attempt to solve the reported problem "pcrecpp::no_arg is not + exported in the Windows port". It has not yet been confirmed that the patch + solves the problem, but it does no harm. + +6. Applied Sheri's patch to CMakeLists.txt to add NON_STANDARD_LIB_PREFIX and + NON_STANDARD_LIB_SUFFIX for dll names built with mingw when configured + with CMake, and also correct the comment about stack recursion. + +7. Remove the automatic building of pcredemo from the ./configure system and + from CMakeLists.txt. The whole idea of pcredemo.c is that it is an example + of a program that users should build themselves after PCRE is installed, so + building it automatically is not really right. What is more, it gave + trouble in some build environments. + +8. Further tidies to CMakeLists.txt from Sheri and Christian. + + +Version 7.5 10-Jan-08 +--------------------- + +1. Applied a patch from Craig: "This patch makes it possible to 'ignore' + values in parens when parsing an RE using the C++ wrapper." + +2. Negative specials like \S did not work in character classes in UTF-8 mode. + Characters greater than 255 were excluded from the class instead of being + included. + +3. The same bug as (2) above applied to negated POSIX classes such as + [:^space:]. + +4. PCRECPP_STATIC was referenced in pcrecpp_internal.h, but nowhere was it + defined or documented. It seems to have been a typo for PCRE_STATIC, so + I have changed it. + +5. The construct (?&) was not diagnosed as a syntax error (it referenced the + first named subpattern) and a construct such as (?&a) would reference the + first named subpattern whose name started with "a" (in other words, the + length check was missing). Both these problems are fixed. "Subpattern name + expected" is now given for (?&) (a zero-length name), and this patch also + makes it give the same error for \k'' (previously it complained that that + was a reference to a non-existent subpattern). + +6. The erroneous patterns (?+-a) and (?-+a) give different error messages; + this is right because (?- can be followed by option settings as well as by + digits. I have, however, made the messages clearer. + +7. Patterns such as (?(1)a|b) (a pattern that contains fewer subpatterns + than the number used in the conditional) now cause a compile-time error. + This is actually not compatible with Perl, which accepts such patterns, but + treats the conditional as always being FALSE (as PCRE used to), but it + seems to me that giving a diagnostic is better. + +8. Change "alphameric" to the more common word "alphanumeric" in comments + and messages. + +9. Fix two occurrences of "backslash" in comments that should have been + "backspace". + +10. Remove two redundant lines of code that can never be obeyed (their function + was moved elsewhere). + +11. The program that makes PCRE's Unicode character property table had a bug + which caused it to generate incorrect table entries for sequences of + characters that have the same character type, but are in different scripts. + It amalgamated them into a single range, with the script of the first of + them. In other words, some characters were in the wrong script. There were + thirteen such cases, affecting characters in the following ranges: + + U+002b0 - U+002c1 + U+0060c - U+0060d + U+0061e - U+00612 + U+0064b - U+0065e + U+0074d - U+0076d + U+01800 - U+01805 + U+01d00 - U+01d77 + U+01d9b - U+01dbf + U+0200b - U+0200f + U+030fc - U+030fe + U+03260 - U+0327f + U+0fb46 - U+0fbb1 + U+10450 - U+1049d + +12. The -o option (show only the matching part of a line) for pcregrep was not + compatible with GNU grep in that, if there was more than one match in a + line, it showed only the first of them. It now behaves in the same way as + GNU grep. + +13. If the -o and -v options were combined for pcregrep, it printed a blank + line for every non-matching line. GNU grep prints nothing, and pcregrep now + does the same. The return code can be used to tell if there were any + non-matching lines. + +14. Added --file-offsets and --line-offsets to pcregrep. + +15. The pattern (?=something)(?R) was not being diagnosed as a potentially + infinitely looping recursion. The bug was that positive lookaheads were not + being skipped when checking for a possible empty match (negative lookaheads + and both kinds of lookbehind were skipped). + +16. Fixed two typos in the Windows-only code in pcregrep.c, and moved the + inclusion of to before rather than after the definition of + INVALID_FILE_ATTRIBUTES (patch from David Byron). + +17. Specifying a possessive quantifier with a specific limit for a Unicode + character property caused pcre_compile() to compile bad code, which led at + runtime to PCRE_ERROR_INTERNAL (-14). Examples of patterns that caused this + are: /\p{Zl}{2,3}+/8 and /\p{Cc}{2}+/8. It was the possessive "+" that + caused the error; without that there was no problem. + +18. Added --enable-pcregrep-libz and --enable-pcregrep-libbz2. + +19. Added --enable-pcretest-libreadline. + +20. In pcrecpp.cc, the variable 'count' was incremented twice in + RE::GlobalReplace(). As a result, the number of replacements returned was + double what it should be. I removed one of the increments, but Craig sent a + later patch that removed the other one (the right fix) and added unit tests + that check the return values (which was not done before). + +21. Several CMake things: + + (1) Arranged that, when cmake is used on Unix, the libraries end up with + the names libpcre and libpcreposix, not just pcre and pcreposix. + + (2) The above change means that pcretest and pcregrep are now correctly + linked with the newly-built libraries, not previously installed ones. + + (3) Added PCRE_SUPPORT_LIBREADLINE, PCRE_SUPPORT_LIBZ, PCRE_SUPPORT_LIBBZ2. + +22. In UTF-8 mode, with newline set to "any", a pattern such as .*a.*=.b.* + crashed when matching a string such as a\x{2029}b (note that \x{2029} is a + UTF-8 newline character). The key issue is that the pattern starts .*; + this means that the match must be either at the beginning, or after a + newline. The bug was in the code for advancing after a failed match and + checking that the new position followed a newline. It was not taking + account of UTF-8 characters correctly. + +23. PCRE was behaving differently from Perl in the way it recognized POSIX + character classes. PCRE was not treating the sequence [:...:] as a + character class unless the ... were all letters. Perl, however, seems to + allow any characters between [: and :], though of course it rejects as + unknown any "names" that contain non-letters, because all the known class + names consist only of letters. Thus, Perl gives an error for [[:1234:]], + for example, whereas PCRE did not - it did not recognize a POSIX character + class. This seemed a bit dangerous, so the code has been changed to be + closer to Perl. The behaviour is not identical to Perl, because PCRE will + diagnose an unknown class for, for example, [[:l\ower:]] where Perl will + treat it as [[:lower:]]. However, PCRE does now give "unknown" errors where + Perl does, and where it didn't before. + +24. Rewrite so as to remove the single use of %n from pcregrep because in some + Windows environments %n is disabled by default. + + +Version 7.4 21-Sep-07 +--------------------- + +1. Change 7.3/28 was implemented for classes by looking at the bitmap. This + means that a class such as [\s] counted as "explicit reference to CR or + LF". That isn't really right - the whole point of the change was to try to + help when there was an actual mention of one of the two characters. So now + the change happens only if \r or \n (or a literal CR or LF) character is + encountered. + +2. The 32-bit options word was also used for 6 internal flags, but the numbers + of both had grown to the point where there were only 3 bits left. + Fortunately, there was spare space in the data structure, and so I have + moved the internal flags into a new 16-bit field to free up more option + bits. + +3. The appearance of (?J) at the start of a pattern set the DUPNAMES option, + but did not set the internal JCHANGED flag - either of these is enough to + control the way the "get" function works - but the PCRE_INFO_JCHANGED + facility is supposed to tell if (?J) was ever used, so now (?J) at the + start sets both bits. + +4. Added options (at build time, compile time, exec time) to change \R from + matching any Unicode line ending sequence to just matching CR, LF, or CRLF. + +5. doc/pcresyntax.html was missing from the distribution. + +6. Put back the definition of PCRE_ERROR_NULLWSLIMIT, for backward + compatibility, even though it is no longer used. + +7. Added macro for snprintf to pcrecpp_unittest.cc and also for strtoll and + strtoull to pcrecpp.cc to select the available functions in WIN32 when the + windows.h file is present (where different names are used). [This was + reversed later after testing - see 16 below.] + +8. Changed all #include to #include "config.h". There were also + some further cases that I changed to "pcre.h". + +9. When pcregrep was used with the --colour option, it missed the line ending + sequence off the lines that it output. + +10. It was pointed out to me that arrays of string pointers cause lots of + relocations when a shared library is dynamically loaded. A technique of + using a single long string with a table of offsets can drastically reduce + these. I have refactored PCRE in four places to do this. The result is + dramatic: + + Originally: 290 + After changing UCP table: 187 + After changing error message table: 43 + After changing table of "verbs" 36 + After changing table of Posix names 22 + + Thanks to the folks working on Gregex for glib for this insight. + +11. --disable-stack-for-recursion caused compiling to fail unless -enable- + unicode-properties was also set. + +12. Updated the tests so that they work when \R is defaulted to ANYCRLF. + +13. Added checks for ANY and ANYCRLF to pcrecpp.cc where it previously + checked only for CRLF. + +14. Added casts to pcretest.c to avoid compiler warnings. + +15. Added Craig's patch to various pcrecpp modules to avoid compiler warnings. + +16. Added Craig's patch to remove the WINDOWS_H tests, that were not working, + and instead check for _strtoi64 explicitly, and avoid the use of snprintf() + entirely. This removes changes made in 7 above. + +17. The CMake files have been updated, and there is now more information about + building with CMake in the NON-UNIX-USE document. + + +Version 7.3 28-Aug-07 +--------------------- + + 1. In the rejigging of the build system that eventually resulted in 7.1, the + line "#include " was included in pcre_internal.h. The use of angle + brackets there is not right, since it causes compilers to look for an + installed pcre.h, not the version that is in the source that is being + compiled (which of course may be different). I have changed it back to: + + #include "pcre.h" + + I have a vague recollection that the change was concerned with compiling in + different directories, but in the new build system, that is taken care of + by the VPATH setting the Makefile. + + 2. The pattern .*$ when run in not-DOTALL UTF-8 mode with newline=any failed + when the subject happened to end in the byte 0x85 (e.g. if the last + character was \x{1ec5}). *Character* 0x85 is one of the "any" newline + characters but of course it shouldn't be taken as a newline when it is part + of another character. The bug was that, for an unlimited repeat of . in + not-DOTALL UTF-8 mode, PCRE was advancing by bytes rather than by + characters when looking for a newline. + + 3. A small performance improvement in the DOTALL UTF-8 mode .* case. + + 4. Debugging: adjusted the names of opcodes for different kinds of parentheses + in debug output. + + 5. Arrange to use "%I64d" instead of "%lld" and "%I64u" instead of "%llu" for + long printing in the pcrecpp unittest when running under MinGW. + + 6. ESC_K was left out of the EBCDIC table. + + 7. Change 7.0/38 introduced a new limit on the number of nested non-capturing + parentheses; I made it 1000, which seemed large enough. Unfortunately, the + limit also applies to "virtual nesting" when a pattern is recursive, and in + this case 1000 isn't so big. I have been able to remove this limit at the + expense of backing off one optimization in certain circumstances. Normally, + when pcre_exec() would call its internal match() function recursively and + immediately return the result unconditionally, it uses a "tail recursion" + feature to save stack. However, when a subpattern that can match an empty + string has an unlimited repetition quantifier, it no longer makes this + optimization. That gives it a stack frame in which to save the data for + checking that an empty string has been matched. Previously this was taken + from the 1000-entry workspace that had been reserved. So now there is no + explicit limit, but more stack is used. + + 8. Applied Daniel's patches to solve problems with the import/export magic + syntax that is required for Windows, and which was going wrong for the + pcreposix and pcrecpp parts of the library. These were overlooked when this + problem was solved for the main library. + + 9. There were some crude static tests to avoid integer overflow when computing + the size of patterns that contain repeated groups with explicit upper + limits. As the maximum quantifier is 65535, the maximum group length was + set at 30,000 so that the product of these two numbers did not overflow a + 32-bit integer. However, it turns out that people want to use groups that + are longer than 30,000 bytes (though not repeat them that many times). + Change 7.0/17 (the refactoring of the way the pattern size is computed) has + made it possible to implement the integer overflow checks in a much more + dynamic way, which I have now done. The artificial limitation on group + length has been removed - we now have only the limit on the total length of + the compiled pattern, which depends on the LINK_SIZE setting. + +10. Fixed a bug in the documentation for get/copy named substring when + duplicate names are permitted. If none of the named substrings are set, the + functions return PCRE_ERROR_NOSUBSTRING (7); the doc said they returned an + empty string. + +11. Because Perl interprets \Q...\E at a high level, and ignores orphan \E + instances, patterns such as [\Q\E] or [\E] or even [^\E] cause an error, + because the ] is interpreted as the first data character and the + terminating ] is not found. PCRE has been made compatible with Perl in this + regard. Previously, it interpreted [\Q\E] as an empty class, and [\E] could + cause memory overwriting. + +10. Like Perl, PCRE automatically breaks an unlimited repeat after an empty + string has been matched (to stop an infinite loop). It was not recognizing + a conditional subpattern that could match an empty string if that + subpattern was within another subpattern. For example, it looped when + trying to match (((?(1)X|))*) but it was OK with ((?(1)X|)*) where the + condition was not nested. This bug has been fixed. + +12. A pattern like \X?\d or \P{L}?\d in non-UTF-8 mode could cause a backtrack + past the start of the subject in the presence of bytes with the top bit + set, for example "\x8aBCD". + +13. Added Perl 5.10 experimental backtracking controls (*FAIL), (*F), (*PRUNE), + (*SKIP), (*THEN), (*COMMIT), and (*ACCEPT). + +14. Optimized (?!) to (*FAIL). + +15. Updated the test for a valid UTF-8 string to conform to the later RFC 3629. + This restricts code points to be within the range 0 to 0x10FFFF, excluding + the "low surrogate" sequence 0xD800 to 0xDFFF. Previously, PCRE allowed the + full range 0 to 0x7FFFFFFF, as defined by RFC 2279. Internally, it still + does: it's just the validity check that is more restrictive. + +16. Inserted checks for integer overflows during escape sequence (backslash) + processing, and also fixed erroneous offset values for syntax errors during + backslash processing. + +17. Fixed another case of looking too far back in non-UTF-8 mode (cf 12 above) + for patterns like [\PPP\x8a]{1,}\x80 with the subject "A\x80". + +18. An unterminated class in a pattern like (?1)\c[ with a "forward reference" + caused an overrun. + +19. A pattern like (?:[\PPa*]*){8,} which had an "extended class" (one with + something other than just ASCII characters) inside a group that had an + unlimited repeat caused a loop at compile time (while checking to see + whether the group could match an empty string). + +20. Debugging a pattern containing \p or \P could cause a crash. For example, + [\P{Any}] did so. (Error in the code for printing property names.) + +21. An orphan \E inside a character class could cause a crash. + +22. A repeated capturing bracket such as (A)? could cause a wild memory + reference during compilation. + +23. There are several functions in pcre_compile() that scan along a compiled + expression for various reasons (e.g. to see if it's fixed length for look + behind). There were bugs in these functions when a repeated \p or \P was + present in the pattern. These operators have additional parameters compared + with \d, etc, and these were not being taken into account when moving along + the compiled data. Specifically: + + (a) A item such as \p{Yi}{3} in a lookbehind was not treated as fixed + length. + + (b) An item such as \pL+ within a repeated group could cause crashes or + loops. + + (c) A pattern such as \p{Yi}+(\P{Yi}+)(?1) could give an incorrect + "reference to non-existent subpattern" error. + + (d) A pattern like (\P{Yi}{2}\277)? could loop at compile time. + +24. A repeated \S or \W in UTF-8 mode could give wrong answers when multibyte + characters were involved (for example /\S{2}/8g with "A\x{a3}BC"). + +25. Using pcregrep in multiline, inverted mode (-Mv) caused it to loop. + +26. Patterns such as [\P{Yi}A] which include \p or \P and just one other + character were causing crashes (broken optimization). + +27. Patterns such as (\P{Yi}*\277)* (group with possible zero repeat containing + \p or \P) caused a compile-time loop. + +28. More problems have arisen in unanchored patterns when CRLF is a valid line + break. For example, the unstudied pattern [\r\n]A does not match the string + "\r\nA" because change 7.0/46 below moves the current point on by two + characters after failing to match at the start. However, the pattern \nA + *does* match, because it doesn't start till \n, and if [\r\n]A is studied, + the same is true. There doesn't seem any very clean way out of this, but + what I have chosen to do makes the common cases work: PCRE now takes note + of whether there can be an explicit match for \r or \n anywhere in the + pattern, and if so, 7.0/46 no longer applies. As part of this change, + there's a new PCRE_INFO_HASCRORLF option for finding out whether a compiled + pattern has explicit CR or LF references. + +29. Added (*CR) etc for changing newline setting at start of pattern. + + +Version 7.2 19-Jun-07 +--------------------- + + 1. If the fr_FR locale cannot be found for test 3, try the "french" locale, + which is apparently normally available under Windows. + + 2. Re-jig the pcregrep tests with different newline settings in an attempt + to make them independent of the local environment's newline setting. + + 3. Add code to configure.ac to remove -g from the CFLAGS default settings. + + 4. Some of the "internals" tests were previously cut out when the link size + was not 2, because the output contained actual offsets. The recent new + "Z" feature of pcretest means that these can be cut out, making the tests + usable with all link sizes. + + 5. Implemented Stan Switzer's goto replacement for longjmp() when not using + stack recursion. This gives a massive performance boost under BSD, but just + a small improvement under Linux. However, it saves one field in the frame + in all cases. + + 6. Added more features from the forthcoming Perl 5.10: + + (a) (?-n) (where n is a string of digits) is a relative subroutine or + recursion call. It refers to the nth most recently opened parentheses. + + (b) (?+n) is also a relative subroutine call; it refers to the nth next + to be opened parentheses. + + (c) Conditions that refer to capturing parentheses can be specified + relatively, for example, (?(-2)... or (?(+3)... + + (d) \K resets the start of the current match so that everything before + is not part of it. + + (e) \k{name} is synonymous with \k and \k'name' (.NET compatible). + + (f) \g{name} is another synonym - part of Perl 5.10's unification of + reference syntax. + + (g) (?| introduces a group in which the numbering of parentheses in each + alternative starts with the same number. + + (h) \h, \H, \v, and \V match horizontal and vertical whitespace. + + 7. Added two new calls to pcre_fullinfo(): PCRE_INFO_OKPARTIAL and + PCRE_INFO_JCHANGED. + + 8. A pattern such as (.*(.)?)* caused pcre_exec() to fail by either not + terminating or by crashing. Diagnosed by Viktor Griph; it was in the code + for detecting groups that can match an empty string. + + 9. A pattern with a very large number of alternatives (more than several + hundred) was running out of internal workspace during the pre-compile + phase, where pcre_compile() figures out how much memory will be needed. A + bit of new cunning has reduced the workspace needed for groups with + alternatives. The 1000-alternative test pattern now uses 12 bytes of + workspace instead of running out of the 4096 that are available. + +10. Inserted some missing (unsigned int) casts to get rid of compiler warnings. + +11. Applied patch from Google to remove an optimization that didn't quite work. + The report of the bug said: + + pcrecpp::RE("a*").FullMatch("aaa") matches, while + pcrecpp::RE("a*?").FullMatch("aaa") does not, and + pcrecpp::RE("a*?\\z").FullMatch("aaa") does again. + +12. If \p or \P was used in non-UTF-8 mode on a character greater than 127 + it matched the wrong number of bytes. + + +Version 7.1 24-Apr-07 +--------------------- + + 1. Applied Bob Rossi and Daniel G's patches to convert the build system to one + that is more "standard", making use of automake and other Autotools. There + is some re-arrangement of the files and adjustment of comments consequent + on this. + + 2. Part of the patch fixed a problem with the pcregrep tests. The test of -r + for recursive directory scanning broke on some systems because the files + are not scanned in any specific order and on different systems the order + was different. A call to "sort" has been inserted into RunGrepTest for the + approprate test as a short-term fix. In the longer term there may be an + alternative. + + 3. I had an email from Eric Raymond about problems translating some of PCRE's + man pages to HTML (despite the fact that I distribute HTML pages, some + people do their own conversions for various reasons). The problems + concerned the use of low-level troff macros .br and .in. I have therefore + removed all such uses from the man pages (some were redundant, some could + be replaced by .nf/.fi pairs). The 132html script that I use to generate + HTML has been updated to handle .nf/.fi and to complain if it encounters + .br or .in. + + 4. Updated comments in configure.ac that get placed in config.h.in and also + arranged for config.h to be included in the distribution, with the name + config.h.generic, for the benefit of those who have to compile without + Autotools (compare pcre.h, which is now distributed as pcre.h.generic). + + 5. Updated the support (such as it is) for Virtual Pascal, thanks to Stefan + Weber: (1) pcre_internal.h was missing some function renames; (2) updated + makevp.bat for the current PCRE, using the additional files + makevp_c.txt, makevp_l.txt, and pcregexp.pas. + + 6. A Windows user reported a minor discrepancy with test 2, which turned out + to be caused by a trailing space on an input line that had got lost in his + copy. The trailing space was an accident, so I've just removed it. + + 7. Add -Wl,-R... flags in pcre-config.in for *BSD* systems, as I'm told + that is needed. + + 8. Mark ucp_table (in ucptable.h) and ucp_gentype (in pcre_ucp_searchfuncs.c) + as "const" (a) because they are and (b) because it helps the PHP + maintainers who have recently made a script to detect big data structures + in the php code that should be moved to the .rodata section. I remembered + to update Builducptable as well, so it won't revert if ucptable.h is ever + re-created. + + 9. Added some extra #ifdef SUPPORT_UTF8 conditionals into pcretest.c, + pcre_printint.src, pcre_compile.c, pcre_study.c, and pcre_tables.c, in + order to be able to cut out the UTF-8 tables in the latter when UTF-8 + support is not required. This saves 1.5-2K of code, which is important in + some applications. + + Later: more #ifdefs are needed in pcre_ord2utf8.c and pcre_valid_utf8.c + so as not to refer to the tables, even though these functions will never be + called when UTF-8 support is disabled. Otherwise there are problems with a + shared library. + +10. Fixed two bugs in the emulated memmove() function in pcre_internal.h: + + (a) It was defining its arguments as char * instead of void *. + + (b) It was assuming that all moves were upwards in memory; this was true + a long time ago when I wrote it, but is no longer the case. + + The emulated memove() is provided for those environments that have neither + memmove() nor bcopy(). I didn't think anyone used it these days, but that + is clearly not the case, as these two bugs were recently reported. + +11. The script PrepareRelease is now distributed: it calls 132html, CleanTxt, + and Detrail to create the HTML documentation, the .txt form of the man + pages, and it removes trailing spaces from listed files. It also creates + pcre.h.generic and config.h.generic from pcre.h and config.h. In the latter + case, it wraps all the #defines with #ifndefs. This script should be run + before "make dist". + +12. Fixed two fairly obscure bugs concerned with quantified caseless matching + with Unicode property support. + + (a) For a maximizing quantifier, if the two different cases of the + character were of different lengths in their UTF-8 codings (there are + some cases like this - I found 11), and the matching function had to + back up over a mixture of the two cases, it incorrectly assumed they + were both the same length. + + (b) When PCRE was configured to use the heap rather than the stack for + recursion during matching, it was not correctly preserving the data for + the other case of a UTF-8 character when checking ahead for a match + while processing a minimizing repeat. If the check also involved + matching a wide character, but failed, corruption could cause an + erroneous result when trying to check for a repeat of the original + character. + +13. Some tidying changes to the testing mechanism: + + (a) The RunTest script now detects the internal link size and whether there + is UTF-8 and UCP support by running ./pcretest -C instead of relying on + values substituted by "configure". (The RunGrepTest script already did + this for UTF-8.) The configure.ac script no longer substitutes the + relevant variables. + + (b) The debugging options /B and /D in pcretest show the compiled bytecode + with length and offset values. This means that the output is different + for different internal link sizes. Test 2 is skipped for link sizes + other than 2 because of this, bypassing the problem. Unfortunately, + there was also a test in test 3 (the locale tests) that used /B and + failed for link sizes other than 2. Rather than cut the whole test out, + I have added a new /Z option to pcretest that replaces the length and + offset values with spaces. This is now used to make test 3 independent + of link size. (Test 2 will be tidied up later.) + +14. If erroroffset was passed as NULL to pcre_compile, it provoked a + segmentation fault instead of returning the appropriate error message. + +15. In multiline mode when the newline sequence was set to "any", the pattern + ^$ would give a match between the \r and \n of a subject such as "A\r\nB". + This doesn't seem right; it now treats the CRLF combination as the line + ending, and so does not match in that case. It's only a pattern such as ^$ + that would hit this one: something like ^ABC$ would have failed after \r + and then tried again after \r\n. + +16. Changed the comparison command for RunGrepTest from "diff -u" to "diff -ub" + in an attempt to make files that differ only in their line terminators + compare equal. This works on Linux. + +17. Under certain error circumstances pcregrep might try to free random memory + as it exited. This is now fixed, thanks to valgrind. + +19. In pcretest, if the pattern /(?m)^$/g was matched against the string + "abc\r\n\r\n", it found an unwanted second match after the second \r. This + was because its rules for how to advance for /g after matching an empty + string at the end of a line did not allow for this case. They now check for + it specially. + +20. pcretest is supposed to handle patterns and data of any length, by + extending its buffers when necessary. It was getting this wrong when the + buffer for a data line had to be extended. + +21. Added PCRE_NEWLINE_ANYCRLF which is like ANY, but matches only CR, LF, or + CRLF as a newline sequence. + +22. Code for handling Unicode properties in pcre_dfa_exec() wasn't being cut + out by #ifdef SUPPORT_UCP. This did no harm, as it could never be used, but + I have nevertheless tidied it up. + +23. Added some casts to kill warnings from HP-UX ia64 compiler. + +24. Added a man page for pcre-config. + + +Version 7.0 19-Dec-06 +--------------------- + + 1. Fixed a signed/unsigned compiler warning in pcre_compile.c, shown up by + moving to gcc 4.1.1. + + 2. The -S option for pcretest uses setrlimit(); I had omitted to #include + sys/time.h, which is documented as needed for this function. It doesn't + seem to matter on Linux, but it showed up on some releases of OS X. + + 3. It seems that there are systems where bytes whose values are greater than + 127 match isprint() in the "C" locale. The "C" locale should be the + default when a C program starts up. In most systems, only ASCII printing + characters match isprint(). This difference caused the output from pcretest + to vary, making some of the tests fail. I have changed pcretest so that: + + (a) When it is outputting text in the compiled version of a pattern, bytes + other than 32-126 are always shown as hex escapes. + + (b) When it is outputting text that is a matched part of a subject string, + it does the same, unless a different locale has been set for the match + (using the /L modifier). In this case, it uses isprint() to decide. + + 4. Fixed a major bug that caused incorrect computation of the amount of memory + required for a compiled pattern when options that changed within the + pattern affected the logic of the preliminary scan that determines the + length. The relevant options are -x, and -i in UTF-8 mode. The result was + that the computed length was too small. The symptoms of this bug were + either the PCRE error "internal error: code overflow" from pcre_compile(), + or a glibc crash with a message such as "pcretest: free(): invalid next + size (fast)". Examples of patterns that provoked this bug (shown in + pcretest format) are: + + /(?-x: )/x + /(?x)(?-x: \s*#\s*)/ + /((?i)[\x{c0}])/8 + /(?i:[\x{c0}])/8 + + HOWEVER: Change 17 below makes this fix obsolete as the memory computation + is now done differently. + + 5. Applied patches from Google to: (a) add a QuoteMeta function to the C++ + wrapper classes; (b) implement a new function in the C++ scanner that is + more efficient than the old way of doing things because it avoids levels of + recursion in the regex matching; (c) add a paragraph to the documentation + for the FullMatch() function. + + 6. The escape sequence \n was being treated as whatever was defined as + "newline". Not only was this contrary to the documentation, which states + that \n is character 10 (hex 0A), but it also went horribly wrong when + "newline" was defined as CRLF. This has been fixed. + + 7. In pcre_dfa_exec.c the value of an unsigned integer (the variable called c) + was being set to -1 for the "end of line" case (supposedly a value that no + character can have). Though this value is never used (the check for end of + line is "zero bytes in current character"), it caused compiler complaints. + I've changed it to 0xffffffff. + + 8. In pcre_version.c, the version string was being built by a sequence of + C macros that, in the event of PCRE_PRERELEASE being defined as an empty + string (as it is for production releases) called a macro with an empty + argument. The C standard says the result of this is undefined. The gcc + compiler treats it as an empty string (which was what was wanted) but it is + reported that Visual C gives an error. The source has been hacked around to + avoid this problem. + + 9. On the advice of a Windows user, included and in Windows + builds of pcretest, and changed the call to _setmode() to use _O_BINARY + instead of 0x8000. Made all the #ifdefs test both _WIN32 and WIN32 (not all + of them did). + +10. Originally, pcretest opened its input and output without "b"; then I was + told that "b" was needed in some environments, so it was added for release + 5.0 to both the input and output. (It makes no difference on Unix-like + systems.) Later I was told that it is wrong for the input on Windows. I've + now abstracted the modes into two macros, to make it easier to fiddle with + them, and removed "b" from the input mode under Windows. + +11. Added pkgconfig support for the C++ wrapper library, libpcrecpp. + +12. Added -help and --help to pcretest as an official way of being reminded + of the options. + +13. Removed some redundant semicolons after macro calls in pcrecpparg.h.in + and pcrecpp.cc because they annoy compilers at high warning levels. + +14. A bit of tidying/refactoring in pcre_exec.c in the main bumpalong loop. + +15. Fixed an occurrence of == in configure.ac that should have been = (shell + scripts are not C programs :-) and which was not noticed because it works + on Linux. + +16. pcretest is supposed to handle any length of pattern and data line (as one + line or as a continued sequence of lines) by extending its input buffer if + necessary. This feature was broken for very long pattern lines, leading to + a string of junk being passed to pcre_compile() if the pattern was longer + than about 50K. + +17. I have done a major re-factoring of the way pcre_compile() computes the + amount of memory needed for a compiled pattern. Previously, there was code + that made a preliminary scan of the pattern in order to do this. That was + OK when PCRE was new, but as the facilities have expanded, it has become + harder and harder to keep it in step with the real compile phase, and there + have been a number of bugs (see for example, 4 above). I have now found a + cunning way of running 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. This should make future maintenance and development + easier. A side effect of this work is that the limit of 200 on the nesting + depth of parentheses has been removed (though this was never a serious + limitation, I suspect). However, there is a downside: pcre_compile() now + runs more slowly than before (30% or more, depending on the pattern). I + hope this isn't a big issue. There is no effect on runtime performance. + +18. Fixed a minor bug in pcretest: if a pattern line was not terminated by a + newline (only possible for the last line of a file) and it was a + pattern that set a locale (followed by /Lsomething), pcretest crashed. + +19. Added additional timing features to pcretest. (1) The -tm option now times + matching only, not compiling. (2) Both -t and -tm can be followed, as a + separate command line item, by a number that specifies the number of + repeats to use when timing. The default is 50000; this gives better + precision, but takes uncomfortably long for very large patterns. + +20. Extended pcre_study() to be more clever in cases where a branch of a + subpattern has no definite first character. For example, (a*|b*)[cd] would + previously give no result from pcre_study(). Now it recognizes that the + first character must be a, b, c, or d. + +21. There was an incorrect error "recursive call could loop indefinitely" if + a subpattern (or the entire pattern) that was being tested for matching an + empty string contained only one non-empty item after a nested subpattern. + For example, the pattern (?>\x{100}*)\d(?R) provoked this error + incorrectly, because the \d was being skipped in the check. + +22. The pcretest program now has a new pattern option /B and a command line + option -b, which is equivalent to adding /B to every pattern. This causes + it to show the compiled bytecode, without the additional information that + -d shows. The effect of -d is now the same as -b with -i (and similarly, /D + is the same as /B/I). + +23. A new optimization is now able automatically to treat some sequences such + as a*b as a*+b. More specifically, if something simple (such as a character + or a simple class like \d) has an unlimited quantifier, and is followed by + something that cannot possibly match the quantified thing, the quantifier + is automatically "possessified". + +24. A recursive reference to a subpattern whose number was greater than 39 + went wrong under certain circumstances in UTF-8 mode. This bug could also + have affected the operation of pcre_study(). + +25. Realized that a little bit of performance could be had by replacing + (c & 0xc0) == 0xc0 with c >= 0xc0 when processing UTF-8 characters. + +26. Timing data from pcretest is now shown to 4 decimal places instead of 3. + +27. Possessive quantifiers such as a++ were previously implemented by turning + them into atomic groups such as ($>a+). Now they have their own opcodes, + which improves performance. This includes the automatically created ones + from 23 above. + +28. A pattern such as (?=(\w+))\1: which simulates an atomic group using a + lookahead was broken if it was not anchored. PCRE was mistakenly expecting + the first matched character to be a colon. This applied both to named and + numbered groups. + +29. The ucpinternal.h header file was missing its idempotency #ifdef. + +30. I was sent a "project" file called libpcre.a.dev which I understand makes + building PCRE on Windows easier, so I have included it in the distribution. + +31. There is now a check in pcretest against a ridiculously large number being + returned by pcre_exec() or pcre_dfa_exec(). If this happens in a /g or /G + loop, the loop is abandoned. + +32. Forward references to subpatterns in conditions such as (?(2)...) where + subpattern 2 is defined later cause pcre_compile() to search forwards in + the pattern for the relevant set of parentheses. This search went wrong + when there were unescaped parentheses in a character class, parentheses + escaped with \Q...\E, or parentheses in a #-comment in /x mode. + +33. "Subroutine" calls and backreferences were previously restricted to + referencing subpatterns earlier in the regex. This restriction has now + been removed. + +34. Added a number of extra features that are going to be in Perl 5.10. On the + whole, these are just syntactic alternatives for features that PCRE had + previously implemented using the Python syntax or my own invention. The + other formats are all retained for compatibility. + + (a) Named groups can now be defined as (?...) or (?'name'...) as well + as (?P...). The new forms, as well as being in Perl 5.10, are + also .NET compatible. + + (b) A recursion or subroutine call to a named group can now be defined as + (?&name) as well as (?P>name). + + (c) A backreference to a named group can now be defined as \k or + \k'name' as well as (?P=name). The new forms, as well as being in Perl + 5.10, are also .NET compatible. + + (d) A conditional reference to a named group can now use the syntax + (?() or (?('name') as well as (?(name). + + (e) A "conditional group" of the form (?(DEFINE)...) can be used to define + groups (named and numbered) that are never evaluated inline, but can be + called as "subroutines" from elsewhere. In effect, the DEFINE condition + is always false. There may be only one alternative in such a group. + + (f) A test for recursion can be given as (?(R1).. or (?(R&name)... as well + as the simple (?(R). The condition is true only if the most recent + recursion is that of the given number or name. It does not search out + through the entire recursion stack. + + (g) The escape \gN or \g{N} has been added, where N is a positive or + negative number, specifying an absolute or relative reference. + +35. Tidied to get rid of some further signed/unsigned compiler warnings and + some "unreachable code" warnings. + +36. Updated the Unicode property tables to Unicode version 5.0.0. Amongst other + things, this adds five new scripts. + +37. Perl ignores orphaned \E escapes completely. PCRE now does the same. + There were also incompatibilities regarding the handling of \Q..\E inside + character classes, for example with patterns like [\Qa\E-\Qz\E] where the + hyphen was adjacent to \Q or \E. I hope I've cleared all this up now. + +38. Like Perl, PCRE detects when an indefinitely repeated parenthesized group + matches an empty string, and forcibly breaks the loop. There were bugs in + this code in non-simple cases. For a pattern such as ^(a()*)* matched + against aaaa the result was just "a" rather than "aaaa", for example. Two + separate and independent bugs (that affected different cases) have been + fixed. + +39. Refactored the code to abolish the use of different opcodes for small + capturing bracket numbers. This is a tidy that I avoided doing when I + removed the limit on the number of capturing brackets for 3.5 back in 2001. + The new approach is not only tidier, it makes it possible to reduce the + memory needed to fix the previous bug (38). + +40. Implemented PCRE_NEWLINE_ANY to recognize any of the Unicode newline + sequences (http://unicode.org/unicode/reports/tr18/) as "newline" when + processing dot, circumflex, or dollar metacharacters, or #-comments in /x + mode. + +41. Add \R to match any Unicode newline sequence, as suggested in the Unicode + report. + +42. Applied patch, originally from Ari Pollak, modified by Google, to allow + copy construction and assignment in the C++ wrapper. + +43. Updated pcregrep to support "--newline=any". In the process, I fixed a + couple of bugs that could have given wrong results in the "--newline=crlf" + case. + +44. Added a number of casts and did some reorganization of signed/unsigned int + variables following suggestions from Dair Grant. Also renamed the variable + "this" as "item" because it is a C++ keyword. + +45. Arranged for dftables to add + + #include "pcre_internal.h" + + to pcre_chartables.c because without it, gcc 4.x may remove the array + definition from the final binary if PCRE is built into a static library and + dead code stripping is activated. + +46. For an unanchored pattern, if a match attempt fails at the start of a + newline sequence, and the newline setting is CRLF or ANY, and the next two + characters are CRLF, advance by two characters instead of one. + + +Version 6.7 04-Jul-06 +--------------------- + + 1. In order to handle tests when input lines are enormously long, pcretest has + been re-factored so that it automatically extends its buffers when + necessary. The code is crude, but this _is_ just a test program. The + default size has been increased from 32K to 50K. + + 2. The code in pcre_study() was using the value of the re argument before + testing it for NULL. (Of course, in any sensible call of the function, it + won't be NULL.) + + 3. The memmove() emulation function in pcre_internal.h, which is used on + systems that lack both memmove() and bcopy() - that is, hardly ever - + was missing a "static" storage class specifier. + + 4. When UTF-8 mode was not set, PCRE looped when compiling certain patterns + containing an extended class (one that cannot be represented by a bitmap + because it contains high-valued characters or Unicode property items, e.g. + [\pZ]). Almost always one would set UTF-8 mode when processing such a + pattern, but PCRE should not loop if you do not (it no longer does). + [Detail: two cases were found: (a) a repeated subpattern containing an + extended class; (b) a recursive reference to a subpattern that followed a + previous extended class. It wasn't skipping over the extended class + correctly when UTF-8 mode was not set.] + + 5. A negated single-character class was not being recognized as fixed-length + in lookbehind assertions such as (?<=[^f]), leading to an incorrect + compile error "lookbehind assertion is not fixed length". + + 6. The RunPerlTest auxiliary script was showing an unexpected difference + between PCRE and Perl for UTF-8 tests. It turns out that it is hard to + write a Perl script that can interpret lines of an input file either as + byte characters or as UTF-8, which is what "perltest" was being required to + do for the non-UTF-8 and UTF-8 tests, respectively. Essentially what you + can't do is switch easily at run time between having the "use utf8;" pragma + or not. In the end, I fudged it by using the RunPerlTest script to insert + "use utf8;" explicitly for the UTF-8 tests. + + 7. In multiline (/m) mode, PCRE was matching ^ after a terminating newline at + the end of the subject string, contrary to the documentation and to what + Perl does. This was true of both matching functions. Now it matches only at + the start of the subject and immediately after *internal* newlines. + + 8. A call of pcre_fullinfo() from pcretest to get the option bits was passing + a pointer to an int instead of a pointer to an unsigned long int. This + caused problems on 64-bit systems. + + 9. Applied a patch from the folks at Google to pcrecpp.cc, to fix "another + instance of the 'standard' template library not being so standard". + +10. There was no check on the number of named subpatterns nor the maximum + length of a subpattern name. The product of these values is used to compute + the size of the memory block for a compiled pattern. By supplying a very + long subpattern name and a large number of named subpatterns, the size + computation could be caused to overflow. This is now prevented by limiting + the length of names to 32 characters, and the number of named subpatterns + to 10,000. + +11. Subpatterns that are repeated with specific counts have to be replicated in + the compiled pattern. The size of memory for this was computed from the + length of the subpattern and the repeat count. The latter is limited to + 65535, but there was no limit on the former, meaning that integer overflow + could in principle occur. The compiled length of a repeated subpattern is + now limited to 30,000 bytes in order to prevent this. + +12. Added the optional facility to have named substrings with the same name. + +13. Added the ability to use a named substring as a condition, using the + Python syntax: (?(name)yes|no). This overloads (?(R)... and names that + are numbers (not recommended). Forward references are permitted. + +14. Added forward references in named backreferences (if you see what I mean). + +15. In UTF-8 mode, with the PCRE_DOTALL option set, a quantified dot in the + pattern could run off the end of the subject. For example, the pattern + "(?s)(.{1,5})"8 did this with the subject "ab". + +16. If PCRE_DOTALL or PCRE_MULTILINE were set, pcre_dfa_exec() behaved as if + PCRE_CASELESS was set when matching characters that were quantified with ? + or *. + +17. A character class other than a single negated character that had a minimum + but no maximum quantifier - for example [ab]{6,} - was not handled + correctly by pce_dfa_exec(). It would match only one character. + +18. A valid (though odd) pattern that looked like a POSIX character + class but used an invalid character after [ (for example [[,abc,]]) caused + pcre_compile() to give the error "Failed: internal error: code overflow" or + in some cases to crash with a glibc free() error. This could even happen if + the pattern terminated after [[ but there just happened to be a sequence of + letters, a binary zero, and a closing ] in the memory that followed. + +19. Perl's treatment of octal escapes in the range \400 to \777 has changed + over the years. Originally (before any Unicode support), just the bottom 8 + bits were taken. Thus, for example, \500 really meant \100. Nowadays the + output from "man perlunicode" includes this: + + The regular expression compiler produces polymorphic opcodes. That + is, the pattern adapts to the data and automatically switches to + the Unicode character scheme when presented with Unicode data--or + instead uses a traditional byte scheme when presented with byte + data. + + Sadly, a wide octal escape does not cause a switch, and in a string with + no other multibyte characters, these octal escapes are treated as before. + Thus, in Perl, the pattern /\500/ actually matches \100 but the pattern + /\500|\x{1ff}/ matches \500 or \777 because the whole thing is treated as a + Unicode string. + + I have not perpetrated such confusion in PCRE. Up till now, it took just + the bottom 8 bits, as in old Perl. I have now made octal escapes with + values greater than \377 illegal in non-UTF-8 mode. In UTF-8 mode they + translate to the appropriate multibyte character. + +29. Applied some refactoring to reduce the number of warnings from Microsoft + and Borland compilers. This has included removing the fudge introduced + seven years ago for the OS/2 compiler (see 2.02/2 below) because it caused + a warning about an unused variable. + +21. PCRE has not included VT (character 0x0b) in the set of whitespace + characters since release 4.0, because Perl (from release 5.004) does not. + [Or at least, is documented not to: some releases seem to be in conflict + with the documentation.] However, when a pattern was studied with + pcre_study() and all its branches started with \s, PCRE still included VT + as a possible starting character. Of course, this did no harm; it just + caused an unnecessary match attempt. + +22. Removed a now-redundant internal flag bit that recorded the fact that case + dependency changed within the pattern. This was once needed for "required + byte" processing, but is no longer used. This recovers a now-scarce options + bit. Also moved the least significant internal flag bit to the most- + significant bit of the word, which was not previously used (hangover from + the days when it was an int rather than a uint) to free up another bit for + the future. + +23. Added support for CRLF line endings as well as CR and LF. As well as the + default being selectable at build time, it can now be changed at runtime + via the PCRE_NEWLINE_xxx flags. There are now options for pcregrep to + specify that it is scanning data with non-default line endings. + +24. Changed the definition of CXXLINK to make it agree with the definition of + LINK in the Makefile, by replacing LDFLAGS to CXXFLAGS. + +25. Applied Ian Taylor's patches to avoid using another stack frame for tail + recursions. This makes a big different to stack usage for some patterns. + +26. If a subpattern containing a named recursion or subroutine reference such + as (?P>B) was quantified, for example (xxx(?P>B)){3}, the calculation of + the space required for the compiled pattern went wrong and gave too small a + value. Depending on the environment, this could lead to "Failed: internal + error: code overflow at offset 49" or "glibc detected double free or + corruption" errors. + +27. Applied patches from Google (a) to support the new newline modes and (b) to + advance over multibyte UTF-8 characters in GlobalReplace. + +28. Change free() to pcre_free() in pcredemo.c. Apparently this makes a + difference for some implementation of PCRE in some Windows version. + +29. Added some extra testing facilities to pcretest: + + \q in a data line sets the "match limit" value + \Q in a data line sets the "match recursion limt" value + -S sets the stack size, where is in megabytes + + The -S option isn't available for Windows. + + +Version 6.6 06-Feb-06 +--------------------- + + 1. Change 16(a) for 6.5 broke things, because PCRE_DATA_SCOPE was not defined + in pcreposix.h. I have copied the definition from pcre.h. + + 2. Change 25 for 6.5 broke compilation in a build directory out-of-tree + because pcre.h is no longer a built file. + + 3. Added Jeff Friedl's additional debugging patches to pcregrep. These are + not normally included in the compiled code. + + +Version 6.5 01-Feb-06 +--------------------- + + 1. When using the partial match feature with pcre_dfa_exec(), it was not + anchoring the second and subsequent partial matches at the new starting + point. This could lead to incorrect results. For example, with the pattern + /1234/, partially matching against "123" and then "a4" gave a match. + + 2. Changes to pcregrep: + + (a) All non-match returns from pcre_exec() were being treated as failures + to match the line. Now, unless the error is PCRE_ERROR_NOMATCH, an + error message is output. Some extra information is given for the + PCRE_ERROR_MATCHLIMIT and PCRE_ERROR_RECURSIONLIMIT errors, which are + probably the only errors that are likely to be caused by users (by + specifying a regex that has nested indefinite repeats, for instance). + If there are more than 20 of these errors, pcregrep is abandoned. + + (b) A binary zero was treated as data while matching, but terminated the + output line if it was written out. This has been fixed: binary zeroes + are now no different to any other data bytes. + + (c) Whichever of the LC_ALL or LC_CTYPE environment variables is set is + used to set a locale for matching. The --locale=xxxx long option has + been added (no short equivalent) to specify a locale explicitly on the + pcregrep command, overriding the environment variables. + + (d) When -B was used with -n, some line numbers in the output were one less + than they should have been. + + (e) Added the -o (--only-matching) option. + + (f) If -A or -C was used with -c (count only), some lines of context were + accidentally printed for the final match. + + (g) Added the -H (--with-filename) option. + + (h) The combination of options -rh failed to suppress file names for files + that were found from directory arguments. + + (i) Added the -D (--devices) and -d (--directories) options. + + (j) Added the -F (--fixed-strings) option. + + (k) Allow "-" to be used as a file name for -f as well as for a data file. + + (l) Added the --colo(u)r option. + + (m) Added Jeffrey Friedl's -S testing option, but within #ifdefs so that it + is not present by default. + + 3. A nasty bug was discovered in the handling of recursive patterns, that is, + items such as (?R) or (?1), when the recursion could match a number of + alternatives. If it matched one of the alternatives, but subsequently, + outside the recursion, there was a failure, the code tried to back up into + the recursion. However, because of the way PCRE is implemented, this is not + possible, and the result was an incorrect result from the match. + + In order to prevent this happening, the specification of recursion has + been changed so that all such subpatterns are automatically treated as + atomic groups. Thus, for example, (?R) is treated as if it were (?>(?R)). + + 4. I had overlooked the fact that, in some locales, there are characters for + which isalpha() is true but neither isupper() nor islower() are true. In + the fr_FR locale, for instance, the \xAA and \xBA characters (ordmasculine + and ordfeminine) are like this. This affected the treatment of \w and \W + when they appeared in character classes, but not when they appeared outside + a character class. The bit map for "word" characters is now created + separately from the results of isalnum() instead of just taking it from the + upper, lower, and digit maps. (Plus the underscore character, of course.) + + 5. The above bug also affected the handling of POSIX character classes such as + [[:alpha:]] and [[:alnum:]]. These do not have their own bit maps in PCRE's + permanent tables. Instead, the bit maps for such a class were previously + created as the appropriate unions of the upper, lower, and digit bitmaps. + Now they are created by subtraction from the [[:word:]] class, which has + its own bitmap. + + 6. The [[:blank:]] character class matches horizontal, but not vertical space. + It is created by subtracting the vertical space characters (\x09, \x0a, + \x0b, \x0c) from the [[:space:]] bitmap. Previously, however, the + subtraction was done in the overall bitmap for a character class, meaning + that a class such as [\x0c[:blank:]] was incorrect because \x0c would not + be recognized. This bug has been fixed. + + 7. Patches from the folks at Google: + + (a) pcrecpp.cc: "to handle a corner case that may or may not happen in + real life, but is still worth protecting against". + + (b) pcrecpp.cc: "corrects a bug when negative radixes are used with + regular expressions". + + (c) pcre_scanner.cc: avoid use of std::count() because not all systems + have it. + + (d) Split off pcrecpparg.h from pcrecpp.h and had the former built by + "configure" and the latter not, in order to fix a problem somebody had + with compiling the Arg class on HP-UX. + + (e) Improve the error-handling of the C++ wrapper a little bit. + + (f) New tests for checking recursion limiting. + + 8. The pcre_memmove() function, which is used only if the environment does not + have a standard memmove() function (and is therefore rarely compiled), + contained two bugs: (a) use of int instead of size_t, and (b) it was not + returning a result (though PCRE never actually uses the result). + + 9. In the POSIX regexec() interface, if nmatch is specified as a ridiculously + large number - greater than INT_MAX/(3*sizeof(int)) - REG_ESPACE is + returned instead of calling malloc() with an overflowing number that would + most likely cause subsequent chaos. + +10. The debugging option of pcretest was not showing the NO_AUTO_CAPTURE flag. + +11. The POSIX flag REG_NOSUB is now supported. When a pattern that was compiled + with this option is matched, the nmatch and pmatch options of regexec() are + ignored. + +12. Added REG_UTF8 to the POSIX interface. This is not defined by POSIX, but is + provided in case anyone wants to the the POSIX interface with UTF-8 + strings. + +13. Added CXXLDFLAGS to the Makefile parameters to provide settings only on the + C++ linking (needed for some HP-UX environments). + +14. Avoid compiler warnings in get_ucpname() when compiled without UCP support + (unused parameter) and in the pcre_printint() function (omitted "default" + switch label when the default is to do nothing). + +15. Added some code to make it possible, when PCRE is compiled as a C++ + library, to replace subject pointers for pcre_exec() with a smart pointer + class, thus making it possible to process discontinuous strings. + +16. The two macros PCRE_EXPORT and PCRE_DATA_SCOPE are confusing, and perform + much the same function. They were added by different people who were trying + to make PCRE easy to compile on non-Unix systems. It has been suggested + that PCRE_EXPORT be abolished now that there is more automatic apparatus + for compiling on Windows systems. I have therefore replaced it with + PCRE_DATA_SCOPE. This is set automatically for Windows; if not set it + defaults to "extern" for C or "extern C" for C++, which works fine on + Unix-like systems. It is now possible to override the value of PCRE_DATA_ + SCOPE with something explicit in config.h. In addition: + + (a) pcreposix.h still had just "extern" instead of either of these macros; + I have replaced it with PCRE_DATA_SCOPE. + + (b) Functions such as _pcre_xclass(), which are internal to the library, + but external in the C sense, all had PCRE_EXPORT in their definitions. + This is apparently wrong for the Windows case, so I have removed it. + (It makes no difference on Unix-like systems.) + +17. Added a new limit, MATCH_LIMIT_RECURSION, which limits the depth of nesting + of recursive calls to match(). This is different to MATCH_LIMIT because + that limits the total number of calls to match(), not all of which increase + the depth of recursion. Limiting the recursion depth limits the amount of + stack (or heap if NO_RECURSE is set) that is used. The default can be set + when PCRE is compiled, and changed at run time. A patch from Google adds + this functionality to the C++ interface. + +18. Changes to the handling of Unicode character properties: + + (a) Updated the table to Unicode 4.1.0. + + (b) Recognize characters that are not in the table as "Cn" (undefined). + + (c) I revised the way the table is implemented to a much improved format + which includes recognition of ranges. It now supports the ranges that + are defined in UnicodeData.txt, and it also amalgamates other + characters into ranges. This has reduced the number of entries in the + table from around 16,000 to around 3,000, thus reducing its size + considerably. I realized I did not need to use a tree structure after + all - a binary chop search is just as efficient. Having reduced the + number of entries, I extended their size from 6 bytes to 8 bytes to + allow for more data. + + (d) Added support for Unicode script names via properties such as \p{Han}. + +19. In UTF-8 mode, a backslash followed by a non-Ascii character was not + matching that character. + +20. When matching a repeated Unicode property with a minimum greater than zero, + (for example \pL{2,}), PCRE could look past the end of the subject if it + reached it while seeking the minimum number of characters. This could + happen only if some of the characters were more than one byte long, because + there is a check for at least the minimum number of bytes. + +21. Refactored the implementation of \p and \P so as to be more general, to + allow for more different types of property in future. This has changed the + compiled form incompatibly. Anybody with saved compiled patterns that use + \p or \P will have to recompile them. + +22. Added "Any" and "L&" to the supported property types. + +23. Recognize \x{...} as a code point specifier, even when not in UTF-8 mode, + but give a compile time error if the value is greater than 0xff. + +24. The man pages for pcrepartial, pcreprecompile, and pcre_compile2 were + accidentally not being installed or uninstalled. + +25. The pcre.h file was built from pcre.h.in, but the only changes that were + made were to insert the current release number. This seemed silly, because + it made things harder for people building PCRE on systems that don't run + "configure". I have turned pcre.h into a distributed file, no longer built + by "configure", with the version identification directly included. There is + no longer a pcre.h.in file. + + However, this change necessitated a change to the pcre-config script as + well. It is built from pcre-config.in, and one of the substitutions was the + release number. I have updated configure.ac so that ./configure now finds + the release number by grepping pcre.h. + +26. Added the ability to run the tests under valgrind. + + +Version 6.4 05-Sep-05 +--------------------- + + 1. Change 6.0/10/(l) to pcregrep introduced a bug that caused separator lines + "--" to be printed when multiple files were scanned, even when none of the + -A, -B, or -C options were used. This is not compatible with Gnu grep, so I + consider it to be a bug, and have restored the previous behaviour. + + 2. A couple of code tidies to get rid of compiler warnings. + + 3. The pcretest program used to cheat by referring to symbols in the library + whose names begin with _pcre_. These are internal symbols that are not + really supposed to be visible externally, and in some environments it is + possible to suppress them. The cheating is now confined to including + certain files from the library's source, which is a bit cleaner. + + 4. Renamed pcre.in as pcre.h.in to go with pcrecpp.h.in; it also makes the + file's purpose clearer. + + 5. Reorganized pcre_ucp_findchar(). + + +Version 6.3 15-Aug-05 +--------------------- + + 1. The file libpcre.pc.in did not have general read permission in the tarball. + + 2. There were some problems when building without C++ support: + + (a) If C++ support was not built, "make install" and "make test" still + tried to test it. + + (b) There were problems when the value of CXX was explicitly set. Some + changes have been made to try to fix these, and ... + + (c) --disable-cpp can now be used to explicitly disable C++ support. + + (d) The use of @CPP_OBJ@ directly caused a blank line preceded by a + backslash in a target when C++ was disabled. This confuses some + versions of "make", apparently. Using an intermediate variable solves + this. (Same for CPP_LOBJ.) + + 3. $(LINK_FOR_BUILD) now includes $(CFLAGS_FOR_BUILD) and $(LINK) + (non-Windows) now includes $(CFLAGS) because these flags are sometimes + necessary on certain architectures. + + 4. Added a setting of -export-symbols-regex to the link command to remove + those symbols that are exported in the C sense, but actually are local + within the library, and not documented. Their names all begin with + "_pcre_". This is not a perfect job, because (a) we have to except some + symbols that pcretest ("illegally") uses, and (b) the facility isn't always + available (and never for static libraries). I have made a note to try to + find a way round (a) in the future. + + +Version 6.2 01-Aug-05 +--------------------- + + 1. There was no test for integer overflow of quantifier values. A construction + such as {1111111111111111} would give undefined results. What is worse, if + a minimum quantifier for a parenthesized subpattern overflowed and became + negative, the calculation of the memory size went wrong. This could have + led to memory overwriting. + + 2. Building PCRE using VPATH was broken. Hopefully it is now fixed. + + 3. Added "b" to the 2nd argument of fopen() in dftables.c, for non-Unix-like + operating environments where this matters. + + 4. Applied Giuseppe Maxia's patch to add additional features for controlling + PCRE options from within the C++ wrapper. + + 5. Named capturing subpatterns were not being correctly counted when a pattern + was compiled. This caused two problems: (a) If there were more than 100 + such subpatterns, the calculation of the memory needed for the whole + compiled pattern went wrong, leading to an overflow error. (b) Numerical + back references of the form \12, where the number was greater than 9, were + not recognized as back references, even though there were sufficient + previous subpatterns. + + 6. Two minor patches to pcrecpp.cc in order to allow it to compile on older + versions of gcc, e.g. 2.95.4. + + +Version 6.1 21-Jun-05 +--------------------- + + 1. There was one reference to the variable "posix" in pcretest.c that was not + surrounded by "#if !defined NOPOSIX". + + 2. Make it possible to compile pcretest without DFA support, UTF8 support, or + the cross-check on the old pcre_info() function, for the benefit of the + cut-down version of PCRE that is currently imported into Exim. + + 3. A (silly) pattern starting with (?i)(?-i) caused an internal space + allocation error. I've done the easy fix, which wastes 2 bytes for sensible + patterns that start (?i) but I don't think that matters. The use of (?i) is + just an example; this all applies to the other options as well. + + 4. Since libtool seems to echo the compile commands it is issuing, the output + from "make" can be reduced a bit by putting "@" in front of each libtool + compile command. + + 5. Patch from the folks at Google for configure.in to be a bit more thorough + in checking for a suitable C++ installation before trying to compile the + C++ stuff. This should fix a reported problem when a compiler was present, + but no suitable headers. + + 6. The man pages all had just "PCRE" as their title. I have changed them to + be the relevant file name. I have also arranged that these names are + retained in the file doc/pcre.txt, which is a concatenation in text format + of all the man pages except the little individual ones for each function. + + 7. The NON-UNIX-USE file had not been updated for the different set of source + files that come with release 6. I also added a few comments about the C++ + wrapper. + + +Version 6.0 07-Jun-05 +--------------------- + + 1. Some minor internal re-organization to help with my DFA experiments. + + 2. Some missing #ifdef SUPPORT_UCP conditionals in pcretest and printint that + didn't matter for the library itself when fully configured, but did matter + when compiling without UCP support, or within Exim, where the ucp files are + not imported. + + 3. Refactoring of the library code to split up the various functions into + different source modules. The addition of the new DFA matching code (see + below) to a single monolithic source would have made it really too + unwieldy, quite apart from causing all the code to be include in a + statically linked application, when only some functions are used. This is + relevant even without the DFA addition now that patterns can be compiled in + one application and matched in another. + + The downside of splitting up is that there have to be some external + functions and data tables that are used internally in different modules of + the library but which are not part of the API. These have all had their + names changed to start with "_pcre_" so that they are unlikely to clash + with other external names. + + 4. Added an alternate matching function, pcre_dfa_exec(), which matches using + a different (DFA) algorithm. Although it is slower than the original + function, it does have some advantages for certain types of matching + problem. + + 5. Upgrades to pcretest in order to test the features of pcre_dfa_exec(), + including restarting after a partial match. + + 6. A patch for pcregrep that defines INVALID_FILE_ATTRIBUTES if it is not + defined when compiling for Windows was sent to me. I have put it into the + code, though I have no means of testing or verifying it. + + 7. Added the pcre_refcount() auxiliary function. + + 8. Added the PCRE_FIRSTLINE option. This constrains an unanchored pattern to + match before or at the first newline in the subject string. In pcretest, + the /f option on a pattern can be used to set this. + + 9. A repeated \w when used in UTF-8 mode with characters greater than 256 + would behave wrongly. This has been present in PCRE since release 4.0. + +10. A number of changes to the pcregrep command: + + (a) Refactored how -x works; insert ^(...)$ instead of setting + PCRE_ANCHORED and checking the length, in preparation for adding + something similar for -w. + + (b) Added the -w (match as a word) option. + + (c) Refactored the way lines are read and buffered so as to have more + than one at a time available. + + (d) Implemented a pcregrep test script. + + (e) Added the -M (multiline match) option. This allows patterns to match + over several lines of the subject. The buffering ensures that at least + 8K, or the rest of the document (whichever is the shorter) is available + for matching (and similarly the previous 8K for lookbehind assertions). + + (f) Changed the --help output so that it now says + + -w, --word-regex(p) + + instead of two lines, one with "regex" and the other with "regexp" + because that confused at least one person since the short forms are the + same. (This required a bit of code, as the output is generated + automatically from a table. It wasn't just a text change.) + + (g) -- can be used to terminate pcregrep options if the next thing isn't an + option but starts with a hyphen. Could be a pattern or a path name + starting with a hyphen, for instance. + + (h) "-" can be given as a file name to represent stdin. + + (i) When file names are being printed, "(standard input)" is used for + the standard input, for compatibility with GNU grep. Previously + "" was used. + + (j) The option --label=xxx can be used to supply a name to be used for + stdin when file names are being printed. There is no short form. + + (k) Re-factored the options decoding logic because we are going to add + two more options that take data. Such options can now be given in four + different ways, e.g. "-fname", "-f name", "--file=name", "--file name". + + (l) Added the -A, -B, and -C options for requesting that lines of context + around matches be printed. + + (m) Added the -L option to print the names of files that do not contain + any matching lines, that is, the complement of -l. + + (n) The return code is 2 if any file cannot be opened, but pcregrep does + continue to scan other files. + + (o) The -s option was incorrectly implemented. For compatibility with other + greps, it now suppresses the error message for a non-existent or non- + accessible file (but not the return code). There is a new option called + -q that suppresses the output of matching lines, which was what -s was + previously doing. + + (p) Added --include and --exclude options to specify files for inclusion + and exclusion when recursing. + +11. The Makefile was not using the Autoconf-supported LDFLAGS macro properly. + Hopefully, it now does. + +12. Missing cast in pcre_study(). + +13. Added an "uninstall" target to the makefile. + +14. Replaced "extern" in the function prototypes in Makefile.in with + "PCRE_DATA_SCOPE", which defaults to 'extern' or 'extern "C"' in the Unix + world, but is set differently for Windows. + +15. Added a second compiling function called pcre_compile2(). The only + difference is that it has an extra argument, which is a pointer to an + integer error code. When there is a compile-time failure, this is set + non-zero, in addition to the error test pointer being set to point to an + error message. The new argument may be NULL if no error number is required + (but then you may as well call pcre_compile(), which is now just a + wrapper). This facility is provided because some applications need a + numeric error indication, but it has also enabled me to tidy up the way + compile-time errors are handled in the POSIX wrapper. + +16. Added VPATH=.libs to the makefile; this should help when building with one + prefix path and installing with another. (Or so I'm told by someone who + knows more about this stuff than I do.) + +17. Added a new option, REG_DOTALL, to the POSIX function regcomp(). This + passes PCRE_DOTALL to the pcre_compile() function, making the "." character + match everything, including newlines. This is not POSIX-compatible, but + somebody wanted the feature. From pcretest it can be activated by using + both the P and the s flags. + +18. AC_PROG_LIBTOOL appeared twice in Makefile.in. Removed one. + +19. libpcre.pc was being incorrectly installed as executable. + +20. A couple of places in pcretest check for end-of-line by looking for '\n'; + it now also looks for '\r' so that it will work unmodified on Windows. + +21. Added Google's contributed C++ wrapper to the distribution. + +22. Added some untidy missing memory free() calls in pcretest, to keep + Electric Fence happy when testing. + + + +Version 5.0 13-Sep-04 +--------------------- + + 1. Internal change: literal characters are no longer packed up into items + containing multiple characters in a single byte-string. Each character + is now matched using a separate opcode. However, there may be more than one + byte in the character in UTF-8 mode. + + 2. The pcre_callout_block structure has two new fields: pattern_position and + next_item_length. These contain the offset in the pattern to the next match + item, and its length, respectively. + + 3. The PCRE_AUTO_CALLOUT option for pcre_compile() requests the automatic + insertion of callouts before each pattern item. Added the /C option to + pcretest to make use of this. + + 4. On the advice of a Windows user, the lines + + #if defined(_WIN32) || defined(WIN32) + _setmode( _fileno( stdout ), 0x8000 ); + #endif /* defined(_WIN32) || defined(WIN32) */ + + have been added to the source of pcretest. This apparently does useful + magic in relation to line terminators. + + 5. Changed "r" and "w" in the calls to fopen() in pcretest to "rb" and "wb" + for the benefit of those environments where the "b" makes a difference. + + 6. The icc compiler has the same options as gcc, but "configure" doesn't seem + to know about it. I have put a hack into configure.in that adds in code + to set GCC=yes if CC=icc. This seems to end up at a point in the + generated configure script that is early enough to affect the setting of + compiler options, which is what is needed, but I have no means of testing + whether it really works. (The user who reported this had patched the + generated configure script, which of course I cannot do.) + + LATER: After change 22 below (new libtool files), the configure script + seems to know about icc (and also ecc). Therefore, I have commented out + this hack in configure.in. + + 7. Added support for pkg-config (2 patches were sent in). + + 8. Negated POSIX character classes that used a combination of internal tables + were completely broken. These were [[:^alpha:]], [[:^alnum:]], and + [[:^ascii]]. Typically, they would match almost any characters. The other + POSIX classes were not broken in this way. + + 9. Matching the pattern "\b.*?" against "ab cd", starting at offset 1, failed + to find the match, as PCRE was deluded into thinking that the match had to + start at the start point or following a newline. The same bug applied to + patterns with negative forward assertions or any backward assertions + preceding ".*" at the start, unless the pattern required a fixed first + character. This was a failing pattern: "(?!.bcd).*". The bug is now fixed. + +10. In UTF-8 mode, when moving forwards in the subject after a failed match + starting at the last subject character, bytes beyond the end of the subject + string were read. + +11. Renamed the variable "class" as "classbits" to make life easier for C++ + users. (Previously there was a macro definition, but it apparently wasn't + enough.) + +12. Added the new field "tables" to the extra data so that tables can be passed + in at exec time, or the internal tables can be re-selected. This allows + a compiled regex to be saved and re-used at a later time by a different + program that might have everything at different addresses. + +13. Modified the pcre-config script so that, when run on Solaris, it shows a + -R library as well as a -L library. + +14. The debugging options of pcretest (-d on the command line or D on a + pattern) showed incorrect output for anything following an extended class + that contained multibyte characters and which was followed by a quantifier. + +15. Added optional support for general category Unicode character properties + via the \p, \P, and \X escapes. Unicode property support implies UTF-8 + support. It adds about 90K to the size of the library. The meanings of the + inbuilt class escapes such as \d and \s have NOT been changed. + +16. Updated pcredemo.c to include calls to free() to release the memory for the + compiled pattern. + +17. The generated file chartables.c was being created in the source directory + instead of in the building directory. This caused the build to fail if the + source directory was different from the building directory, and was + read-only. + +18. Added some sample Win commands from Mark Tetrode into the NON-UNIX-USE + file. No doubt somebody will tell me if they don't make sense... Also added + Dan Mooney's comments about building on OpenVMS. + +19. Added support for partial matching via the PCRE_PARTIAL option for + pcre_exec() and the \P data escape in pcretest. + +20. Extended pcretest with 3 new pattern features: + + (i) A pattern option of the form ">rest-of-line" causes pcretest to + write the compiled pattern to the file whose name is "rest-of-line". + This is a straight binary dump of the data, with the saved pointer to + the character tables forced to be NULL. The study data, if any, is + written too. After writing, pcretest reads a new pattern. + + (ii) If, instead of a pattern, ": new target + : new target + : use native compiler + : use native linker + : handle Windows platform correctly + : ditto + : ditto + copy DLL to top builddir before testing + + As part of these changes, -no-undefined was removed again. This was reported + to give trouble on HP-UX 11.0, so getting rid of it seems like a good idea + in any case. + +3. Some tidies to get rid of compiler warnings: + + . In the match_data structure, match_limit was an unsigned long int, whereas + match_call_count was an int. I've made them both unsigned long ints. + + . In pcretest the fact that a const uschar * doesn't automatically cast to + a void * provoked a warning. + + . Turning on some more compiler warnings threw up some "shadow" variables + and a few more missing casts. + +4. If PCRE was complied with UTF-8 support, but called without the PCRE_UTF8 + option, a class that contained a single character with a value between 128 + and 255 (e.g. /[\xFF]/) caused PCRE to crash. + +5. If PCRE was compiled with UTF-8 support, but called without the PCRE_UTF8 + option, a class that contained several characters, but with at least one + whose value was between 128 and 255 caused PCRE to crash. + + +Version 4.1 12-Mar-03 +--------------------- + +1. Compiling with gcc -pedantic found a couple of places where casts were +needed, and a string in dftables.c that was longer than standard compilers are +required to support. + +2. Compiling with Sun's compiler found a few more places where the code could +be tidied up in order to avoid warnings. + +3. The variables for cross-compiling were called HOST_CC and HOST_CFLAGS; the +first of these names is deprecated in the latest Autoconf in favour of the name +CC_FOR_BUILD, because "host" is typically used to mean the system on which the +compiled code will be run. I can't find a reference for HOST_CFLAGS, but by +analogy I have changed it to CFLAGS_FOR_BUILD. + +4. Added -no-undefined to the linking command in the Makefile, because this is +apparently helpful for Windows. To make it work, also added "-L. -lpcre" to the +linking step for the pcreposix library. + +5. PCRE was failing to diagnose the case of two named groups with the same +name. + +6. A problem with one of PCRE's optimizations was discovered. PCRE remembers a +literal character that is needed in the subject for a match, and scans along to +ensure that it is present before embarking on the full matching process. This +saves time in cases of nested unlimited repeats that are never going to match. +Problem: the scan can take a lot of time if the subject is very long (e.g. +megabytes), thus penalizing straightforward matches. It is now done only if the +amount of subject to be scanned is less than 1000 bytes. + +7. A lesser problem with the same optimization is that it was recording the +first character of an anchored pattern as "needed", thus provoking a search +right along the subject, even when the first match of the pattern was going to +fail. The "needed" character is now not set for anchored patterns, unless it +follows something in the pattern that is of non-fixed length. Thus, it still +fulfils its original purpose of finding quick non-matches in cases of nested +unlimited repeats, but isn't used for simple anchored patterns such as /^abc/. + + +Version 4.0 17-Feb-03 +--------------------- + +1. If a comment in an extended regex that started immediately after a meta-item +extended to the end of string, PCRE compiled incorrect data. This could lead to +all kinds of weird effects. Example: /#/ was bad; /()#/ was bad; /a#/ was not. + +2. Moved to autoconf 2.53 and libtool 1.4.2. + +3. Perl 5.8 no longer needs "use utf8" for doing UTF-8 things. Consequently, +the special perltest8 script is no longer needed - all the tests can be run +from a single perltest script. + +4. From 5.004, Perl has not included the VT character (0x0b) in the set defined +by \s. It has now been removed in PCRE. This means it isn't recognized as +whitespace in /x regexes too, which is the same as Perl. Note that the POSIX +class [:space:] *does* include VT, thereby creating a mess. + +5. Added the class [:blank:] (a GNU extension from Perl 5.8) to match only +space and tab. + +6. Perl 5.005 was a long time ago. It's time to amalgamate the tests that use +its new features into the main test script, reducing the number of scripts. + +7. Perl 5.8 has changed the meaning of patterns like /a(?i)b/. Earlier versions +were backward compatible, and made the (?i) apply to the whole pattern, as if +/i were given. Now it behaves more logically, and applies the option setting +only to what follows. PCRE has been changed to follow suit. However, if it +finds options settings right at the start of the pattern, it extracts them into +the global options, as before. Thus, they show up in the info data. + +8. Added support for the \Q...\E escape sequence. 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 will cause variable +interpolation. Note the following examples: + + Pattern PCRE matches Perl matches + + \Qabc$xyz\E abc$xyz abc followed by the contents of $xyz + \Qabc\$xyz\E abc\$xyz abc\$xyz + \Qabc\E\$\Qxyz\E abc$xyz abc$xyz + +For compatibility with Perl, \Q...\E sequences are recognized inside character +classes as well as outside them. + +9. Re-organized 3 code statements in pcretest to avoid "overflow in +floating-point constant arithmetic" warnings from a Microsoft compiler. Added a +(size_t) cast to one statement in pcretest and one in pcreposix to avoid +signed/unsigned warnings. + +10. SunOS4 doesn't have strtoul(). This was used only for unpicking the -o +option for pcretest, so I've replaced it by a simple function that does just +that job. + +11. pcregrep was ending with code 0 instead of 2 for the commands "pcregrep" or +"pcregrep -". + +12. Added "possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's +Java package. This provides some syntactic sugar for simple cases of what my +documentation calls "once-only subpatterns". A pattern such as x*+ is the same +as (?>x*). In other words, if what is inside (?>...) is just a single repeated +item, you can use this simplified notation. Note that only makes sense with +greedy quantifiers. Consequently, the use of the possessive quantifier forces +greediness, whatever the setting of the PCRE_UNGREEDY option. + +13. A change of greediness default within a pattern was not taking effect at +the current level for patterns like /(b+(?U)a+)/. It did apply to parenthesized +subpatterns that followed. Patterns like /b+(?U)a+/ worked because the option +was abstracted outside. + +14. PCRE now supports the \G assertion. It is true when the current matching +position is at the start point of the match. This differs from \A when the +starting offset is non-zero. Used with the /g option of pcretest (or similar +code), it works in the same way as it does for Perl's /g option. If all +alternatives of a regex begin with \G, the expression is anchored to the start +match position, and the "anchored" flag is set in the compiled expression. + +15. Some bugs concerning the handling of certain option changes within patterns +have been fixed. These applied to options other than (?ims). For example, +"a(?x: b c )d" did not match "XabcdY" but did match "Xa b c dY". It should have +been the other way round. Some of this was related to change 7 above. + +16. PCRE now gives errors for /[.x.]/ and /[=x=]/ as unsupported POSIX +features, as Perl does. Previously, PCRE gave the warnings only for /[[.x.]]/ +and /[[=x=]]/. PCRE now also gives an error for /[:name:]/ because it supports +POSIX classes only within a class (e.g. /[[:alpha:]]/). + +17. Added support for Perl's \C escape. This matches one byte, even in UTF8 +mode. Unlike ".", it always matches newline, whatever the setting of +PCRE_DOTALL. However, PCRE does not permit \C to appear in lookbehind +assertions. Perl allows it, but it doesn't (in general) work because it can't +calculate the length of the lookbehind. At least, that's the case for Perl +5.8.0 - I've been told they are going to document that it doesn't work in +future. + +18. Added an error diagnosis for escapes that PCRE does not support: these are +\L, \l, \N, \P, \p, \U, \u, and \X. + +19. Although correctly diagnosing a missing ']' in a character class, PCRE was +reading past the end of the pattern in cases such as /[abcd/. + +20. PCRE was getting more memory than necessary for patterns with classes that +contained both POSIX named classes and other characters, e.g. /[[:space:]abc/. + +21. Added some code, conditional on #ifdef VPCOMPAT, to make life easier for +compiling PCRE for use with Virtual Pascal. + +22. Small fix to the Makefile to make it work properly if the build is done +outside the source tree. + +23. Added a new extension: a condition to go with recursion. If a conditional +subpattern starts with (?(R) the "true" branch is used if recursion has +happened, whereas the "false" branch is used only at the top level. + +24. When there was a very long string of literal characters (over 255 bytes +without UTF support, over 250 bytes with UTF support), the computation of how +much memory was required could be incorrect, leading to segfaults or other +strange effects. + +25. PCRE was incorrectly assuming anchoring (either to start of subject or to +start of line for a non-DOTALL pattern) when a pattern started with (.*) and +there was a subsequent back reference to those brackets. This meant that, for +example, /(.*)\d+\1/ failed to match "abc123bc". Unfortunately, it isn't +possible to check for precisely this case. All we can do is abandon the +optimization if .* occurs inside capturing brackets when there are any back +references whatsoever. (See below for a better fix that came later.) + +26. The handling of the optimization for finding the first character of a +non-anchored pattern, and for finding a character that is required later in the +match were failing in some cases. This didn't break the matching; it just +failed to optimize when it could. The way this is done has been re-implemented. + +27. Fixed typo in error message for invalid (?R item (it said "(?p"). + +28. Added a new feature that provides some of the functionality that Perl +provides with (?{...}). The facility is termed a "callout". The way it is done +in PCRE is for the caller to provide an optional function, by setting +pcre_callout to its entry point. Like pcre_malloc and pcre_free, this is a +global variable. By default it is unset, which disables all calling out. To get +the function called, the regex must include (?C) at appropriate points. This +is, in fact, equivalent to (?C0), and any number <= 255 may be given with (?C). +This provides a means of identifying different callout points. When PCRE +reaches such a point in the regex, if pcre_callout has been set, the external +function is called. It is provided with data in a structure called +pcre_callout_block, which is defined in pcre.h. If the function returns 0, +matching continues; if it returns a non-zero value, the match at the current +point fails. However, backtracking will occur if possible. [This was changed +later and other features added - see item 49 below.] + +29. pcretest is upgraded to test the callout functionality. It provides a +callout function that displays information. By default, it shows the start of +the match and the current position in the text. There are some new data escapes +to vary what happens: + + \C+ in addition, show current contents of captured substrings + \C- do not supply a callout function + \C!n return 1 when callout number n is reached + \C!n!m return 1 when callout number n is reached for the mth time + +30. If pcregrep was called with the -l option and just a single file name, it +output "" if a match was found, instead of the file name. + +31. Improve the efficiency of the POSIX API to PCRE. If the number of capturing +slots is less than POSIX_MALLOC_THRESHOLD, use a block on the stack to pass to +pcre_exec(). This saves a malloc/free per call. The default value of +POSIX_MALLOC_THRESHOLD is 10; it can be changed by --with-posix-malloc-threshold +when configuring. + +32. The default maximum size of a compiled pattern is 64K. There have been a +few cases of people hitting this limit. The code now uses macros to handle the +storing of links as offsets within the compiled pattern. It defaults to 2-byte +links, but this can be changed to 3 or 4 bytes by --with-link-size when +configuring. Tests 2 and 5 work only with 2-byte links because they output +debugging information about compiled patterns. + +33. Internal code re-arrangements: + +(a) Moved the debugging function for printing out a compiled regex into + its own source file (printint.c) and used #include to pull it into + pcretest.c and, when DEBUG is defined, into pcre.c, instead of having two + separate copies. + +(b) Defined the list of op-code names for debugging as a macro in + internal.h so that it is next to the definition of the opcodes. + +(c) Defined a table of op-code lengths for simpler skipping along compiled + code. This is again a macro in internal.h so that it is next to the + definition of the opcodes. + +34. Added support for recursive calls to individual subpatterns, along the +lines of Robin Houston's patch (but implemented somewhat differently). + +35. Further mods to the Makefile to help Win32. Also, added code to pcregrep to +allow it to read and process whole directories in Win32. This code was +contributed by Lionel Fourquaux; it has not been tested by me. + +36. Added support for named subpatterns. The Python syntax (?P...) is +used to name a group. Names consist of alphanumerics and underscores, and must +be unique. Back references use the syntax (?P=name) and recursive calls use +(?P>name) which is a PCRE extension to the Python extension. Groups still have +numbers. The function pcre_fullinfo() can be used after compilation to extract +a name/number map. There are three relevant calls: + + PCRE_INFO_NAMEENTRYSIZE yields the size of each entry in the map + PCRE_INFO_NAMECOUNT yields the number of entries + PCRE_INFO_NAMETABLE yields a pointer to the map. + +The map is a vector of fixed-size entries. The size of each entry depends on +the length of the longest name used. The first two bytes of each entry are the +group number, most significant byte first. There follows the corresponding +name, zero terminated. The names are in alphabetical order. + +37. Make the maximum literal string in the compiled code 250 for the non-UTF-8 +case instead of 255. Making it the same both with and without UTF-8 support +means that the same test output works with both. + +38. There was a case of malloc(0) in the POSIX testing code in pcretest. Avoid +calling malloc() with a zero argument. + +39. Change 25 above had to resort to a heavy-handed test for the .* anchoring +optimization. I've improved things by keeping a bitmap of backreferences with +numbers 1-31 so that if .* occurs inside capturing brackets that are not in +fact referenced, the optimization can be applied. It is unlikely that a +relevant occurrence of .* (i.e. one which might indicate anchoring or forcing +the match to follow \n) will appear inside brackets with a number greater than +31, but if it does, any back reference > 31 suppresses the optimization. + +40. Added a new compile-time option PCRE_NO_AUTO_CAPTURE. This has the effect +of disabling numbered capturing parentheses. 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 will acquire numbers in the usual +way). + +41. Redesigned the return codes from the match() function into yes/no/error so +that errors can be passed back from deep inside the nested calls. A malloc +failure while inside a recursive subpattern call now causes the +PCRE_ERROR_NOMEMORY return instead of quietly going wrong. + +42. It is now possible to set a limit on the number of times the match() +function is called in a call to pcre_exec(). This facility makes it possible to +limit the amount of recursion and backtracking, though not in a directly +obvious way, because the match() function is used in a number of different +circumstances. The count starts from zero for each position in the subject +string (for non-anchored patterns). The default limit is, for compatibility, a +large number, namely 10 000 000. You can change this in two ways: + +(a) When configuring PCRE before making, you can use --with-match-limit=n + to set a default value for the compiled library. + +(b) For each call to pcre_exec(), you can pass a pcre_extra block in which + a different value is set. See 45 below. + +If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT. + +43. Added a new function pcre_config(int, void *) to enable run-time extraction +of things that can be changed at compile time. The first argument specifies +what is wanted and the second points to where the information is to be placed. +The current list of available information is: + + 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. + + PCRE_CONFIG_NEWLINE + +The output is an integer that it set to the value of the code that is used for +newline. It is either LF (10) or CR (13). + + PCRE_CONFIG_LINK_SIZE + +The output is an integer that contains the number of bytes used for internal +linkage in compiled expressions. The value is 2, 3, or 4. See item 32 above. + + PCRE_CONFIG_POSIX_MALLOC_THRESHOLD + +The output is an integer that contains the threshold above which the POSIX +interface uses malloc() for output vectors. See item 31 above. + + PCRE_CONFIG_MATCH_LIMIT + +The output is an unsigned integer that contains the default limit of the number +of match() calls in a pcre_exec() execution. See 42 above. + +44. pcretest has been upgraded by the addition of the -C option. This causes it +to extract all the available output from the new pcre_config() function, and to +output it. The program then exits immediately. + +45. A need has arisen to pass over additional data with calls to pcre_exec() in +order to support additional features. One way would have been to define +pcre_exec2() (for example) with extra arguments, but this would not have been +extensible, and would also have required all calls to the original function to +be mapped to the new one. Instead, I have chosen to extend the mechanism that +is used for passing in "extra" data from pcre_study(). + +The pcre_extra structure is now exposed and defined in pcre.h. It currently +contains the following fields: + + flags a bitmap indicating which of the following fields are set + study_data opaque data from pcre_study() + match_limit a way of specifying a limit on match() calls for a specific + call to pcre_exec() + callout_data data for callouts (see 49 below) + +The flag bits are also defined in pcre.h, and are + + PCRE_EXTRA_STUDY_DATA + PCRE_EXTRA_MATCH_LIMIT + PCRE_EXTRA_CALLOUT_DATA + +The pcre_study() function now returns one of these new pcre_extra blocks, with +the actual study data pointed to by the study_data field, and the +PCRE_EXTRA_STUDY_DATA flag set. This can be passed directly to pcre_exec() as +before. That is, this change is entirely upwards-compatible and requires no +change to existing code. + +If you want to pass in additional data to pcre_exec(), you can either place it +in a pcre_extra block provided by pcre_study(), or create your own pcre_extra +block. + +46. pcretest has been extended to test the PCRE_EXTRA_MATCH_LIMIT feature. If a +data string contains the escape sequence \M, pcretest calls pcre_exec() several +times with different match limits, until it finds the minimum value needed for +pcre_exec() to complete. The value is then output. This can be instructive; for +most simple matches the number is quite small, but for pathological cases it +gets very large very quickly. + +47. There's a new option for pcre_fullinfo() called PCRE_INFO_STUDYSIZE. It +returns the size of the data block pointed to by the study_data field in a +pcre_extra block, that is, the value that was passed as the argument to +pcre_malloc() when PCRE was getting memory in which to place the information +created by pcre_study(). The fourth argument should point to a size_t variable. +pcretest has been extended so that this information is shown after a successful +pcre_study() call when information about the compiled regex is being displayed. + +48. Cosmetic change to Makefile: there's no need to have / after $(DESTDIR) +because what follows is always an absolute path. (Later: it turns out that this +is more than cosmetic for MinGW, because it doesn't like empty path +components.) + +49. Some changes have been made to the callout feature (see 28 above): + +(i) A callout function now has three choices for what it returns: + + 0 => success, carry on matching + > 0 => failure at this point, but backtrack if possible + < 0 => serious error, return this value from pcre_exec() + + Negative values should normally be chosen from the set of PCRE_ERROR_xxx + values. In particular, returning PCRE_ERROR_NOMATCH forces a standard + "match failed" error. The error number PCRE_ERROR_CALLOUT is reserved for + use by callout functions. It will never be used by PCRE itself. + +(ii) The pcre_extra structure (see 45 above) has a void * field called + callout_data, with corresponding flag bit PCRE_EXTRA_CALLOUT_DATA. The + pcre_callout_block structure has a field of the same name. The contents of + the field passed in the pcre_extra structure are passed to the callout + function in the corresponding field in the callout block. This makes it + easier to use the same callout-containing regex from multiple threads. For + testing, the pcretest program has a new data escape + + \C*n pass the number n (may be negative) as callout_data + + If the callout function in pcretest receives a non-zero value as + callout_data, it returns that value. + +50. Makefile wasn't handling CFLAGS properly when compiling dftables. Also, +there were some redundant $(CFLAGS) in commands that are now specified as +$(LINK), which already includes $(CFLAGS). + +51. Extensions to UTF-8 support are listed below. These all apply when (a) PCRE +has been compiled with UTF-8 support *and* pcre_compile() has been compiled +with the PCRE_UTF8 flag. Patterns that are compiled without that flag assume +one-byte characters throughout. Note that case-insensitive matching applies +only to characters whose values are less than 256. PCRE doesn't support the +notion of cases for higher-valued characters. + +(i) A character class whose characters are all within 0-255 is handled as + a bit map, and the map is inverted for negative classes. Previously, a + character > 255 always failed to match such a class; however it should + match if the class was a negative one (e.g. [^ab]). This has been fixed. + +(ii) A negated character class with a single character < 255 is coded as + "not this character" (OP_NOT). This wasn't working properly when the test + character was multibyte, either singly or repeated. + +(iii) Repeats of multibyte characters are now handled correctly in UTF-8 + mode, for example: \x{100}{2,3}. + +(iv) The character escapes \b, \B, \d, \D, \s, \S, \w, and \W (either + singly or repeated) now correctly test multibyte characters. However, + PCRE doesn't recognize any characters with values greater than 255 as + digits, spaces, or word characters. Such characters always match \D, \S, + and \W, and never match \d, \s, or \w. + +(v) Classes may now contain characters and character ranges with values + greater than 255. For example: [ab\x{100}-\x{400}]. + +(vi) pcregrep now has a --utf-8 option (synonym -u) which makes it call + PCRE in UTF-8 mode. + +52. The info request value PCRE_INFO_FIRSTCHAR has been renamed +PCRE_INFO_FIRSTBYTE because it is a byte value. However, the old name is +retained for backwards compatibility. (Note that LASTLITERAL is also a byte +value.) + +53. The single man page has become too large. I have therefore split it up into +a number of separate man pages. These also give rise to individual HTML pages; +these are now put in a separate directory, and there is an index.html page that +lists them all. Some hyperlinking between the pages has been installed. + +54. Added convenience functions for handling named capturing parentheses. + +55. Unknown escapes inside character classes (e.g. [\M]) and escapes that +aren't interpreted therein (e.g. [\C]) are literals in Perl. This is now also +true in PCRE, except when the PCRE_EXTENDED option is set, in which case they +are faulted. + +56. Introduced HOST_CC and HOST_CFLAGS which can be set in the environment when +calling configure. These values are used when compiling the dftables.c program +which is run to generate the source of the default character tables. They +default to the values of CC and CFLAGS. If you are cross-compiling PCRE, +you will need to set these values. + +57. Updated the building process for Windows DLL, as provided by Fred Cox. + + +Version 3.9 02-Jan-02 +--------------------- + +1. A bit of extraneous text had somehow crept into the pcregrep documentation. + +2. If --disable-static was given, the building process failed when trying to +build pcretest and pcregrep. (For some reason it was using libtool to compile +them, which is not right, as they aren't part of the library.) + + +Version 3.8 18-Dec-01 +--------------------- + +1. The experimental UTF-8 code was completely screwed up. It was packing the +bytes in the wrong order. How dumb can you get? + + +Version 3.7 29-Oct-01 +--------------------- + +1. In updating pcretest to check change 1 of version 3.6, I screwed up. +This caused pcretest, when used on the test data, to segfault. Unfortunately, +this didn't happen under Solaris 8, where I normally test things. + +2. The Makefile had to be changed to make it work on BSD systems, where 'make' +doesn't seem to recognize that ./xxx and xxx are the same file. (This entry +isn't in ChangeLog distributed with 3.7 because I forgot when I hastily made +this fix an hour or so after the initial 3.7 release.) + + +Version 3.6 23-Oct-01 +--------------------- + +1. Crashed with /(sens|respons)e and \1ibility/ and "sense and sensibility" if +offsets passed as NULL with zero offset count. + +2. The config.guess and config.sub files had not been updated when I moved to +the latest autoconf. + + +Version 3.5 15-Aug-01 +--------------------- + +1. Added some missing #if !defined NOPOSIX conditionals in pcretest.c that +had been forgotten. + +2. By using declared but undefined structures, we can avoid using "void" +definitions in pcre.h while keeping the internal definitions of the structures +private. + +3. The distribution is now built using autoconf 2.50 and libtool 1.4. From a +user point of view, this means that both static and shared libraries are built +by default, but this can be individually controlled. More of the work of +handling this static/shared cases is now inside libtool instead of PCRE's make +file. + +4. The pcretest utility is now installed along with pcregrep because it is +useful for users (to test regexs) and by doing this, it automatically gets +relinked by libtool. The documentation has been turned into a man page, so +there are now .1, .txt, and .html versions in /doc. + +5. Upgrades to pcregrep: + (i) Added long-form option names like gnu grep. + (ii) Added --help to list all options with an explanatory phrase. + (iii) Added -r, --recursive to recurse into sub-directories. + (iv) Added -f, --file to read patterns from a file. + +6. pcre_exec() was referring to its "code" argument before testing that +argument for NULL (and giving an error if it was NULL). + +7. Upgraded Makefile.in to allow for compiling in a different directory from +the source directory. + +8. Tiny buglet in pcretest: when pcre_fullinfo() was called to retrieve the +options bits, the pointer it was passed was to an int instead of to an unsigned +long int. This mattered only on 64-bit systems. + +9. Fixed typo (3.4/1) in pcre.h again. Sigh. I had changed pcre.h (which is +generated) instead of pcre.in, which it its source. Also made the same change +in several of the .c files. + +10. A new release of gcc defines printf() as a macro, which broke pcretest +because it had an ifdef in the middle of a string argument for printf(). Fixed +by using separate calls to printf(). + +11. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure +script, to force use of CR or LF instead of \n in the source. On non-Unix +systems, the value can be set in config.h. + +12. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an +absolute limit. Changed the text of the error message to make this clear, and +likewise updated the man page. + +13. The limit of 99 on the number of capturing subpatterns has been removed. +The new limit is 65535, which I hope will not be a "real" limit. + + +Version 3.4 22-Aug-00 +--------------------- + +1. Fixed typo in pcre.h: unsigned const char * changed to const unsigned char *. + +2. Diagnose condition (?(0) as an error instead of crashing on matching. + + +Version 3.3 01-Aug-00 +--------------------- + +1. If an octal character was given, but the value was greater than \377, it +was not getting masked to the least significant bits, as documented. This could +lead to crashes in some systems. + +2. Perl 5.6 (if not earlier versions) accepts classes like [a-\d] and treats +the hyphen as a literal. PCRE used to give an error; it now behaves like Perl. + +3. Added the functions pcre_free_substring() and pcre_free_substring_list(). +These just pass their arguments on to (pcre_free)(), but they are provided +because some uses of PCRE bind it to non-C systems that can call its functions, +but cannot call free() or pcre_free() directly. + +4. Add "make test" as a synonym for "make check". Corrected some comments in +the Makefile. + +5. Add $(DESTDIR)/ in front of all the paths in the "install" target in the +Makefile. + +6. Changed the name of pgrep to pcregrep, because Solaris has introduced a +command called pgrep for grepping around the active processes. + +7. Added the beginnings of support for UTF-8 character strings. + +8. Arranged for the Makefile to pass over the settings of CC, CFLAGS, and +RANLIB to ./ltconfig so that they are used by libtool. I think these are all +the relevant ones. (AR is not passed because ./ltconfig does its own figuring +out for the ar command.) + + +Version 3.2 12-May-00 +--------------------- + +This is purely a bug fixing release. + +1. If the pattern /((Z)+|A)*/ was matched agained ZABCDEFG it matched Z instead +of ZA. This was just one example of several cases that could provoke this bug, +which was introduced by change 9 of version 2.00. The code for breaking +infinite loops after an iteration that matches an empty string was't working +correctly. + +2. The pcretest program was not imitating Perl correctly for the pattern /a*/g +when matched against abbab (for example). After matching an empty string, it +wasn't forcing anchoring when setting PCRE_NOTEMPTY for the next attempt; this +caused it to match further down the string than it should. + +3. The code contained an inclusion of sys/types.h. It isn't clear why this +was there because it doesn't seem to be needed, and it causes trouble on some +systems, as it is not a Standard C header. It has been removed. + +4. Made 4 silly changes to the source to avoid stupid compiler warnings that +were reported on the Macintosh. The changes were from + + while ((c = *(++ptr)) != 0 && c != '\n'); +to + while ((c = *(++ptr)) != 0 && c != '\n') ; + +Totally extraordinary, but if that's what it takes... + +5. PCRE is being used in one environment where neither memmove() nor bcopy() is +available. Added HAVE_BCOPY and an autoconf test for it; if neither +HAVE_MEMMOVE nor HAVE_BCOPY is set, use a built-in emulation function which +assumes the way PCRE uses memmove() (always moving upwards). + +6. PCRE is being used in one environment where strchr() is not available. There +was only one use in pcre.c, and writing it out to avoid strchr() probably gives +faster code anyway. + + +Version 3.1 09-Feb-00 +--------------------- + +The only change in this release is the fixing of some bugs in Makefile.in for +the "install" target: + +(1) It was failing to install pcreposix.h. + +(2) It was overwriting the pcre.3 man page with the pcreposix.3 man page. + + +Version 3.0 01-Feb-00 +--------------------- + +1. Add support for the /+ modifier to perltest (to output $` like it does in +pcretest). + +2. Add support for the /g modifier to perltest. + +3. Fix pcretest so that it behaves even more like Perl for /g when the pattern +matches null strings. + +4. Fix perltest so that it doesn't do unwanted things when fed an empty +pattern. Perl treats empty patterns specially - it reuses the most recent +pattern, which is not what we want. Replace // by /(?#)/ in order to avoid this +effect. + +5. The POSIX interface was broken in that it was just handing over the POSIX +captured string vector to pcre_exec(), but (since release 2.00) PCRE has +required a bigger vector, with some working space on the end. This means that +the POSIX wrapper now has to get and free some memory, and copy the results. + +6. Added some simple autoconf support, placing the test data and the +documentation in separate directories, re-organizing some of the +information files, and making it build pcre-config (a GNU standard). Also added +libtool support for building PCRE as a shared library, which is now the +default. + +7. Got rid of the leading zero in the definition of PCRE_MINOR because 08 and +09 are not valid octal constants. Single digits will be used for minor values +less than 10. + +8. Defined REG_EXTENDED and REG_NOSUB as zero in the POSIX header, so that +existing programs that set these in the POSIX interface can use PCRE without +modification. + +9. Added a new function, pcre_fullinfo() with an extensible interface. It can +return all that pcre_info() returns, plus additional data. The pcre_info() +function is retained for compatibility, but is considered to be obsolete. + +10. Added experimental recursion feature (?R) to handle one common case that +Perl 5.6 will be able to do with (?p{...}). + +11. Added support for POSIX character classes like [:alpha:], which Perl is +adopting. + + +Version 2.08 31-Aug-99 +---------------------- + +1. When startoffset was not zero and the pattern began with ".*", PCRE was not +trying to match at the startoffset position, but instead was moving forward to +the next newline as if a previous match had failed. + +2. pcretest was not making use of PCRE_NOTEMPTY when repeating for /g and /G, +and could get into a loop if a null string was matched other than at the start +of the subject. + +3. Added definitions of PCRE_MAJOR and PCRE_MINOR to pcre.h so the version can +be distinguished at compile time, and for completeness also added PCRE_DATE. + +5. Added Paul Sokolovsky's minor changes to make it easy to compile a Win32 DLL +in GnuWin32 environments. + + +Version 2.07 29-Jul-99 +---------------------- + +1. The documentation is now supplied in plain text form and HTML as well as in +the form of man page sources. + +2. C++ compilers don't like assigning (void *) values to other pointer types. +In particular this affects malloc(). Although there is no problem in Standard +C, I've put in casts to keep C++ compilers happy. + +3. Typo on pcretest.c; a cast of (unsigned char *) in the POSIX regexec() call +should be (const char *). + +4. If NOPOSIX is defined, pcretest.c compiles without POSIX support. This may +be useful for non-Unix systems who don't want to bother with the POSIX stuff. +However, I haven't made this a standard facility. The documentation doesn't +mention it, and the Makefile doesn't support it. + +5. The Makefile now contains an "install" target, with editable destinations at +the top of the file. The pcretest program is not installed. + +6. pgrep -V now gives the PCRE version number and date. + +7. Fixed bug: a zero repetition after a literal string (e.g. /abcde{0}/) was +causing the entire string to be ignored, instead of just the last character. + +8. If a pattern like /"([^\\"]+|\\.)*"/ is applied in the normal way to a +non-matching string, it can take a very, very long time, even for strings of +quite modest length, because of the nested recursion. PCRE now does better in +some of these cases. It does this by remembering the last required literal +character in the pattern, and pre-searching the subject to ensure it is present +before running the real match. In other words, it applies a heuristic to detect +some types of certain failure quickly, and in the above example, if presented +with a string that has no trailing " it gives "no match" very quickly. + +9. A new runtime option PCRE_NOTEMPTY causes null string matches to be ignored; +other alternatives are tried instead. + + +Version 2.06 09-Jun-99 +---------------------- + +1. Change pcretest's output for amount of store used to show just the code +space, because the remainder (the data block) varies in size between 32-bit and +64-bit systems. + +2. Added an extra argument to pcre_exec() to supply an offset in the subject to +start matching at. This allows lookbehinds to work when searching for multiple +occurrences in a string. + +3. Added additional options to pcretest for testing multiple occurrences: + + /+ outputs the rest of the string that follows a match + /g loops for multiple occurrences, using the new startoffset argument + /G loops for multiple occurrences by passing an incremented pointer + +4. PCRE wasn't doing the "first character" optimization for patterns starting +with \b or \B, though it was doing it for other lookbehind assertions. That is, +it wasn't noticing that a match for a pattern such as /\bxyz/ has to start with +the letter 'x'. On long subject strings, this gives a significant speed-up. + + +Version 2.05 21-Apr-99 +---------------------- + +1. Changed the type of magic_number from int to long int so that it works +properly on 16-bit systems. + +2. Fixed a bug which caused patterns starting with .* not to work correctly +when the subject string contained newline characters. PCRE was assuming +anchoring for such patterns in all cases, which is not correct because .* will +not pass a newline unless PCRE_DOTALL is set. It now assumes anchoring only if +DOTALL is set at top level; otherwise it knows that patterns starting with .* +must be retried after every newline in the subject. + + +Version 2.04 18-Feb-99 +---------------------- + +1. For parenthesized subpatterns with repeats whose minimum was zero, the +computation of the store needed to hold the pattern was incorrect (too large). +If such patterns were nested a few deep, this could multiply and become a real +problem. + +2. Added /M option to pcretest to show the memory requirement of a specific +pattern. Made -m a synonym of -s (which does this globally) for compatibility. + +3. Subpatterns of the form (regex){n,m} (i.e. limited maximum) were being +compiled in such a way that the backtracking after subsequent failure was +pessimal. Something like (a){0,3} was compiled as (a)?(a)?(a)? instead of +((a)((a)(a)?)?)? with disastrous performance if the maximum was of any size. + + +Version 2.03 02-Feb-99 +---------------------- + +1. Fixed typo and small mistake in man page. + +2. Added 4th condition (GPL supersedes if conflict) and created separate +LICENCE file containing the conditions. + +3. Updated pcretest so that patterns such as /abc\/def/ work like they do in +Perl, that is the internal \ allows the delimiter to be included in the +pattern. Locked out the use of \ as a delimiter. If \ immediately follows +the final delimiter, add \ to the end of the pattern (to test the error). + +4. Added the convenience functions for extracting substrings after a successful +match. Updated pcretest to make it able to test these functions. + + +Version 2.02 14-Jan-99 +---------------------- + +1. Initialized the working variables associated with each extraction so that +their saving and restoring doesn't refer to uninitialized store. + +2. Put dummy code into study.c in order to trick the optimizer of the IBM C +compiler for OS/2 into generating correct code. Apparently IBM isn't going to +fix the problem. + +3. Pcretest: the timing code wasn't using LOOPREPEAT for timing execution +calls, and wasn't printing the correct value for compiling calls. Increased the +default value of LOOPREPEAT, and the number of significant figures in the +times. + +4. Changed "/bin/rm" in the Makefile to "-rm" so it works on Windows NT. + +5. Renamed "deftables" as "dftables" to get it down to 8 characters, to avoid +a building problem on Windows NT with a FAT file system. + + +Version 2.01 21-Oct-98 +---------------------- + +1. Changed the API for pcre_compile() to allow for the provision of a pointer +to character tables built by pcre_maketables() in the current locale. If NULL +is passed, the default tables are used. + + +Version 2.00 24-Sep-98 +---------------------- + +1. Since the (>?) facility is in Perl 5.005, don't require PCRE_EXTRA to enable +it any more. + +2. Allow quantification of (?>) groups, and make it work correctly. + +3. The first character computation wasn't working for (?>) groups. + +4. Correct the implementation of \Z (it is permitted to match on the \n at the +end of the subject) and add 5.005's \z, which really does match only at the +very end of the subject. + +5. Remove the \X "cut" facility; Perl doesn't have it, and (?> is neater. + +6. Remove the ability to specify CASELESS, MULTILINE, DOTALL, and +DOLLAR_END_ONLY at runtime, to make it possible to implement the Perl 5.005 +localized options. All options to pcre_study() were also removed. + +7. Add other new features from 5.005: + + $(?<= positive lookbehind + $(?a*))*/ (a PCRE_EXTRA facility). + + +Version 1.00 18-Nov-97 +---------------------- + +1. Added compile-time macros to support systems such as SunOS4 which don't have +memmove() or strerror() but have other things that can be used instead. + +2. Arranged that "make clean" removes the executables. + + +Version 0.99 27-Oct-97 +---------------------- + +1. Fixed bug in code for optimizing classes with only one character. It was +initializing a 32-byte map regardless, which could cause it to run off the end +of the memory it had got. + +2. Added, conditional on PCRE_EXTRA, the proposed (?>REGEX) construction. + + +Version 0.98 22-Oct-97 +---------------------- + +1. Fixed bug in code for handling temporary memory usage when there are more +back references than supplied space in the ovector. This could cause segfaults. + + +Version 0.97 21-Oct-97 +---------------------- + +1. Added the \X "cut" facility, conditional on PCRE_EXTRA. + +2. Optimized negated single characters not to use a bit map. + +3. Brought error texts together as macro definitions; clarified some of them; +fixed one that was wrong - it said "range out of order" when it meant "invalid +escape sequence". + +4. Changed some char * arguments to const char *. + +5. Added PCRE_NOTBOL and PCRE_NOTEOL (from POSIX). + +6. Added the POSIX-style API wrapper in pcreposix.a and testing facilities in +pcretest. + + +Version 0.96 16-Oct-97 +---------------------- + +1. Added a simple "pgrep" utility to the distribution. + +2. Fixed an incompatibility with Perl: "{" is now treated as a normal character +unless it appears in one of the precise forms "{ddd}", "{ddd,}", or "{ddd,ddd}" +where "ddd" means "one or more decimal digits". + +3. Fixed serious bug. If a pattern had a back reference, but the call to +pcre_exec() didn't supply a large enough ovector to record the related +identifying subpattern, the match always failed. PCRE now remembers the number +of the largest back reference, and gets some temporary memory in which to save +the offsets during matching if necessary, in order to ensure that +backreferences always work. + +4. Increased the compatibility with Perl in a number of ways: + + (a) . no longer matches \n by default; an option PCRE_DOTALL is provided + to request this handling. The option can be set at compile or exec time. + + (b) $ matches before a terminating newline by default; an option + PCRE_DOLLAR_ENDONLY is provided to override this (but not in multiline + mode). The option can be set at compile or exec time. + + (c) The handling of \ followed by a digit other than 0 is now supposed to be + the same as Perl's. If the decimal number it represents is less than 10 + or there aren't that many previous left capturing parentheses, an octal + escape is read. Inside a character class, it's always an octal escape, + even if it is a single digit. + + (d) An escaped but undefined alphabetic character is taken as a literal, + unless PCRE_EXTRA is set. Currently this just reserves the remaining + escapes. + + (e) {0} is now permitted. (The previous item is removed from the compiled + pattern). + +5. Changed all the names of code files so that the basic parts are no longer +than 10 characters, and abolished the teeny "globals.c" file. + +6. Changed the handling of character classes; they are now done with a 32-byte +bit map always. + +7. Added the -d and /D options to pcretest to make it possible to look at the +internals of compilation without having to recompile pcre. + + +Version 0.95 23-Sep-97 +---------------------- + +1. Fixed bug in pre-pass concerning escaped "normal" characters such as \x5c or +\x20 at the start of a run of normal characters. These were being treated as +real characters, instead of the source characters being re-checked. + + +Version 0.94 18-Sep-97 +---------------------- + +1. The functions are now thread-safe, with the caveat that the global variables +containing pointers to malloc() and free() or alternative functions are the +same for all threads. + +2. Get pcre_study() to generate a bitmap of initial characters for non- +anchored patterns when this is possible, and use it if passed to pcre_exec(). + + +Version 0.93 15-Sep-97 +---------------------- + +1. /(b)|(:+)/ was computing an incorrect first character. + +2. Add pcre_study() to the API and the passing of pcre_extra to pcre_exec(), +but not actually doing anything yet. + +3. Treat "-" characters in classes that cannot be part of ranges as literals, +as Perl does (e.g. [-az] or [az-]). + +4. Set the anchored flag if a branch starts with .* or .*? because that tests +all possible positions. + +5. Split up into different modules to avoid including unneeded functions in a +compiled binary. However, compile and exec are still in one module. The "study" +function is split off. + +6. The character tables are now in a separate module whose source is generated +by an auxiliary program - but can then be edited by hand if required. There are +now no calls to isalnum(), isspace(), isdigit(), isxdigit(), tolower() or +toupper() in the code. + +7. Turn the malloc/free funtions variables into pcre_malloc and pcre_free and +make them global. Abolish the function for setting them, as the caller can now +set them directly. + + +Version 0.92 11-Sep-97 +---------------------- + +1. A repeat with a fixed maximum and a minimum of 1 for an ordinary character +(e.g. /a{1,3}/) was broken (I mis-optimized it). + +2. Caseless matching was not working in character classes if the characters in +the pattern were in upper case. + +3. Make ranges like [W-c] work in the same way as Perl for caseless matching. + +4. Make PCRE_ANCHORED public and accept as a compile option. + +5. Add an options word to pcre_exec() and accept PCRE_ANCHORED and +PCRE_CASELESS at run time. Add escapes \A and \I to pcretest to cause it to +pass them. + +6. Give an error if bad option bits passed at compile or run time. + +7. Add PCRE_MULTILINE at compile and exec time, and (?m) as well. Add \M to +pcretest to cause it to pass that flag. + +8. Add pcre_info(), to get the number of identifying subpatterns, the stored +options, and the first character, if set. + +9. Recognize C+ or C{n,m} where n >= 1 as providing a fixed starting character. + + +Version 0.91 10-Sep-97 +---------------------- + +1. PCRE was failing to diagnose unlimited repeats of subpatterns that could +match the empty string as in /(a*)*/. It was looping and ultimately crashing. + +2. PCRE was looping on encountering an indefinitely repeated back reference to +a subpattern that had matched an empty string, e.g. /(a|)\1*/. It now does what +Perl does - treats the match as successful. + +**** diff --git a/tools/pcre/CheckMan b/tools/pcre/CheckMan new file mode 100644 index 00000000..de013347 --- /dev/null +++ b/tools/pcre/CheckMan @@ -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 --git a/tools/pcre/CleanTxt b/tools/pcre/CleanTxt new file mode 100644 index 00000000..1f42519c --- /dev/null +++ b/tools/pcre/CleanTxt @@ -0,0 +1,113 @@ +#! /usr/bin/perl -w + +# Script to take the output of nroff -man and remove all the backspacing and +# the page footers and the screen commands etc so that it is more usefully +# readable online. In fact, in the latest nroff, intermediate footers don't +# seem to be generated any more. + +$blankcount = 0; +$lastwascut = 0; +$firstheader = 1; + +# Input on STDIN; output to STDOUT. + +while () + { + s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m" + s/.\x8//g; # Remove "char, backspace" + + # Handle header lines. Retain only the first one we encounter, but remove + # the blank line that follows. Any others (e.g. at end of document) and the + # following blank line are dropped. + + if (/^PCRE(\w*)\(([13])\)\s+PCRE\1\(\2\)$/) + { + if ($firstheader) + { + $firstheader = 0; + print; + $lastprinted = $_; + $lastwascut = 0; + } + $_=; # Remove a blank that follows + next; + } + + # Count runs of empty lines + + if (/^\s*$/) + { + $blankcount++; + $lastwascut = 0; + next; + } + + # If a chunk of lines has been cut out (page footer) and the next line + # has a different indentation, put back one blank line. + + if ($lastwascut && $blankcount < 1 && defined($lastprinted)) + { + ($a) = $lastprinted =~ /^(\s*)/; + ($b) = $_ =~ /^(\s*)/; + $blankcount++ if ($a ne $b); + } + + # We get here only when we have a non-blank line in hand. If it was preceded + # by 3 or more blank lines, read the next 3 lines and see if they are blank. + # If so, remove all 7 lines, and remember that we have just done a cut. + + if ($blankcount >= 3) + { + for ($i = 0; $i < 3; $i++) + { + $next[$i] = ; + $next[$i] = "" if !defined $next[$i]; + $next[$i] =~ s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m" + $next[$i] =~ s/.\x8//g; # Remove "char, backspace" + } + + # Cut out chunks of the form <3 blanks><3 blanks> + + if ($next[0] =~ /^\s*$/ && + $next[1] =~ /^\s*$/ && + $next[2] =~ /^\s*$/) + { + $blankcount -= 3; + $lastwascut = 1; + } + + # Otherwise output the saved blanks, the current, and the next three + # lines. Remember the last printed line. + + else + { + for ($i = 0; $i < $blankcount; $i++) { print "\n"; } + print; + for ($i = 0; $i < 3; $i++) + { + $next[$i] =~ s/.\x8//g; + print $next[$i]; + $lastprinted = $_; + } + $lastwascut = 0; + $blankcount = 0; + } + } + + # This non-blank line is not preceded by 3 or more blank lines. Output + # any blanks there are, and the line. Remember it. Force two blank lines + # before headings. + + else + { + $blankcount = 2 if /^\S/ && !/^Last updated/ && !/^Copyright/ && + defined($lastprinted); + for ($i = 0; $i < $blankcount; $i++) { print "\n"; } + print; + $lastprinted = $_; + $lastwascut = 0; + $blankcount = 0; + } + } + +# End diff --git a/tools/pcre/Detrail b/tools/pcre/Detrail new file mode 100644 index 00000000..1c5c7e9c --- /dev/null +++ b/tools/pcre/Detrail @@ -0,0 +1,35 @@ +#!/usr/bin/perl + +# This is a script for removing trailing whitespace from lines in files that +# are listed on the command line. + +# This subroutine does the work for one file. + +sub detrail { +my($file) = $_[0]; +my($changed) = 0; +open(IN, "$file") || die "Can't open $file for input"; +@lines = ; +close(IN); +foreach (@lines) + { + if (/\s+\n$/) + { + s/\s+\n$/\n/; + $changed = 1; + } + } +if ($changed) + { + open(OUT, ">$file") || die "Can't open $file for output"; + print OUT @lines; + close(OUT); + } +} + +# This is the main program + +$, = ""; # Output field separator +for ($i = 0; $i < @ARGV; $i++) { &detrail($ARGV[$i]); } + +# End diff --git a/tools/pcre/HACKING b/tools/pcre/HACKING new file mode 100644 index 00000000..a90ddf87 --- /dev/null +++ b/tools/pcre/HACKING @@ -0,0 +1,473 @@ +Technical Notes about PCRE +-------------------------- + +These are very rough technical notes that record potentially useful information +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 +----------------- + +Many years ago I implemented some regular expression functions to an algorithm +suggested by Martin Richards. These were not Unix-like in form, and were quite +restricted in what they could do by comparison with Perl. The interesting part +about the algorithm was that the amount of space required to hold the compiled +form of an expression was known in advance. The code to apply an expression did +not operate by backtracking, as the original Henry Spencer code and current +Perl code does, but instead checked all possibilities simultaneously by keeping +a list of current states and checking all of them as it advanced through the +subject string. In the terminology of Jeffrey Friedl's book, it was a "DFA +algorithm", though it was not a traditional Finite State Machine (FSM). When +the pattern was all used up, all remaining states were possible matches, and +the one matching the longest subset of the subject string was chosen. This did +not necessarily maximize the individual wild portions of the pattern, as is +expected in Unix and Perl-style regular expressions. + + +Historical note 2 +----------------- + +By contrast, the code originally written by Henry Spencer (which was +subsequently heavily modified for Perl) compiles the expression twice: once in +a dummy mode in order to find out how much store will be needed, and then for +real. (The Perl version probably doesn't do this any more; I'm talking about +the original library.) The execution function operates by backtracking and +maximizing (or, optionally, minimizing in Perl) the amount of the subject that +matches individual wild portions of the pattern. This is an "NFA algorithm" in +Friedl's terminology. + + +OK, here's the real stuff +------------------------- + +For the set of functions that form the "basic" PCRE library (which are +unrelated to those mentioned above), I tried at first to invent an algorithm +that used an amount of store bounded by a multiple of the number of characters +in the pattern, to save on compiling time. However, because of the greater +complexity in Perl regular expressions, I couldn't do this. In any case, a +first pass through the pattern is helpful for other reasons. + + +Support for 16-bit and 32-bit data strings +------------------------------------------- + +From release 8.30, PCRE supports 16-bit as well as 8-bit data strings; and from +release 8.32, PCRE supports 32-bit data strings. The library can be compiled +in any combination of 8-bit, 16-bit or 32-bit modes, creating different +libraries. In the description that follows, the word "short" is +used for a 16-bit data quantity, and the word "unit" is used for a quantity +that is a byte in 8-bit mode, a short in 16-bit mode and a 32-bit unsigned +integer in 32-bit mode. However, so as not to over-complicate the text, the +names of PCRE functions are given in 8-bit form only. + + +Computing the memory requirement: how it was +-------------------------------------------- + +Up to and including release 6.7, PCRE worked by running a very degenerate first +pass to calculate a maximum store size, and then a second pass to do the real +compile - which might use a bit less than the predicted amount of memory. The +idea was that this would turn out faster than the Henry Spencer code because +the first pass is degenerate and the second pass can just store stuff straight +into the vector, which it knows is big enough. + + +Computing the memory requirement: how it is +------------------------------------------- + +By the time I was working on a potential 6.8 release, the degenerate first pass +had become very complicated and hard to maintain. Indeed one of the early +things I did for 6.8 was to fix Yet Another Bug in the memory computation. Then +I had a flash of inspiration as to how I could run the real compile function in +a "fake" mode that enables it to compute how much memory it would need, while +actually only ever using a few hundred bytes of working memory, and without too +many tests of the mode that might slow it down. So I 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 +major changes were also present in the 7.0 release). + +A side effect of this work was that the previous limit of 200 on the nesting +depth of parentheses was removed. However, there is a downside: pcre_compile() +runs more slowly than before (30% or more, depending on the pattern) because it +is doing a full analysis of the pattern. My hope was that this would not be a +big issue, and in the event, nobody has commented on it. + + +Traditional matching function +----------------------------- + +The "traditional", and original, matching function is called pcre_exec(), and +it implements an NFA algorithm, similar to the original Henry Spencer algorithm +and the way that Perl works. This is not surprising, since it is intended to be +as compatible with Perl as possible. This is the function most users of PCRE +will use most of the time. 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 +------------------------------- + +From PCRE 6.0, there is also a supplementary matching function called +pcre_dfa_exec(). This implements a DFA matching algorithm that searches +simultaneously for all possible matches that start at one point in the subject +string. (Going back to my roots: see Historical Note 1 above.) This function +intreprets the same compiled pattern data as pcre_exec(); however, not all the +facilities are available, and those that are do not always work in quite the +same way. See the user documentation for details. + +The algorithm that is used for pcre_dfa_exec() is not a traditional FSM, +because it may have a number of states active at one time. More work would be +needed at compile time to produce a traditional FSM where only one state is +ever active at once. I believe some other regex matchers work this way. + + +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 units (bytes in 8-bit mode, or +shorts in 16-bit mode, 32-bit unsigned integers in 32-bit mode), containing +items of variable length. The first unit in an item contains an opcode, and +the length of the item is either implicit in the opcode or contained in the +data that follows it. + +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 unit long + + OP_END end of pattern + OP_ANY match any one character other than newline + OP_ALLANY match any one character, including newline + OP_ANYBYTE match any single byte, even in UTF-8 mode + OP_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) + OP_CIRCM ^ multiline mode (start of data or after newline) + OP_NOT_WORD_BOUNDARY \W + OP_WORD_BOUNDARY \w + OP_NOT_DIGIT \D + OP_DIGIT \d + OP_NOT_HSPACE \H + OP_HSPACE \h + OP_NOT_WHITESPACE \S + OP_WHITESPACE \s + OP_NOT_VSPACE \V + OP_VSPACE \v + OP_NOT_WORDCHAR \W + 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 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 + + OP_ACCEPT ) These are Perl 5.10's "backtracking control + OP_COMMIT ) verbs". If OP_ACCEPT is inside capturing + OP_FAIL ) parentheses, it may be preceded by one or more + OP_PRUNE ) OP_CLOSE, followed by a 2-byte number, + OP_SKIP ) indicating which parentheses must be closed. + + +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. In UTF-32 mode, characters +are always exactly one unit long. + + +Repeating single characters +--------------------------- + +The common repeats (*, +, ?), when applied to a single character, use the +following opcodes, which come in caseful and caseless versions: + + 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; in +UTF-32 mode these are one-unit items. +Those with "MIN" in their names are the minimizing versions. Those with "POS" +in their names are possessive versions. Other repeats make use of these +opcodes: + + 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 +------------------------- + +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 +unit. The opcodes are: + + OP_TYPESTAR + OP_TYPEMINSTAR + OP_TYPEPOSSTAR + OP_TYPEPLUS + OP_TYPEMINPLUS + OP_TYPEPOSPLUS + OP_TYPEQUERY + OP_TYPEMINQUERY + OP_TYPEPOSQUERY + OP_TYPEUPTO + OP_TYPEMINUPTO + OP_TYPEPOSUPTO + OP_TYPEEXACT + + +Match by Unicode property +------------------------- + +OP_PROP and OP_NOTPROP are used for positive and negative matches of a +character by testing its Unicode property (the \p and \P escape sequences). +Each is followed by two units that encode the desired property as a type and a +value. + +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. + + +Character classes +----------------- + +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/32 mode, +subject characters with values greater than 255 can be handled correctly. For +OP_CLASS they do not match, whereas for OP_NCLASS they do. + +For classes containing characters with values greater than 255, 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 (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[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 + OP_CRPLUS + OP_CRMINPLUS + OP_CRQUERY + OP_CRMINQUERY + OP_CRRANGE + OP_CRMINRANGE + +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 +------------------------ + +A pair of non-capturing (round) brackets is wrapped round each expression at +compile time, so alternation always happens in the context of brackets. + +[Note for North Americans: "bracket" to some English speakers, including +myself, can be round, square, curly, or pointy. Hence this usage 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 +3.5, the limit was removed by putting the bracket number into the data for +higher-numbered brackets. From release 7.0 all capturing brackets are handled +this way, using the single opcode OP_CBRA. + +A bracket opcode is followed by LINK_SIZE bytes which give the offset to the +next alternative OP_ALT or, if there aren't any branches, to the matching +OP_KET opcode. Each OP_ALT is followed by LINK_SIZE bytes giving the offset to +the next one, or to the OP_KET opcode. For capturing brackets, the bracket +number immediately follows the offset, always as a 2-byte (one short) item. + +OP_KET is used for subpatterns that do not repeat indefinitely, and +OP_KETRMIN and OP_KETRMAX are used for indefinite repetitions, minimally or +maximally respectively (see below for possessive repetitions). All three are +followed by LINK_SIZE bytes giving (as a positive number) the offset back to +the matching bracket opcode. + +If a subpattern is quantified such that it is permitted to match zero times, it +is preceded by one of OP_BRAZERO, OP_BRAMINZERO, or OP_SKIPZERO. These are +single-unit opcodes that tell the matcher that skipping the following +subpattern entirely is a valid branch. In the case of the first two, not +skipping the pattern is also valid (greedy and non-greedy). The third is used +when a pattern has the quantifier {0,0}. It cannot be entirely discarded, +because it may be called as a subroutine from elsewhere in the regex. + +A subpattern with an indefinite maximum repetition is replicated in the +compiled data its minimum number of times (or once with OP_BRAZERO if the +minimum is zero), with the final copy terminating with OP_KETRMIN or OP_KETRMAX +as appropriate. + +A subpattern with a bounded maximum repetition is replicated in a nested +fashion up to the maximum number of times, with OP_BRAZERO or OP_BRAMINZERO +before each replication after the minimum, so that, for example, (abc){2,5} is +compiled as (abc)(abc)((abc)((abc)(abc)?)?)?, except that each bracketed group +has the same number. + +When a repeated subpattern has an unbounded upper limit, it is checked to see +whether it could match an empty string. If this is the case, the opcode in the +final replication is changed to OP_SBRA or OP_SCBRA. This tells the matcher +that it needs to check for matching an empty string when it hits OP_KETRMIN or +OP_KETRMAX, and if so, to break the loop. + +Possessive brackets +------------------- + +When a repeated group (capturing or non-capturing) is marked as possessive by +the "+" notation, e.g. (abc)++, different opcodes are used. Their names all +have POS on the end, e.g. OP_BRAPOS instead of OP_BRA and OP_SCPBRPOS instead +of OP_SCBRA. The end of such a group is marked by OP_KETRPOS. If the minimum +repetition is zero, the group is preceded by OP_BRAPOSZERO. + + +Assertions +---------- + +Forward assertions are just like other subpatterns, but starting with one of +the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes +OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion +is OP_REVERSE, followed by a two byte (one short) count of the number of +characters to move back the pointer in the subject string. In ASCII mode, the +count is a number of units, but in UTF-8/16 mode each character may occupy more +than one unit; in UTF-32 mode each character occupies exactly one unit. +A separate count is present in each alternative of a lookbehind +assertion, allowing them to have different fixed lengths. + + +Once-only (atomic) subpatterns +------------------------------ + +These are also just like other subpatterns, but they start with the opcode +OP_ONCE. The check for matching an empty string in an unbounded repeat is +handled entirely at runtime, so there is just this one opcode. + + +Conditional subpatterns +----------------------- + +These are like other subpatterns, but they start with the opcode OP_COND, or +OP_SCOND for one that might match an empty string in an unbounded repeat. If +the condition is a back reference, this is stored at the start of the +subpattern using the opcode OP_CREF followed by two bytes (one short) +containing the reference number. OP_NCREF is used instead if the reference was +generated by name (so that the runtime code knows to check for duplicate +names). + +If the condition is "in recursion" (coded as "(?(R)"), or "in recursion of +group x" (coded as "(?(Rx)"), the group number is stored at the start of the +subpattern using the opcode OP_RREF or OP_NRREF (cf OP_NCREF), and a value of +zero for "the whole pattern". For a DEFINE condition, just the single unit +OP_DEF is used (it has no associated data). Otherwise, a conditional subpattern +always starts with one of the assertions. + + +Recursion +--------- + +Recursion either matches the current regex, or some subexpression. The opcode +OP_RECURSE is followed by an value which is the offset to the starting bracket +from the start of the whole pattern. From release 6.5, OP_RECURSE is +automatically wrapped inside OP_ONCE brackets (because otherwise some patterns +broke it). OP_RECURSE is also used for "subroutine" calls, even though they +are not strictly a recursion. + + +Callout +------- + +OP_CALLOUT is followed by one unit of data that holds a callout number in the +range 0 to 254 for manual callouts, or 255 for an automatic callout. In both +cases there follows a two-byte (one short) value giving the offset in the +pattern to the start of the following item, and another two-byte (one short) +item giving the length of the next item. + + +Philip Hazel +February 2012 diff --git a/tools/pcre/INSTALL b/tools/pcre/INSTALL new file mode 100644 index 00000000..a1e89e18 --- /dev/null +++ b/tools/pcre/INSTALL @@ -0,0 +1,370 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/tools/pcre/LICENCE b/tools/pcre/LICENCE new file mode 100644 index 00000000..5ce31a82 --- /dev/null +++ b/tools/pcre/LICENCE @@ -0,0 +1,92 @@ +PCRE LICENCE +------------ + +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. + +Release 8 of PCRE is distributed under the terms of the "BSD" licence, as +specified below. The documentation for PCRE, supplied in the "doc" +directory, is distributed under the same terms as the software itself. + +The basic library functions are written in C and are freestanding. Also +included in the distribution is a set of C++ wrapper functions, 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 +--------------------------- + +Written by: Philip Hazel +Email local part: ph10 +Email domain: cam.ac.uk + +University of Cambridge Computing Service, +Cambridge, England. + +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 FUNCTIONS +------------------------- + +Contributed by: Google Inc. + +Copyright (c) 2007-2012, Google Inc. +All rights reserved. + + +THE "BSD" LICENCE +----------------- + +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 name of Google + Inc. nor the names of their 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. + +End diff --git a/tools/pcre/Makefile.am b/tools/pcre/Makefile.am new file mode 100644 index 00000000..5d9928a4 --- /dev/null +++ b/tools/pcre/Makefile.am @@ -0,0 +1,877 @@ +## Process this file with automake to produce Makefile.in. + +ACLOCAL_AMFLAGS = -I m4 + +dist_doc_DATA = \ + doc/pcre.txt \ + doc/pcre-config.txt \ + doc/pcregrep.txt \ + doc/pcretest.txt \ + AUTHORS \ + COPYING \ + ChangeLog \ + LICENCE \ + NEWS \ + README + +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 \ + doc/html/pcre_copy_named_substring.html \ + 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 \ + doc/html/pcre_get_named_substring.html \ + doc/html/pcre_get_stringnumber.html \ + doc/html/pcre_get_stringtable_entries.html \ + doc/html/pcre_get_substring.html \ + doc/html/pcre_get_substring_list.html \ + doc/html/pcre_jit_exec.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 \ + doc/html/pcrecallout.html \ + 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 \ + doc/html/pcreperform.html \ + doc/html/pcreposix.html \ + doc/html/pcreprecompile.html \ + doc/html/pcresample.html \ + doc/html/pcrestack.html \ + doc/html/pcresyntax.html \ + doc/html/pcretest.html \ + doc/html/pcreunicode.html + +# doc/html/pcre32.html \ +# doc/html/pcre_utf32_to_host_byte_order.html \ +# + +pcrecpp_html = doc/html/pcrecpp.html +dist_noinst_DATA = $(pcrecpp_html) + +if WITH_PCRE_CPP +html_DATA = $(pcrecpp_html) +endif + +# The Libtool libraries to install. We'll add to this later. +lib_LTLIBRARIES = + +# Unit tests you want to run when people type 'make check'. +# TESTS is for binary unit tests, check_SCRIPTS for script-based tests +TESTS = +check_SCRIPTS = +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, libpcre16 +# or libpcre32. +bin_PROGRAMS = +noinst_PROGRAMS = + +# Additional files to delete on 'make clean' and 'make maintainer-clean'. +CLEANFILES = +MAINTAINERCLEANFILES = + +# Additional files to bundle with the distribution, over and above what +# the Autotools include by default. +EXTRA_DIST = + +# These files contain additional m4 macros that are used by autoconf. +EXTRA_DIST += \ + m4/ax_pthread.m4 m4/pcre_visibility.m4 + +# These files contain maintenance information +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 \ + doc/index.html.src + +# These files are to do with building for Virtual Pascal +EXTRA_DIST += \ + makevp.bat \ + makevp_c.txt \ + makevp_l.txt \ + pcregexp.pas + +# These files are usable versions of pcre.h and config.h that are distributed +# for the benefit of people who are building PCRE manually, without the +# Autotools support. +EXTRA_DIST += \ + pcre.h.generic \ + config.h.generic + +# The only difference between pcre.h.in and pcre.h is the setting of the PCRE +# version number. Therefore, we can create the generic version just by copying. +pcre.h.generic: pcre.h.in configure.ac + rm -f $@ + cp -p pcre.h $@ + +# It is more complicated for config.h.generic. We need the version that results +# from a default configuration. We can get this by doing a configure in a +# temporary directory. However, some trickery is needed, +# because the source directory may already be configured. If you +# just try running configure in a new directory, it complains. For this reason, +# we move config.status out of the way while doing the default configuration. +# The resulting config.h is munged by perl to put #ifdefs round any #defines +# and to get rid of any gcc-specific visibility settings. Make sure that +# PCRE_EXP_DEFN is unset (in case it has visibility settings). +config.h.generic: configure.ac + rm -rf $@ _generic + mkdir _generic + cs=$(srcdir)/config.status; test ! -f $$cs || mv -f $$cs $$cs.aside + cd _generic && $(abs_top_srcdir)/configure || : + cs=$(srcdir)/config.status; test ! -f $$cs.aside || mv -f $$cs.aside $$cs + test -f _generic/config.h + perl -n \ + -e 'BEGIN{$$blank=0;}' \ + -e 'if(/PCRE_EXP_DEFN/){print"/* #undef PCRE_EXP_DEFN */\n";$$blank=0;next;}' \ + -e 'if(/to make a symbol visible/){next;}' \ + -e 'if(/__attribute__ \(\(visibility/){next;}' \ + -e 'if(/^#define\s(?!PACKAGE)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;}' \ + -e 'else {if(/^\s*$$/){print unless $$blank; $$blank=1;} else{print;$$blank=0;}}' \ + _generic/config.h >$@ + rm -rf _generic + +MAINTAINERCLEANFILES += pcre.h.generic config.h.generic + +# These are the header files we'll install. We do not distribute pcre.h because +# it is generated from pcre.h.in. +nodist_include_HEADERS = \ + pcre.h +include_HEADERS = \ + pcreposix.h + +# 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 +# from corresponding .h.in files (which we do distribute). +if WITH_PCRE_CPP +nodist_include_HEADERS += \ + pcrecpparg.h \ + pcre_stringpiece.h +include_HEADERS += \ + pcrecpp.h \ + pcre_scanner.h +endif # WITH_PCRE_CPP + +bin_SCRIPTS = pcre-config + +## --------------------------------------------------------------- +## The dftables program is used to rebuild character tables before compiling +## PCRE, if --enable-rebuild-chartables is specified. It is not a user-visible +## program. The default (when --enable-rebuild-chartables is not specified) is +## to copy a distributed set of tables that are defined for ASCII code. In this +## case, dftables is not needed. + +if WITH_REBUILD_CHARTABLES + +noinst_PROGRAMS += dftables +dftables_SOURCES = dftables.c + +pcre_chartables.c: dftables$(EXEEXT) + ./dftables$(EXEEXT) $@ +else + +pcre_chartables.c: $(srcdir)/pcre_chartables.c.dist + rm -f $@ + $(LN_S) $(srcdir)/pcre_chartables.c.dist $@ + +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 \ + 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 + +libpcre_la_CFLAGS = \ + $(VISIBILITY_CFLAGS) \ + $(AM_CFLAGS) + +libpcre_la_LIBADD = + +## This file is generated as part of the building process, so don't distribute. +nodist_libpcre_la_SOURCES = \ + pcre_chartables.c + +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 + +libpcre16_la_CFLAGS = \ + $(VISIBILITY_CFLAGS) \ + $(AM_CFLAGS) + +libpcre16_la_LIBADD = + +## This file is generated as part of the building process, so don't distribute. +nodist_libpcre16_la_SOURCES = \ + pcre_chartables.c + +endif # WITH_PCRE16 + +# Build the 32 bit library if it is enabled. +if WITH_PCRE32 +lib_LTLIBRARIES += libpcre32.la +libpcre32_la_SOURCES = \ + pcre32_byte_order.c \ + pcre32_chartables.c \ + pcre32_compile.c \ + pcre32_config.c \ + pcre32_dfa_exec.c \ + pcre32_exec.c \ + pcre32_fullinfo.c \ + pcre32_get.c \ + pcre32_globals.c \ + pcre32_jit_compile.c \ + pcre32_maketables.c \ + pcre32_newline.c \ + pcre32_ord2utf32.c \ + pcre32_refcount.c \ + pcre32_string_utils.c \ + pcre32_study.c \ + pcre32_tables.c \ + pcre32_ucd.c \ + pcre32_utf32_utils.c \ + pcre32_valid_utf32.c \ + pcre32_version.c \ + pcre32_xclass.c + +libpcre32_la_CFLAGS = \ + $(VISIBILITY_CFLAGS) \ + $(AM_CFLAGS) + +libpcre32_la_LIBADD = + +## This file is generated as part of the building process, so don't distribute. +nodist_libpcre32_la_SOURCES = \ + pcre_chartables.c + +endif # WITH_PCRE32 + +# 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/sljitNativeSPARC_32.c \ + sljit/sljitNativeSPARC_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 +if WITH_PCRE32 +libpcre32_la_LDFLAGS = $(EXTRA_LIBPCRE32_LDFLAGS) +endif # WITH_PCRE32 + +if WITH_VALGRIND +if WITH_PCRE8 +libpcre_la_CFLAGS += $(VALGRIND_CFLAGS) +endif # WITH_PCRE8 +if WITH_PCRE16 +libpcre16_la_CFLAGS += $(VALGRIND_CFLAGS) +endif # WITH_PCRE16 +if WITH_PCRE32 +libpcre32_la_CFLAGS += $(VALGRIND_CFLAGS) +endif # WITH_PCRE32 +endif # WITH_VALGRIND + +if WITH_GCOV +if WITH_PCRE8 +libpcre_la_CFLAGS += $(GCOV_CFLAGS) +endif # WITH_PCRE8 +if WITH_PCRE16 +libpcre16_la_CFLAGS += $(GCOV_CFLAGS) +endif # WITH_PCRE16 +if WITH_PCRE32 +libpcre32_la_CFLAGS += $(GCOV_CFLAGS) +endif # WITH_PCRE32 +endif # WITH_GCOV + +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_CFLAGS = $(AM_CFLAGS) +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 +if WITH_PCRE32 +pcre_jit_test_LDADD += libpcre32.la +endif # WITH_PCRE32 +if WITH_GCOV +pcre_jit_test_CFLAGS += $(GCOV_CFLAGS) +pcre_jit_test_LDADD += $(GCOV_LIBS) +endif # WITH_GCOV +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_CFLAGS = $(VISIBILITY_CFLAGS) $(AM_CFLAGS) +libpcreposix_la_LDFLAGS = $(EXTRA_LIBPCREPOSIX_LDFLAGS) +libpcreposix_la_LIBADD = libpcre.la + +if WITH_GCOV +libpcreposix_la_CFLAGS += $(GCOV_CFLAGS) +endif # WITH_GCOV + +endif # WITH_PCRE8 + +## There's a C++ library as well. +if WITH_PCRE_CPP + +lib_LTLIBRARIES += libpcrecpp.la +libpcrecpp_la_SOURCES = \ + pcrecpp_internal.h \ + pcrecpp.cc \ + pcre_scanner.cc \ + pcre_stringpiece.cc +libpcrecpp_la_CXXFLAGS = $(VISIBILITY_CXXFLAGS) $(AM_CXXFLAGS) +libpcrecpp_la_LDFLAGS = $(EXTRA_LIBPCRECPP_LDFLAGS) +libpcrecpp_la_LIBADD = libpcre.la + +TESTS += pcrecpp_unittest +noinst_PROGRAMS += pcrecpp_unittest +pcrecpp_unittest_SOURCES = pcrecpp_unittest.cc +pcrecpp_unittest_CXXFLAGS = $(AM_CXXFLAGS) +pcrecpp_unittest_LDADD = libpcrecpp.la + +TESTS += pcre_scanner_unittest +noinst_PROGRAMS += pcre_scanner_unittest +pcre_scanner_unittest_SOURCES = pcre_scanner_unittest.cc +pcre_scanner_unittest_CXXFLAGS = $(AM_CXXFLAGS) +pcre_scanner_unittest_LDADD = libpcrecpp.la + +TESTS += pcre_stringpiece_unittest +noinst_PROGRAMS += pcre_stringpiece_unittest +pcre_stringpiece_unittest_SOURCES = pcre_stringpiece_unittest.cc +pcre_stringpiece_unittest_CXXFLAGS = $(AM_CXXFLAGS) +pcre_stringpiece_unittest_LDADD = libpcrecpp.la + +if WITH_GCOV +libpcrecpp_la_CXXFLAGS += $(GCOV_CXXFLAGS) +pcrecpp_unittest_LDADD += $(GCOV_LIBS) +pcre_scanner_unittest_LDADD += $(GCOV_LIBS) +pcre_stringpiece_unittest_LDADD += $(GCOV_LIBS) +endif # WITH_GCOV + +endif # WITH_PCRE_CPP + +## The main unit tests + +# Each unit test is a binary plus a script that runs that binary in various +# ways. We install these test binaries in case folks find it helpful. + +TESTS += RunTest +dist_noinst_SCRIPTS += RunTest +EXTRA_DIST += RunTest.bat +bin_PROGRAMS += pcretest +pcretest_SOURCES = pcretest.c +pcretest_CFLAGS = $(AM_CFLAGS) +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_PCRE32 +pcretest_SOURCES += pcre32_printint.c +pcretest_LDADD += libpcre32.la +endif # WITH_PCRE32 +if WITH_VALGRIND +pcretest_CFLAGS += $(VALGRIND_CFLAGS) +endif # WITH_VALGRIND +if WITH_GCOV +pcretest_CFLAGS += $(GCOV_CFLAGS) +pcretest_LDADD += $(GCOV_LIBS) +endif # WITH_GCOV + +if WITH_PCRE8 +TESTS += RunGrepTest +dist_noinst_SCRIPTS += RunGrepTest +bin_PROGRAMS += pcregrep +pcregrep_SOURCES = pcregrep.c +pcregrep_CFLAGS = $(AM_CFLAGS) +pcregrep_LDADD = $(LIBZ) $(LIBBZ2) +pcregrep_LDADD += libpcre.la libpcreposix.la +if WITH_GCOV +pcregrep_CFLAGS += $(GCOV_CFLAGS) +pcregrep_LDADD += $(GCOV_LIBS) +endif # WITH_GCOV +endif # WITH_PCRE8 + +EXTRA_DIST += \ + testdata/grepbinary \ + testdata/grepfilelist \ + testdata/grepinput \ + testdata/grepinput3 \ + testdata/grepinput8 \ + testdata/grepinputv \ + testdata/grepinputx \ + testdata/greplist \ + testdata/grepoutput \ + testdata/grepoutput8 \ + testdata/grepoutputN \ + testdata/greppatN4 \ + testdata/saved16 \ + testdata/saved16BE-1 \ + testdata/saved16BE-2 \ + testdata/saved16LE-1 \ + testdata/saved16LE-2 \ + testdata/saved32 \ + testdata/saved32BE-1 \ + testdata/saved32BE-2 \ + testdata/saved32LE-1 \ + testdata/saved32LE-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/testinput23 \ + testdata/testinput24 \ + testdata/testinput25 \ + testdata/testinput26 \ + testdata/testinputEBC \ + testdata/testoutput1 \ + testdata/testoutput2 \ + testdata/testoutput3 \ + testdata/testoutput4 \ + testdata/testoutput5 \ + testdata/testoutput6 \ + testdata/testoutput7 \ + testdata/testoutput8 \ + testdata/testoutput9 \ + testdata/testoutput10 \ + testdata/testoutput11-8 \ + testdata/testoutput11-16 \ + testdata/testoutput11-32 \ + testdata/testoutput12 \ + testdata/testoutput13 \ + testdata/testoutput14 \ + testdata/testoutput15 \ + testdata/testoutput16 \ + testdata/testoutput17 \ + testdata/testoutput18-16 \ + testdata/testoutput18-32 \ + testdata/testoutput19 \ + testdata/testoutput20 \ + testdata/testoutput21-16 \ + testdata/testoutput21-32 \ + testdata/testoutput22-16 \ + testdata/testoutput22-32 \ + testdata/testoutput23 \ + testdata/testoutput24 \ + testdata/testoutput25 \ + testdata/testoutput26 \ + testdata/testoutputEBC \ + testdata/wintestinput3 \ + testdata/wintestoutput3 \ + perltest.pl + +CLEANFILES += \ + testsavedregex \ + teststderr \ + testtemp* \ + testtry \ + testNinput + + +# 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 += pcredemo.c + + +## Utility rules, documentation, etc. + +# A compatibility line, the old build system worked with 'make test' +test: check ; + + +# 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_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_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 \ + pcre_xclass.o + +# 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". +pcre.dll: $(DLL_OBJS) + $(CC) -shared -o pcre.dll -Wl,"--strip-all" -Wl,"--export-all-symbols" $(DLL_OBJS) + + +# 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_PCRE32 +pkgconfig_DATA += libpcre32.pc +endif +if WITH_PCRE_CPP +pkgconfig_DATA += libpcrecpp.pc +endif + +dist_man_MANS = \ + doc/pcre.3 \ + doc/pcre16.3 \ + doc/pcre32.3 \ + doc/pcre-config.1 \ + doc/pcre_assign_jit_stack.3 \ + doc/pcre_compile.3 \ + doc/pcre_compile2.3 \ + doc/pcre_config.3 \ + doc/pcre_copy_named_substring.3 \ + 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 \ + doc/pcre_get_named_substring.3 \ + doc/pcre_get_stringnumber.3 \ + doc/pcre_get_stringtable_entries.3 \ + doc/pcre_get_substring.3 \ + doc/pcre_get_substring_list.3 \ + doc/pcre_jit_exec.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_utf32_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 \ + doc/pcreperform.3 \ + doc/pcreposix.3 \ + doc/pcreprecompile.3 \ + doc/pcresample.3 \ + doc/pcrestack.3 \ + doc/pcresyntax.3 \ + doc/pcretest.1 \ + doc/pcreunicode.3 + +# Arrange for the per-function man pages to have 16- and 32-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_exec.3 $(DESTDIR)$(man3dir)/pcre16_jit_exec.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 + ln -sf pcre_assign_jit_stack.3 $(DESTDIR)$(man3dir)/pcre32_assign_jit_stack.3 + ln -sf pcre_compile.3 $(DESTDIR)$(man3dir)/pcre32_compile.3 + ln -sf pcre_compile2.3 $(DESTDIR)$(man3dir)/pcre32_compile2.3 + ln -sf pcre_config.3 $(DESTDIR)$(man3dir)/pcre32_config.3 + ln -sf pcre_copy_named_substring.3 $(DESTDIR)$(man3dir)/pcre32_copy_named_substring.3 + ln -sf pcre_copy_substring.3 $(DESTDIR)$(man3dir)/pcre32_copy_substring.3 + ln -sf pcre_dfa_exec.3 $(DESTDIR)$(man3dir)/pcre32_dfa_exec.3 + ln -sf pcre_exec.3 $(DESTDIR)$(man3dir)/pcre32_exec.3 + ln -sf pcre_free_study.3 $(DESTDIR)$(man3dir)/pcre32_free_study.3 + ln -sf pcre_free_substring.3 $(DESTDIR)$(man3dir)/pcre32_free_substring.3 + ln -sf pcre_free_substring_list.3 $(DESTDIR)$(man3dir)/pcre32_free_substring_list.3 + ln -sf pcre_fullinfo.3 $(DESTDIR)$(man3dir)/pcre32_fullinfo.3 + ln -sf pcre_get_named_substring.3 $(DESTDIR)$(man3dir)/pcre32_get_named_substring.3 + ln -sf pcre_get_stringnumber.3 $(DESTDIR)$(man3dir)/pcre32_get_stringnumber.3 + ln -sf pcre_get_stringtable_entries.3 $(DESTDIR)$(man3dir)/pcre32_get_stringtable_entries.3 + ln -sf pcre_get_substring.3 $(DESTDIR)$(man3dir)/pcre32_get_substring.3 + ln -sf pcre_get_substring_list.3 $(DESTDIR)$(man3dir)/pcre32_get_substring_list.3 + ln -sf pcre_jit_exec.3 $(DESTDIR)$(man3dir)/pcre32_jit_exec.3 + ln -sf pcre_jit_stack_alloc.3 $(DESTDIR)$(man3dir)/pcre32_jit_stack_alloc.3 + ln -sf pcre_jit_stack_free.3 $(DESTDIR)$(man3dir)/pcre32_jit_stack_free.3 + ln -sf pcre_maketables.3 $(DESTDIR)$(man3dir)/pcre32_maketables.3 + ln -sf pcre_pattern_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre32_pattern_to_host_byte_order.3 + ln -sf pcre_refcount.3 $(DESTDIR)$(man3dir)/pcre32_refcount.3 + ln -sf pcre_study.3 $(DESTDIR)$(man3dir)/pcre32_study.3 + ln -sf pcre_utf32_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre32_utf32_to_host_byte_order.3 + ln -sf pcre_version.3 $(DESTDIR)$(man3dir)/pcre32_version.3 + +pcrecpp_man = doc/pcrecpp.3 +EXTRA_DIST += $(pcrecpp_man) + +if WITH_PCRE_CPP +man_MANS = $(pcrecpp_man) +endif + +# gcov/lcov code coverage reporting + +if WITH_GCOV + +# Coverage reporting targets: +# +# coverage: Create a coverage report from 'make check' +# coverage-baseline: Capture baseline coverage information +# coverage-reset: This zeros the coverage counters only +# coverage-report: This creates the coverage report only +# coverage-clean-report: This removes the generated coverage report +# without cleaning the coverage data itself +# coverage-clean-data: This removes the captured coverage data without +# removing the coverage files created at compile time (*.gcno) +# coverage-clean: This cleans all coverage data including the generated +# coverage report. + +COVERAGE_TEST_NAME = $(PACKAGE) +COVERAGE_NAME = $(PACKAGE)-$(VERSION) +COVERAGE_OUTPUT_FILE = $(COVERAGE_NAME)-coverage.info +COVERAGE_OUTPUT_DIR = $(COVERAGE_NAME)-coverage +COVERAGE_LCOV_EXTRA_FLAGS = +COVERAGE_GENHTML_EXTRA_FLAGS = + +coverage_quiet = $(coverage_quiet_$(V)) +coverage_quiet_ = $(coverage_quiet_$(AM_DEFAULT_VERBOSITY)) +coverage_quiet_0 = --quiet + +coverage-check: all + -$(MAKE) $(AM_MAKEFLAGS) -k check + +coverage-baseline: + $(LCOV) $(coverage_quiet) \ + --directory $(top_builddir) \ + --output-file "$(COVERAGE_OUTPUT_FILE)" \ + --capture \ + --initial + +coverage-report: + $(LCOV) $(coverage_quiet) \ + --directory $(top_builddir) \ + --capture \ + --output-file "$(COVERAGE_OUTPUT_FILE).tmp" \ + --test-name "$(COVERAGE_TEST_NAME)" \ + --no-checksum \ + --compat-libtool \ + $(COVERAGE_LCOV_EXTRA_FLAGS) + $(LCOV) $(coverage_quiet) \ + --directory $(top_builddir) \ + --output-file "$(COVERAGE_OUTPUT_FILE)" \ + --remove "$(COVERAGE_OUTPUT_FILE).tmp" \ + "/tmp/*" \ + "/usr/include/*" \ + "$(includedir)/*" + -@rm -f "$(COVERAGE_OUTPUT_FILE).tmp" + LANG=C $(GENHTML) $(coverage_quiet) \ + --prefix $(top_builddir) \ + --output-directory "$(COVERAGE_OUTPUT_DIR)" \ + --title "$(PACKAGE) $(VERSION) Code Coverage Report" \ + --show-details "$(COVERAGE_OUTPUT_FILE)" \ + --legend \ + $(COVERAGE_GENHTML_EXTRA_FLAGS) + @echo "Code coverage report written to file://$(abs_builddir)/$(COVERAGE_OUTPUT_DIR)/index.html" + +coverage-reset: + -$(LCOV) $(coverage_quiet) --zerocounters --directory $(top_builddir) + +coverage-clean-report: + -rm -f "$(COVERAGE_OUTPUT_FILE)" "$(COVERAGE_OUTPUT_FILE).tmp" + -rm -rf "$(COVERAGE_OUTPUT_DIR)" + +coverage-clean-data: + -find $(top_builddir) -name "*.gcda" -delete + +coverage-clean: coverage-reset coverage-clean-report coverage-clean-data + -find $(top_builddir) -name "*.gcno" -delete + +coverage-distclean: coverage-clean + +coverage: coverage-reset coverage-baseline coverage-check coverage-report +clean-local: coverage-clean +distclean-local: coverage-distclean + +.PHONY: coverage coverage-baseline coverage-check coverage-report coverage-reset coverage-clean-report coverage-clean-data coverage-clean coverage-distclean + +else + +coverage: + @echo "Configuring with --enable-coverage required to generate code coverage report." + +endif # WITH_GCOV + +## CMake support + +EXTRA_DIST += \ + cmake/COPYING-CMAKE-SCRIPTS \ + cmake/FindPackageHandleStandardArgs.cmake \ + cmake/FindReadline.cmake \ + cmake/FindEditline.cmake \ + CMakeLists.txt \ + config-cmake.h.in + +## end Makefile.am diff --git a/tools/pcre/Makefile.in b/tools/pcre/Makefile.in new file mode 100644 index 00000000..d026bea5 --- /dev/null +++ b/tools/pcre/Makefile.in @@ -0,0 +1,2917 @@ +# Makefile.in generated by automake 1.11.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + + + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +TESTS = $(am__EXEEXT_3) $(am__EXEEXT_4) RunTest $(am__append_38) +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 +# from corresponding .h.in files (which we do distribute). +@WITH_PCRE_CPP_TRUE@am__append_1 = \ +@WITH_PCRE_CPP_TRUE@ pcrecpparg.h \ +@WITH_PCRE_CPP_TRUE@ pcre_stringpiece.h + +@WITH_PCRE_CPP_TRUE@am__append_2 = \ +@WITH_PCRE_CPP_TRUE@ pcrecpp.h \ +@WITH_PCRE_CPP_TRUE@ pcre_scanner.h + +@WITH_REBUILD_CHARTABLES_TRUE@am__append_3 = dftables + +# 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 + +# Build the 32 bit library if it is enabled. +@WITH_PCRE32_TRUE@am__append_6 = libpcre32.la +@WITH_PCRE8_TRUE@@WITH_VALGRIND_TRUE@am__append_7 = $(VALGRIND_CFLAGS) +@WITH_PCRE16_TRUE@@WITH_VALGRIND_TRUE@am__append_8 = $(VALGRIND_CFLAGS) +@WITH_PCRE32_TRUE@@WITH_VALGRIND_TRUE@am__append_9 = $(VALGRIND_CFLAGS) +@WITH_GCOV_TRUE@@WITH_PCRE8_TRUE@am__append_10 = $(GCOV_CFLAGS) +@WITH_GCOV_TRUE@@WITH_PCRE16_TRUE@am__append_11 = $(GCOV_CFLAGS) +@WITH_GCOV_TRUE@@WITH_PCRE32_TRUE@am__append_12 = $(GCOV_CFLAGS) +@WITH_JIT_TRUE@am__append_13 = pcre_jit_test +@WITH_JIT_TRUE@am__append_14 = pcre_jit_test +@WITH_JIT_TRUE@@WITH_PCRE8_TRUE@am__append_15 = libpcre.la +@WITH_JIT_TRUE@@WITH_PCRE16_TRUE@am__append_16 = libpcre16.la +@WITH_JIT_TRUE@@WITH_PCRE32_TRUE@am__append_17 = libpcre32.la +@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__append_18 = $(GCOV_CFLAGS) +@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__append_19 = $(GCOV_LIBS) +@WITH_PCRE8_TRUE@am__append_20 = libpcreposix.la +@WITH_GCOV_TRUE@@WITH_PCRE8_TRUE@am__append_21 = $(GCOV_CFLAGS) +@WITH_PCRE_CPP_TRUE@am__append_22 = libpcrecpp.la +@WITH_PCRE_CPP_TRUE@am__append_23 = pcrecpp_unittest \ +@WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest \ +@WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest +@WITH_PCRE_CPP_TRUE@am__append_24 = pcrecpp_unittest \ +@WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest \ +@WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest +@WITH_GCOV_TRUE@@WITH_PCRE_CPP_TRUE@am__append_25 = $(GCOV_CXXFLAGS) +@WITH_GCOV_TRUE@@WITH_PCRE_CPP_TRUE@am__append_26 = $(GCOV_LIBS) +@WITH_GCOV_TRUE@@WITH_PCRE_CPP_TRUE@am__append_27 = $(GCOV_LIBS) +@WITH_GCOV_TRUE@@WITH_PCRE_CPP_TRUE@am__append_28 = $(GCOV_LIBS) +@WITH_PCRE8_TRUE@am__append_29 = pcre_printint.c +@WITH_PCRE8_TRUE@am__append_30 = libpcre.la libpcreposix.la +@WITH_PCRE16_TRUE@am__append_31 = pcre16_printint.c +@WITH_PCRE16_TRUE@am__append_32 = libpcre16.la +@WITH_PCRE32_TRUE@am__append_33 = pcre32_printint.c +@WITH_PCRE32_TRUE@am__append_34 = libpcre32.la +@WITH_VALGRIND_TRUE@am__append_35 = $(VALGRIND_CFLAGS) +@WITH_GCOV_TRUE@am__append_36 = $(GCOV_CFLAGS) +@WITH_GCOV_TRUE@am__append_37 = $(GCOV_LIBS) +@WITH_PCRE8_TRUE@am__append_38 = RunGrepTest +@WITH_PCRE8_TRUE@am__append_39 = RunGrepTest +@WITH_PCRE8_TRUE@am__append_40 = pcregrep +@WITH_GCOV_TRUE@@WITH_PCRE8_TRUE@am__append_41 = $(GCOV_CFLAGS) +@WITH_GCOV_TRUE@@WITH_PCRE8_TRUE@am__append_42 = $(GCOV_LIBS) +@WITH_PCRE16_TRUE@am__append_43 = libpcre16.pc +@WITH_PCRE32_TRUE@am__append_44 = libpcre32.pc +@WITH_PCRE_CPP_TRUE@am__append_45 = libpcrecpp.pc +subdir = . +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) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/libpcre.pc.in $(srcdir)/libpcre16.pc.in \ + $(srcdir)/libpcre32.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 $(top_srcdir)/configure AUTHORS \ + COPYING ChangeLog INSTALL NEWS compile config.guess config.sub \ + depcomp install-sh ltmain.sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pcre_visibility.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = libpcre.pc libpcre16.pc libpcre32.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 \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" \ + "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(htmldir)" \ + "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" \ + "$(DESTDIR)$(includedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libpcre_la_DEPENDENCIES = +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 = \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_byte_order.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_compile.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_config.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_dfa_exec.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_exec.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_fullinfo.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_get.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_globals.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_jit_compile.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_maketables.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_newline.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_ord2utf8.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_refcount.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_string_utils.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_study.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_tables.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_ucd.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_valid_utf8.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_version.lo \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_xclass.lo +@WITH_PCRE8_TRUE@nodist_libpcre_la_OBJECTS = \ +@WITH_PCRE8_TRUE@ libpcre_la-pcre_chartables.lo +libpcre_la_OBJECTS = $(am_libpcre_la_OBJECTS) \ + $(nodist_libpcre_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +libpcre_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpcre_la_CFLAGS) \ + $(CFLAGS) $(libpcre_la_LDFLAGS) $(LDFLAGS) -o $@ +@WITH_PCRE8_TRUE@am_libpcre_la_rpath = -rpath $(libdir) +libpcre16_la_DEPENDENCIES = +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 = \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_byte_order.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_chartables.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_compile.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_config.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_dfa_exec.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_exec.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_fullinfo.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_get.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_globals.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_jit_compile.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_maketables.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_newline.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_ord2utf16.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_refcount.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_string_utils.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_study.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_tables.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_ucd.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_utf16_utils.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_valid_utf16.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_version.lo \ +@WITH_PCRE16_TRUE@ libpcre16_la-pcre16_xclass.lo +@WITH_PCRE16_TRUE@nodist_libpcre16_la_OBJECTS = \ +@WITH_PCRE16_TRUE@ libpcre16_la-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) $(libpcre16_la_CFLAGS) \ + $(CFLAGS) $(libpcre16_la_LDFLAGS) $(LDFLAGS) -o $@ +@WITH_PCRE16_TRUE@am_libpcre16_la_rpath = -rpath $(libdir) +libpcre32_la_DEPENDENCIES = +am__libpcre32_la_SOURCES_DIST = pcre32_byte_order.c \ + pcre32_chartables.c pcre32_compile.c pcre32_config.c \ + pcre32_dfa_exec.c pcre32_exec.c pcre32_fullinfo.c pcre32_get.c \ + pcre32_globals.c pcre32_jit_compile.c pcre32_maketables.c \ + pcre32_newline.c pcre32_ord2utf32.c pcre32_refcount.c \ + pcre32_string_utils.c pcre32_study.c pcre32_tables.c \ + pcre32_ucd.c pcre32_utf32_utils.c pcre32_valid_utf32.c \ + pcre32_version.c pcre32_xclass.c +@WITH_PCRE32_TRUE@am_libpcre32_la_OBJECTS = \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_byte_order.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_chartables.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_compile.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_config.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_dfa_exec.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_exec.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_fullinfo.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_get.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_globals.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_jit_compile.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_maketables.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_newline.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_ord2utf32.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_refcount.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_string_utils.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_study.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_tables.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_ucd.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_utf32_utils.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_valid_utf32.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_version.lo \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre32_xclass.lo +@WITH_PCRE32_TRUE@nodist_libpcre32_la_OBJECTS = \ +@WITH_PCRE32_TRUE@ libpcre32_la-pcre_chartables.lo +libpcre32_la_OBJECTS = $(am_libpcre32_la_OBJECTS) \ + $(nodist_libpcre32_la_OBJECTS) +libpcre32_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpcre32_la_CFLAGS) \ + $(CFLAGS) $(libpcre32_la_LDFLAGS) $(LDFLAGS) -o $@ +@WITH_PCRE32_TRUE@am_libpcre32_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 = \ +@WITH_PCRE_CPP_TRUE@ libpcrecpp_la-pcrecpp.lo \ +@WITH_PCRE_CPP_TRUE@ libpcrecpp_la-pcre_scanner.lo \ +@WITH_PCRE_CPP_TRUE@ libpcrecpp_la-pcre_stringpiece.lo +libpcrecpp_la_OBJECTS = $(am_libpcrecpp_la_OBJECTS) +libpcrecpp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(libpcrecpp_la_CXXFLAGS) $(CXXFLAGS) $(libpcrecpp_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@WITH_PCRE_CPP_TRUE@am_libpcrecpp_la_rpath = -rpath $(libdir) +@WITH_PCRE8_TRUE@libpcreposix_la_DEPENDENCIES = libpcre.la +am__libpcreposix_la_SOURCES_DIST = pcreposix.c +@WITH_PCRE8_TRUE@am_libpcreposix_la_OBJECTS = \ +@WITH_PCRE8_TRUE@ libpcreposix_la-pcreposix.lo +libpcreposix_la_OBJECTS = $(am_libpcreposix_la_OBJECTS) +libpcreposix_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libpcreposix_la_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) +am__dftables_SOURCES_DIST = dftables.c +@WITH_REBUILD_CHARTABLES_TRUE@am_dftables_OBJECTS = \ +@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 = \ +@WITH_JIT_TRUE@ pcre_jit_test-pcre_jit_test.$(OBJEXT) +pcre_jit_test_OBJECTS = $(am_pcre_jit_test_OBJECTS) +am__DEPENDENCIES_1 = +@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__DEPENDENCIES_2 = \ +@WITH_GCOV_TRUE@@WITH_JIT_TRUE@ $(am__DEPENDENCIES_1) +@WITH_JIT_TRUE@pcre_jit_test_DEPENDENCIES = $(am__append_15) \ +@WITH_JIT_TRUE@ $(am__append_16) $(am__append_17) \ +@WITH_JIT_TRUE@ $(am__DEPENDENCIES_2) +pcre_jit_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(pcre_jit_test_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__pcre_scanner_unittest_SOURCES_DIST = pcre_scanner_unittest.cc +@WITH_PCRE_CPP_TRUE@am_pcre_scanner_unittest_OBJECTS = pcre_scanner_unittest-pcre_scanner_unittest.$(OBJEXT) +pcre_scanner_unittest_OBJECTS = $(am_pcre_scanner_unittest_OBJECTS) +@WITH_GCOV_TRUE@@WITH_PCRE_CPP_TRUE@am__DEPENDENCIES_3 = \ +@WITH_GCOV_TRUE@@WITH_PCRE_CPP_TRUE@ $(am__DEPENDENCIES_1) +@WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_DEPENDENCIES = \ +@WITH_PCRE_CPP_TRUE@ libpcrecpp.la $(am__DEPENDENCIES_3) +pcre_scanner_unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(pcre_scanner_unittest_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__pcre_stringpiece_unittest_SOURCES_DIST = \ + pcre_stringpiece_unittest.cc +@WITH_PCRE_CPP_TRUE@am_pcre_stringpiece_unittest_OBJECTS = pcre_stringpiece_unittest-pcre_stringpiece_unittest.$(OBJEXT) +pcre_stringpiece_unittest_OBJECTS = \ + $(am_pcre_stringpiece_unittest_OBJECTS) +@WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_DEPENDENCIES = \ +@WITH_PCRE_CPP_TRUE@ libpcrecpp.la $(am__DEPENDENCIES_3) +pcre_stringpiece_unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(pcre_stringpiece_unittest_CXXFLAGS) $(CXXFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__pcrecpp_unittest_SOURCES_DIST = pcrecpp_unittest.cc +@WITH_PCRE_CPP_TRUE@am_pcrecpp_unittest_OBJECTS = pcrecpp_unittest-pcrecpp_unittest.$(OBJEXT) +pcrecpp_unittest_OBJECTS = $(am_pcrecpp_unittest_OBJECTS) +@WITH_PCRE_CPP_TRUE@pcrecpp_unittest_DEPENDENCIES = libpcrecpp.la \ +@WITH_PCRE_CPP_TRUE@ $(am__DEPENDENCIES_3) +pcrecpp_unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(pcrecpp_unittest_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__pcregrep_SOURCES_DIST = pcregrep.c +@WITH_PCRE8_TRUE@am_pcregrep_OBJECTS = pcregrep-pcregrep.$(OBJEXT) +pcregrep_OBJECTS = $(am_pcregrep_OBJECTS) +@WITH_GCOV_TRUE@@WITH_PCRE8_TRUE@am__DEPENDENCIES_4 = \ +@WITH_GCOV_TRUE@@WITH_PCRE8_TRUE@ $(am__DEPENDENCIES_1) +@WITH_PCRE8_TRUE@pcregrep_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@WITH_PCRE8_TRUE@ $(am__DEPENDENCIES_1) libpcre.la \ +@WITH_PCRE8_TRUE@ libpcreposix.la $(am__DEPENDENCIES_4) +pcregrep_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(pcregrep_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__pcretest_SOURCES_DIST = pcretest.c pcre_printint.c \ + pcre16_printint.c pcre32_printint.c +@WITH_PCRE8_TRUE@am__objects_1 = pcretest-pcre_printint.$(OBJEXT) +@WITH_PCRE16_TRUE@am__objects_2 = pcretest-pcre16_printint.$(OBJEXT) +@WITH_PCRE32_TRUE@am__objects_3 = pcretest-pcre32_printint.$(OBJEXT) +am_pcretest_OBJECTS = pcretest-pcretest.$(OBJEXT) $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) +pcretest_OBJECTS = $(am_pcretest_OBJECTS) +@WITH_GCOV_TRUE@am__DEPENDENCIES_5 = $(am__DEPENDENCIES_1) +pcretest_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__append_30) \ + $(am__append_32) $(am__append_34) $(am__DEPENDENCIES_5) +pcretest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(pcretest_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__dist_noinst_SCRIPTS_DIST = RunTest RunGrepTest +SCRIPTS = $(bin_SCRIPTS) $(dist_noinst_SCRIPTS) +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +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_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +CCLD = $(CC) +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_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +CXXCOMPILE = $(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_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +CXXLD = $(CXX) +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_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libpcre_la_SOURCES) $(nodist_libpcre_la_SOURCES) \ + $(libpcre16_la_SOURCES) $(nodist_libpcre16_la_SOURCES) \ + $(libpcre32_la_SOURCES) $(nodist_libpcre32_la_SOURCES) \ + $(libpcrecpp_la_SOURCES) $(libpcreposix_la_SOURCES) \ + $(dftables_SOURCES) $(pcre_jit_test_SOURCES) \ + $(pcre_scanner_unittest_SOURCES) \ + $(pcre_stringpiece_unittest_SOURCES) \ + $(pcrecpp_unittest_SOURCES) $(pcregrep_SOURCES) \ + $(pcretest_SOURCES) +DIST_SOURCES = $(am__libpcre_la_SOURCES_DIST) \ + $(am__libpcre16_la_SOURCES_DIST) \ + $(am__libpcre32_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) \ + $(am__pcregrep_SOURCES_DIST) $(am__pcretest_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +man1dir = $(mandir)/man1 +man3dir = $(mandir)/man3 +NROFF = nroff +MANS = $(dist_man_MANS) $(man_MANS) +DATA = $(dist_doc_DATA) $(dist_html_DATA) $(dist_noinst_DATA) \ + $(html_DATA) $(pkgconfig_DATA) +am__include_HEADERS_DIST = pcreposix.h pcrecpp.h pcre_scanner.h +HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBPCRE16_LDFLAGS = @EXTRA_LIBPCRE16_LDFLAGS@ +EXTRA_LIBPCRE32_LDFLAGS = @EXTRA_LIBPCRE32_LDFLAGS@ +EXTRA_LIBPCRECPP_LDFLAGS = @EXTRA_LIBPCRECPP_LDFLAGS@ +EXTRA_LIBPCREPOSIX_LDFLAGS = @EXTRA_LIBPCREPOSIX_LDFLAGS@ +EXTRA_LIBPCRE_LDFLAGS = @EXTRA_LIBPCRE_LDFLAGS@ +FGREP = @FGREP@ +GCOV_CFLAGS = @GCOV_CFLAGS@ +GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ +GCOV_LIBS = @GCOV_LIBS@ +GENHTML = @GENHTML@ +GREP = @GREP@ +HAVE_VISIBILITY = @HAVE_VISIBILITY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBBZ2 = @LIBBZ2@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBZ = @LIBZ@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCRE_DATE = @PCRE_DATE@ +PCRE_MAJOR = @PCRE_MAJOR@ +PCRE_MINOR = @PCRE_MINOR@ +PCRE_PRERELEASE = @PCRE_PRERELEASE@ +PCRE_STATIC_CFLAG = @PCRE_STATIC_CFLAG@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SHTOOL = @SHTOOL@ +STRIP = @STRIP@ +VALGRIND_CFLAGS = @VALGRIND_CFLAGS@ +VALGRIND_LIBS = @VALGRIND_LIBS@ +VERSION = @VERSION@ +VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ +VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@ +abs_builddir = @abs_builddir@ +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@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_cpp = @enable_cpp@ +enable_pcre16 = @enable_pcre16@ +enable_pcre32 = @enable_pcre32@ +enable_pcre8 = @enable_pcre8@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pcre_have_bits_type_traits = @pcre_have_bits_type_traits@ +pcre_have_long_long = @pcre_have_long_long@ +pcre_have_type_traits = @pcre_have_type_traits@ +pcre_have_ulong_long = @pcre_have_ulong_long@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I m4 +dist_doc_DATA = \ + doc/pcre.txt \ + doc/pcre-config.txt \ + doc/pcregrep.txt \ + doc/pcretest.txt \ + AUTHORS \ + COPYING \ + ChangeLog \ + LICENCE \ + NEWS \ + README + +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 \ + doc/html/pcre_copy_named_substring.html \ + 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 \ + doc/html/pcre_get_named_substring.html \ + doc/html/pcre_get_stringnumber.html \ + doc/html/pcre_get_stringtable_entries.html \ + doc/html/pcre_get_substring.html \ + doc/html/pcre_get_substring_list.html \ + doc/html/pcre_jit_exec.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 \ + doc/html/pcrecallout.html \ + 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 \ + doc/html/pcreperform.html \ + doc/html/pcreposix.html \ + doc/html/pcreprecompile.html \ + doc/html/pcresample.html \ + doc/html/pcrestack.html \ + doc/html/pcresyntax.html \ + doc/html/pcretest.html \ + doc/html/pcreunicode.html + + +# doc/html/pcre32.html \ +# doc/html/pcre_utf32_to_host_byte_order.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 = $(am__append_4) $(am__append_5) $(am__append_6) \ + $(am__append_20) $(am__append_22) +check_SCRIPTS = +dist_noinst_SCRIPTS = RunTest $(am__append_39) + +# Additional files to delete on 'make clean' and 'make maintainer-clean'. +CLEANFILES = pcre_chartables.c testsavedregex teststderr testtemp* \ + testtry testNinput +MAINTAINERCLEANFILES = pcre.h.generic config.h.generic + +# Additional files to bundle with the distribution, over and above what +# the Autotools include by default. + +# These files contain additional m4 macros that are used by autoconf. + +# These files contain maintenance information + +# These files are used in the preparation of a release + +# These files are to do with building for Virtual Pascal + +# These files are usable versions of pcre.h and config.h that are distributed +# for the benefit of people who are building PCRE manually, without the +# Autotools support. + +# 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 = m4/ax_pthread.m4 m4/pcre_visibility.m4 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/sljitNativeSPARC_32.c \ + sljit/sljitNativeSPARC_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/greppatN4 testdata/saved16 \ + testdata/saved16BE-1 testdata/saved16BE-2 testdata/saved16LE-1 \ + testdata/saved16LE-2 testdata/saved32 testdata/saved32BE-1 \ + testdata/saved32BE-2 testdata/saved32LE-1 testdata/saved32LE-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/testinput23 \ + testdata/testinput24 testdata/testinput25 testdata/testinput26 \ + testdata/testinputEBC testdata/testoutput1 \ + testdata/testoutput2 testdata/testoutput3 testdata/testoutput4 \ + testdata/testoutput5 testdata/testoutput6 testdata/testoutput7 \ + testdata/testoutput8 testdata/testoutput9 \ + testdata/testoutput10 testdata/testoutput11-8 \ + testdata/testoutput11-16 testdata/testoutput11-32 \ + testdata/testoutput12 testdata/testoutput13 \ + testdata/testoutput14 testdata/testoutput15 \ + testdata/testoutput16 testdata/testoutput17 \ + testdata/testoutput18-16 testdata/testoutput18-32 \ + testdata/testoutput19 testdata/testoutput20 \ + testdata/testoutput21-16 testdata/testoutput21-32 \ + testdata/testoutput22-16 testdata/testoutput22-32 \ + testdata/testoutput23 testdata/testoutput24 \ + testdata/testoutput25 testdata/testoutput26 \ + testdata/testoutputEBC testdata/wintestinput3 \ + testdata/wintestoutput3 perltest.pl pcredemo.c $(pcrecpp_man) \ + cmake/COPYING-CMAKE-SCRIPTS \ + cmake/FindPackageHandleStandardArgs.cmake \ + 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. +nodist_include_HEADERS = pcre.h $(am__append_1) +include_HEADERS = pcreposix.h $(am__append_2) +bin_SCRIPTS = pcre-config +@WITH_REBUILD_CHARTABLES_TRUE@dftables_SOURCES = dftables.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@libpcre_la_CFLAGS = $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \ +@WITH_PCRE8_TRUE@ $(am__append_7) $(am__append_10) +@WITH_PCRE8_TRUE@libpcre_la_LIBADD = +@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@libpcre16_la_CFLAGS = $(VISIBILITY_CFLAGS) \ +@WITH_PCRE16_TRUE@ $(AM_CFLAGS) $(am__append_8) \ +@WITH_PCRE16_TRUE@ $(am__append_11) +@WITH_PCRE16_TRUE@libpcre16_la_LIBADD = +@WITH_PCRE16_TRUE@nodist_libpcre16_la_SOURCES = \ +@WITH_PCRE16_TRUE@ pcre_chartables.c + +@WITH_PCRE32_TRUE@libpcre32_la_SOURCES = \ +@WITH_PCRE32_TRUE@ pcre32_byte_order.c \ +@WITH_PCRE32_TRUE@ pcre32_chartables.c \ +@WITH_PCRE32_TRUE@ pcre32_compile.c \ +@WITH_PCRE32_TRUE@ pcre32_config.c \ +@WITH_PCRE32_TRUE@ pcre32_dfa_exec.c \ +@WITH_PCRE32_TRUE@ pcre32_exec.c \ +@WITH_PCRE32_TRUE@ pcre32_fullinfo.c \ +@WITH_PCRE32_TRUE@ pcre32_get.c \ +@WITH_PCRE32_TRUE@ pcre32_globals.c \ +@WITH_PCRE32_TRUE@ pcre32_jit_compile.c \ +@WITH_PCRE32_TRUE@ pcre32_maketables.c \ +@WITH_PCRE32_TRUE@ pcre32_newline.c \ +@WITH_PCRE32_TRUE@ pcre32_ord2utf32.c \ +@WITH_PCRE32_TRUE@ pcre32_refcount.c \ +@WITH_PCRE32_TRUE@ pcre32_string_utils.c \ +@WITH_PCRE32_TRUE@ pcre32_study.c \ +@WITH_PCRE32_TRUE@ pcre32_tables.c \ +@WITH_PCRE32_TRUE@ pcre32_ucd.c \ +@WITH_PCRE32_TRUE@ pcre32_utf32_utils.c \ +@WITH_PCRE32_TRUE@ pcre32_valid_utf32.c \ +@WITH_PCRE32_TRUE@ pcre32_version.c \ +@WITH_PCRE32_TRUE@ pcre32_xclass.c + +@WITH_PCRE32_TRUE@libpcre32_la_CFLAGS = $(VISIBILITY_CFLAGS) \ +@WITH_PCRE32_TRUE@ $(AM_CFLAGS) $(am__append_9) \ +@WITH_PCRE32_TRUE@ $(am__append_12) +@WITH_PCRE32_TRUE@libpcre32_la_LIBADD = +@WITH_PCRE32_TRUE@nodist_libpcre32_la_SOURCES = \ +@WITH_PCRE32_TRUE@ pcre_chartables.c + +@WITH_PCRE8_TRUE@libpcre_la_LDFLAGS = $(EXTRA_LIBPCRE_LDFLAGS) +@WITH_PCRE16_TRUE@libpcre16_la_LDFLAGS = $(EXTRA_LIBPCRE16_LDFLAGS) +@WITH_PCRE32_TRUE@libpcre32_la_LDFLAGS = $(EXTRA_LIBPCRE32_LDFLAGS) +@WITH_JIT_TRUE@pcre_jit_test_SOURCES = pcre_jit_test.c +@WITH_JIT_TRUE@pcre_jit_test_CFLAGS = $(AM_CFLAGS) $(am__append_18) +@WITH_JIT_TRUE@pcre_jit_test_LDADD = $(am__append_15) $(am__append_16) \ +@WITH_JIT_TRUE@ $(am__append_17) $(am__append_19) +@WITH_PCRE8_TRUE@libpcreposix_la_SOURCES = \ +@WITH_PCRE8_TRUE@ pcreposix.c + +@WITH_PCRE8_TRUE@libpcreposix_la_CFLAGS = $(VISIBILITY_CFLAGS) \ +@WITH_PCRE8_TRUE@ $(AM_CFLAGS) $(am__append_21) +@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 \ +@WITH_PCRE_CPP_TRUE@ pcre_scanner.cc \ +@WITH_PCRE_CPP_TRUE@ pcre_stringpiece.cc + +@WITH_PCRE_CPP_TRUE@libpcrecpp_la_CXXFLAGS = $(VISIBILITY_CXXFLAGS) \ +@WITH_PCRE_CPP_TRUE@ $(AM_CXXFLAGS) $(am__append_25) +@WITH_PCRE_CPP_TRUE@libpcrecpp_la_LDFLAGS = $(EXTRA_LIBPCRECPP_LDFLAGS) +@WITH_PCRE_CPP_TRUE@libpcrecpp_la_LIBADD = libpcre.la +@WITH_PCRE_CPP_TRUE@pcrecpp_unittest_SOURCES = pcrecpp_unittest.cc +@WITH_PCRE_CPP_TRUE@pcrecpp_unittest_CXXFLAGS = $(AM_CXXFLAGS) +@WITH_PCRE_CPP_TRUE@pcrecpp_unittest_LDADD = libpcrecpp.la \ +@WITH_PCRE_CPP_TRUE@ $(am__append_26) +@WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_SOURCES = pcre_scanner_unittest.cc +@WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_CXXFLAGS = $(AM_CXXFLAGS) +@WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_LDADD = libpcrecpp.la \ +@WITH_PCRE_CPP_TRUE@ $(am__append_27) +@WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_SOURCES = pcre_stringpiece_unittest.cc +@WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_CXXFLAGS = $(AM_CXXFLAGS) +@WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_LDADD = libpcrecpp.la \ +@WITH_PCRE_CPP_TRUE@ $(am__append_28) +pcretest_SOURCES = pcretest.c $(am__append_29) $(am__append_31) \ + $(am__append_33) +pcretest_CFLAGS = $(AM_CFLAGS) $(am__append_35) $(am__append_36) +pcretest_LDADD = $(LIBREADLINE) $(am__append_30) $(am__append_32) \ + $(am__append_34) $(am__append_37) +@WITH_PCRE8_TRUE@pcregrep_SOURCES = pcregrep.c +@WITH_PCRE8_TRUE@pcregrep_CFLAGS = $(AM_CFLAGS) $(am__append_41) +@WITH_PCRE8_TRUE@pcregrep_LDADD = $(LIBZ) $(LIBBZ2) libpcre.la \ +@WITH_PCRE8_TRUE@ libpcreposix.la $(am__append_42) + +# 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_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_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 \ + pcre_xclass.o + + +# We have .pc files for pkg-config users. +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libpcre.pc libpcreposix.pc $(am__append_43) \ + $(am__append_44) $(am__append_45) +dist_man_MANS = \ + doc/pcre.3 \ + doc/pcre16.3 \ + doc/pcre32.3 \ + doc/pcre-config.1 \ + doc/pcre_assign_jit_stack.3 \ + doc/pcre_compile.3 \ + doc/pcre_compile2.3 \ + doc/pcre_config.3 \ + doc/pcre_copy_named_substring.3 \ + 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 \ + doc/pcre_get_named_substring.3 \ + doc/pcre_get_stringnumber.3 \ + doc/pcre_get_stringtable_entries.3 \ + doc/pcre_get_substring.3 \ + doc/pcre_get_substring_list.3 \ + doc/pcre_jit_exec.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_utf32_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 \ + doc/pcreperform.3 \ + doc/pcreposix.3 \ + doc/pcreprecompile.3 \ + doc/pcresample.3 \ + doc/pcrestack.3 \ + doc/pcresyntax.3 \ + doc/pcretest.1 \ + doc/pcreunicode.3 + +pcrecpp_man = doc/pcrecpp.3 +@WITH_PCRE_CPP_TRUE@man_MANS = $(pcrecpp_man) + +# gcov/lcov code coverage reporting + +# Coverage reporting targets: +# +# coverage: Create a coverage report from 'make check' +# coverage-baseline: Capture baseline coverage information +# coverage-reset: This zeros the coverage counters only +# coverage-report: This creates the coverage report only +# coverage-clean-report: This removes the generated coverage report +# without cleaning the coverage data itself +# coverage-clean-data: This removes the captured coverage data without +# removing the coverage files created at compile time (*.gcno) +# coverage-clean: This cleans all coverage data including the generated +# coverage report. +@WITH_GCOV_TRUE@COVERAGE_TEST_NAME = $(PACKAGE) +@WITH_GCOV_TRUE@COVERAGE_NAME = $(PACKAGE)-$(VERSION) +@WITH_GCOV_TRUE@COVERAGE_OUTPUT_FILE = $(COVERAGE_NAME)-coverage.info +@WITH_GCOV_TRUE@COVERAGE_OUTPUT_DIR = $(COVERAGE_NAME)-coverage +@WITH_GCOV_TRUE@COVERAGE_LCOV_EXTRA_FLAGS = +@WITH_GCOV_TRUE@COVERAGE_GENHTML_EXTRA_FLAGS = +@WITH_GCOV_TRUE@coverage_quiet = $(coverage_quiet_$(V)) +@WITH_GCOV_TRUE@coverage_quiet_ = $(coverage_quiet_$(AM_DEFAULT_VERBOSITY)) +@WITH_GCOV_TRUE@coverage_quiet_0 = --quiet +all: $(BUILT_SOURCES) config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .cc .lo .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -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 $@ +libpcre32.pc: $(top_builddir)/config.status $(srcdir)/libpcre32.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 + cd $(top_builddir) && $(SHELL) ./config.status $@ +pcre-config: $(top_builddir)/config.status $(srcdir)/pcre-config.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +pcre.h: $(top_builddir)/config.status $(srcdir)/pcre.h.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +pcre_stringpiece.h: $(top_builddir)/config.status $(srcdir)/pcre_stringpiece.h.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +pcrecpparg.h: $(top_builddir)/config.status $(srcdir)/pcrecpparg.h.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libpcre.la: $(libpcre_la_OBJECTS) $(libpcre_la_DEPENDENCIES) $(EXTRA_libpcre_la_DEPENDENCIES) + $(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) $(EXTRA_libpcre16_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpcre16_la_LINK) $(am_libpcre16_la_rpath) $(libpcre16_la_OBJECTS) $(libpcre16_la_LIBADD) $(LIBS) +libpcre32.la: $(libpcre32_la_OBJECTS) $(libpcre32_la_DEPENDENCIES) $(EXTRA_libpcre32_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpcre32_la_LINK) $(am_libpcre32_la_rpath) $(libpcre32_la_OBJECTS) $(libpcre32_la_LIBADD) $(LIBS) +libpcrecpp.la: $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_DEPENDENCIES) $(EXTRA_libpcrecpp_la_DEPENDENCIES) + $(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) $(EXTRA_libpcreposix_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpcreposix_la_LINK) $(am_libpcreposix_la_rpath) $(libpcreposix_la_OBJECTS) $(libpcreposix_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +dftables$(EXEEXT): $(dftables_OBJECTS) $(dftables_DEPENDENCIES) $(EXTRA_dftables_DEPENDENCIES) + @rm -f dftables$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dftables_OBJECTS) $(dftables_LDADD) $(LIBS) +pcre_jit_test$(EXEEXT): $(pcre_jit_test_OBJECTS) $(pcre_jit_test_DEPENDENCIES) $(EXTRA_pcre_jit_test_DEPENDENCIES) + @rm -f pcre_jit_test$(EXEEXT) + $(AM_V_CCLD)$(pcre_jit_test_LINK) $(pcre_jit_test_OBJECTS) $(pcre_jit_test_LDADD) $(LIBS) +pcre_scanner_unittest$(EXEEXT): $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_DEPENDENCIES) $(EXTRA_pcre_scanner_unittest_DEPENDENCIES) + @rm -f pcre_scanner_unittest$(EXEEXT) + $(AM_V_CXXLD)$(pcre_scanner_unittest_LINK) $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_LDADD) $(LIBS) +pcre_stringpiece_unittest$(EXEEXT): $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_DEPENDENCIES) $(EXTRA_pcre_stringpiece_unittest_DEPENDENCIES) + @rm -f pcre_stringpiece_unittest$(EXEEXT) + $(AM_V_CXXLD)$(pcre_stringpiece_unittest_LINK) $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_LDADD) $(LIBS) +pcrecpp_unittest$(EXEEXT): $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_DEPENDENCIES) $(EXTRA_pcrecpp_unittest_DEPENDENCIES) + @rm -f pcrecpp_unittest$(EXEEXT) + $(AM_V_CXXLD)$(pcrecpp_unittest_LINK) $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_LDADD) $(LIBS) +pcregrep$(EXEEXT): $(pcregrep_OBJECTS) $(pcregrep_DEPENDENCIES) $(EXTRA_pcregrep_DEPENDENCIES) + @rm -f pcregrep$(EXEEXT) + $(AM_V_CCLD)$(pcregrep_LINK) $(pcregrep_OBJECTS) $(pcregrep_LDADD) $(LIBS) +pcretest$(EXEEXT): $(pcretest_OBJECTS) $(pcretest_DEPENDENCIES) $(EXTRA_pcretest_DEPENDENCIES) + @rm -f pcretest$(EXEEXT) + $(AM_V_CCLD)$(pcretest_LINK) $(pcretest_OBJECTS) $(pcretest_LDADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dftables.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_byte_order.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_chartables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_dfa_exec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_exec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_fullinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_get.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_globals.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_jit_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_maketables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_newline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_ord2utf16.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_refcount.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_string_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_study.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_tables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_ucd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_utf16_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_valid_utf16.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_version.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre16_xclass.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre16_la-pcre_chartables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_byte_order.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_chartables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_dfa_exec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_exec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_fullinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_get.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_globals.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_jit_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_maketables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_newline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_ord2utf32.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_refcount.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_string_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_study.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_tables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_ucd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_utf32_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_valid_utf32.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_version.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre32_xclass.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre32_la-pcre_chartables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_byte_order.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_chartables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_dfa_exec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_exec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_fullinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_get.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_globals.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_jit_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_maketables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_newline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_ord2utf8.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_refcount.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_string_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_study.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_tables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_ucd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_valid_utf8.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_version.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcre_la-pcre_xclass.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcrecpp_la-pcre_scanner.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcrecpp_la-pcre_stringpiece.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcrecpp_la-pcrecpp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpcreposix_la-pcreposix.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_jit_test-pcre_jit_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_scanner_unittest-pcre_scanner_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_stringpiece_unittest-pcre_stringpiece_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcrecpp_unittest-pcrecpp_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcregrep-pcregrep.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcretest-pcre16_printint.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcretest-pcre32_printint.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcretest-pcre_printint.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcretest-pcretest.Po@am__quote@ + +.c.o: +@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 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@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 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@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 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpcre_la-pcre_byte_order.lo: pcre_byte_order.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_byte_order.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_byte_order.Tpo -c -o libpcre_la-pcre_byte_order.lo `test -f 'pcre_byte_order.c' || echo '$(srcdir)/'`pcre_byte_order.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_byte_order.Tpo $(DEPDIR)/libpcre_la-pcre_byte_order.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_byte_order.c' object='libpcre_la-pcre_byte_order.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_byte_order.lo `test -f 'pcre_byte_order.c' || echo '$(srcdir)/'`pcre_byte_order.c + +libpcre_la-pcre_compile.lo: pcre_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_compile.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_compile.Tpo -c -o libpcre_la-pcre_compile.lo `test -f 'pcre_compile.c' || echo '$(srcdir)/'`pcre_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_compile.Tpo $(DEPDIR)/libpcre_la-pcre_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_compile.c' object='libpcre_la-pcre_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_compile.lo `test -f 'pcre_compile.c' || echo '$(srcdir)/'`pcre_compile.c + +libpcre_la-pcre_config.lo: pcre_config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_config.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_config.Tpo -c -o libpcre_la-pcre_config.lo `test -f 'pcre_config.c' || echo '$(srcdir)/'`pcre_config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_config.Tpo $(DEPDIR)/libpcre_la-pcre_config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_config.c' object='libpcre_la-pcre_config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_config.lo `test -f 'pcre_config.c' || echo '$(srcdir)/'`pcre_config.c + +libpcre_la-pcre_dfa_exec.lo: pcre_dfa_exec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_dfa_exec.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_dfa_exec.Tpo -c -o libpcre_la-pcre_dfa_exec.lo `test -f 'pcre_dfa_exec.c' || echo '$(srcdir)/'`pcre_dfa_exec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_dfa_exec.Tpo $(DEPDIR)/libpcre_la-pcre_dfa_exec.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_dfa_exec.c' object='libpcre_la-pcre_dfa_exec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_dfa_exec.lo `test -f 'pcre_dfa_exec.c' || echo '$(srcdir)/'`pcre_dfa_exec.c + +libpcre_la-pcre_exec.lo: pcre_exec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_exec.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_exec.Tpo -c -o libpcre_la-pcre_exec.lo `test -f 'pcre_exec.c' || echo '$(srcdir)/'`pcre_exec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_exec.Tpo $(DEPDIR)/libpcre_la-pcre_exec.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_exec.c' object='libpcre_la-pcre_exec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_exec.lo `test -f 'pcre_exec.c' || echo '$(srcdir)/'`pcre_exec.c + +libpcre_la-pcre_fullinfo.lo: pcre_fullinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_fullinfo.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_fullinfo.Tpo -c -o libpcre_la-pcre_fullinfo.lo `test -f 'pcre_fullinfo.c' || echo '$(srcdir)/'`pcre_fullinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_fullinfo.Tpo $(DEPDIR)/libpcre_la-pcre_fullinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_fullinfo.c' object='libpcre_la-pcre_fullinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_fullinfo.lo `test -f 'pcre_fullinfo.c' || echo '$(srcdir)/'`pcre_fullinfo.c + +libpcre_la-pcre_get.lo: pcre_get.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_get.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_get.Tpo -c -o libpcre_la-pcre_get.lo `test -f 'pcre_get.c' || echo '$(srcdir)/'`pcre_get.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_get.Tpo $(DEPDIR)/libpcre_la-pcre_get.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_get.c' object='libpcre_la-pcre_get.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_get.lo `test -f 'pcre_get.c' || echo '$(srcdir)/'`pcre_get.c + +libpcre_la-pcre_globals.lo: pcre_globals.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_globals.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_globals.Tpo -c -o libpcre_la-pcre_globals.lo `test -f 'pcre_globals.c' || echo '$(srcdir)/'`pcre_globals.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_globals.Tpo $(DEPDIR)/libpcre_la-pcre_globals.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_globals.c' object='libpcre_la-pcre_globals.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_globals.lo `test -f 'pcre_globals.c' || echo '$(srcdir)/'`pcre_globals.c + +libpcre_la-pcre_jit_compile.lo: pcre_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_jit_compile.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_jit_compile.Tpo -c -o libpcre_la-pcre_jit_compile.lo `test -f 'pcre_jit_compile.c' || echo '$(srcdir)/'`pcre_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_jit_compile.Tpo $(DEPDIR)/libpcre_la-pcre_jit_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_jit_compile.c' object='libpcre_la-pcre_jit_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_jit_compile.lo `test -f 'pcre_jit_compile.c' || echo '$(srcdir)/'`pcre_jit_compile.c + +libpcre_la-pcre_maketables.lo: pcre_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_maketables.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_maketables.Tpo -c -o libpcre_la-pcre_maketables.lo `test -f 'pcre_maketables.c' || echo '$(srcdir)/'`pcre_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_maketables.Tpo $(DEPDIR)/libpcre_la-pcre_maketables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_maketables.c' object='libpcre_la-pcre_maketables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_maketables.lo `test -f 'pcre_maketables.c' || echo '$(srcdir)/'`pcre_maketables.c + +libpcre_la-pcre_newline.lo: pcre_newline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_newline.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_newline.Tpo -c -o libpcre_la-pcre_newline.lo `test -f 'pcre_newline.c' || echo '$(srcdir)/'`pcre_newline.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_newline.Tpo $(DEPDIR)/libpcre_la-pcre_newline.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_newline.c' object='libpcre_la-pcre_newline.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_newline.lo `test -f 'pcre_newline.c' || echo '$(srcdir)/'`pcre_newline.c + +libpcre_la-pcre_ord2utf8.lo: pcre_ord2utf8.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_ord2utf8.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_ord2utf8.Tpo -c -o libpcre_la-pcre_ord2utf8.lo `test -f 'pcre_ord2utf8.c' || echo '$(srcdir)/'`pcre_ord2utf8.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_ord2utf8.Tpo $(DEPDIR)/libpcre_la-pcre_ord2utf8.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_ord2utf8.c' object='libpcre_la-pcre_ord2utf8.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_ord2utf8.lo `test -f 'pcre_ord2utf8.c' || echo '$(srcdir)/'`pcre_ord2utf8.c + +libpcre_la-pcre_refcount.lo: pcre_refcount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_refcount.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_refcount.Tpo -c -o libpcre_la-pcre_refcount.lo `test -f 'pcre_refcount.c' || echo '$(srcdir)/'`pcre_refcount.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_refcount.Tpo $(DEPDIR)/libpcre_la-pcre_refcount.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_refcount.c' object='libpcre_la-pcre_refcount.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_refcount.lo `test -f 'pcre_refcount.c' || echo '$(srcdir)/'`pcre_refcount.c + +libpcre_la-pcre_string_utils.lo: pcre_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_string_utils.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_string_utils.Tpo -c -o libpcre_la-pcre_string_utils.lo `test -f 'pcre_string_utils.c' || echo '$(srcdir)/'`pcre_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_string_utils.Tpo $(DEPDIR)/libpcre_la-pcre_string_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_string_utils.c' object='libpcre_la-pcre_string_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_string_utils.lo `test -f 'pcre_string_utils.c' || echo '$(srcdir)/'`pcre_string_utils.c + +libpcre_la-pcre_study.lo: pcre_study.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_study.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_study.Tpo -c -o libpcre_la-pcre_study.lo `test -f 'pcre_study.c' || echo '$(srcdir)/'`pcre_study.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_study.Tpo $(DEPDIR)/libpcre_la-pcre_study.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_study.c' object='libpcre_la-pcre_study.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_study.lo `test -f 'pcre_study.c' || echo '$(srcdir)/'`pcre_study.c + +libpcre_la-pcre_tables.lo: pcre_tables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_tables.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_tables.Tpo -c -o libpcre_la-pcre_tables.lo `test -f 'pcre_tables.c' || echo '$(srcdir)/'`pcre_tables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_tables.Tpo $(DEPDIR)/libpcre_la-pcre_tables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_tables.c' object='libpcre_la-pcre_tables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_tables.lo `test -f 'pcre_tables.c' || echo '$(srcdir)/'`pcre_tables.c + +libpcre_la-pcre_ucd.lo: pcre_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_ucd.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_ucd.Tpo -c -o libpcre_la-pcre_ucd.lo `test -f 'pcre_ucd.c' || echo '$(srcdir)/'`pcre_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_ucd.Tpo $(DEPDIR)/libpcre_la-pcre_ucd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_ucd.c' object='libpcre_la-pcre_ucd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_ucd.lo `test -f 'pcre_ucd.c' || echo '$(srcdir)/'`pcre_ucd.c + +libpcre_la-pcre_valid_utf8.lo: pcre_valid_utf8.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_valid_utf8.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_valid_utf8.Tpo -c -o libpcre_la-pcre_valid_utf8.lo `test -f 'pcre_valid_utf8.c' || echo '$(srcdir)/'`pcre_valid_utf8.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_valid_utf8.Tpo $(DEPDIR)/libpcre_la-pcre_valid_utf8.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_valid_utf8.c' object='libpcre_la-pcre_valid_utf8.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_valid_utf8.lo `test -f 'pcre_valid_utf8.c' || echo '$(srcdir)/'`pcre_valid_utf8.c + +libpcre_la-pcre_version.lo: pcre_version.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_version.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_version.Tpo -c -o libpcre_la-pcre_version.lo `test -f 'pcre_version.c' || echo '$(srcdir)/'`pcre_version.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_version.Tpo $(DEPDIR)/libpcre_la-pcre_version.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_version.c' object='libpcre_la-pcre_version.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_version.lo `test -f 'pcre_version.c' || echo '$(srcdir)/'`pcre_version.c + +libpcre_la-pcre_xclass.lo: pcre_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_xclass.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_xclass.Tpo -c -o libpcre_la-pcre_xclass.lo `test -f 'pcre_xclass.c' || echo '$(srcdir)/'`pcre_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_xclass.Tpo $(DEPDIR)/libpcre_la-pcre_xclass.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_xclass.c' object='libpcre_la-pcre_xclass.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_xclass.lo `test -f 'pcre_xclass.c' || echo '$(srcdir)/'`pcre_xclass.c + +libpcre_la-pcre_chartables.lo: pcre_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -MT libpcre_la-pcre_chartables.lo -MD -MP -MF $(DEPDIR)/libpcre_la-pcre_chartables.Tpo -c -o libpcre_la-pcre_chartables.lo `test -f 'pcre_chartables.c' || echo '$(srcdir)/'`pcre_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre_la-pcre_chartables.Tpo $(DEPDIR)/libpcre_la-pcre_chartables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_chartables.c' object='libpcre_la-pcre_chartables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre_la_CFLAGS) $(CFLAGS) -c -o libpcre_la-pcre_chartables.lo `test -f 'pcre_chartables.c' || echo '$(srcdir)/'`pcre_chartables.c + +libpcre16_la-pcre16_byte_order.lo: pcre16_byte_order.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_byte_order.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_byte_order.Tpo -c -o libpcre16_la-pcre16_byte_order.lo `test -f 'pcre16_byte_order.c' || echo '$(srcdir)/'`pcre16_byte_order.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_byte_order.Tpo $(DEPDIR)/libpcre16_la-pcre16_byte_order.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_byte_order.c' object='libpcre16_la-pcre16_byte_order.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_byte_order.lo `test -f 'pcre16_byte_order.c' || echo '$(srcdir)/'`pcre16_byte_order.c + +libpcre16_la-pcre16_chartables.lo: pcre16_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_chartables.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_chartables.Tpo -c -o libpcre16_la-pcre16_chartables.lo `test -f 'pcre16_chartables.c' || echo '$(srcdir)/'`pcre16_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_chartables.Tpo $(DEPDIR)/libpcre16_la-pcre16_chartables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_chartables.c' object='libpcre16_la-pcre16_chartables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_chartables.lo `test -f 'pcre16_chartables.c' || echo '$(srcdir)/'`pcre16_chartables.c + +libpcre16_la-pcre16_compile.lo: pcre16_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_compile.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_compile.Tpo -c -o libpcre16_la-pcre16_compile.lo `test -f 'pcre16_compile.c' || echo '$(srcdir)/'`pcre16_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_compile.Tpo $(DEPDIR)/libpcre16_la-pcre16_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_compile.c' object='libpcre16_la-pcre16_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_compile.lo `test -f 'pcre16_compile.c' || echo '$(srcdir)/'`pcre16_compile.c + +libpcre16_la-pcre16_config.lo: pcre16_config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_config.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_config.Tpo -c -o libpcre16_la-pcre16_config.lo `test -f 'pcre16_config.c' || echo '$(srcdir)/'`pcre16_config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_config.Tpo $(DEPDIR)/libpcre16_la-pcre16_config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_config.c' object='libpcre16_la-pcre16_config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_config.lo `test -f 'pcre16_config.c' || echo '$(srcdir)/'`pcre16_config.c + +libpcre16_la-pcre16_dfa_exec.lo: pcre16_dfa_exec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_dfa_exec.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_dfa_exec.Tpo -c -o libpcre16_la-pcre16_dfa_exec.lo `test -f 'pcre16_dfa_exec.c' || echo '$(srcdir)/'`pcre16_dfa_exec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_dfa_exec.Tpo $(DEPDIR)/libpcre16_la-pcre16_dfa_exec.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_dfa_exec.c' object='libpcre16_la-pcre16_dfa_exec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_dfa_exec.lo `test -f 'pcre16_dfa_exec.c' || echo '$(srcdir)/'`pcre16_dfa_exec.c + +libpcre16_la-pcre16_exec.lo: pcre16_exec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_exec.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_exec.Tpo -c -o libpcre16_la-pcre16_exec.lo `test -f 'pcre16_exec.c' || echo '$(srcdir)/'`pcre16_exec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_exec.Tpo $(DEPDIR)/libpcre16_la-pcre16_exec.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_exec.c' object='libpcre16_la-pcre16_exec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_exec.lo `test -f 'pcre16_exec.c' || echo '$(srcdir)/'`pcre16_exec.c + +libpcre16_la-pcre16_fullinfo.lo: pcre16_fullinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_fullinfo.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_fullinfo.Tpo -c -o libpcre16_la-pcre16_fullinfo.lo `test -f 'pcre16_fullinfo.c' || echo '$(srcdir)/'`pcre16_fullinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_fullinfo.Tpo $(DEPDIR)/libpcre16_la-pcre16_fullinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_fullinfo.c' object='libpcre16_la-pcre16_fullinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_fullinfo.lo `test -f 'pcre16_fullinfo.c' || echo '$(srcdir)/'`pcre16_fullinfo.c + +libpcre16_la-pcre16_get.lo: pcre16_get.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_get.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_get.Tpo -c -o libpcre16_la-pcre16_get.lo `test -f 'pcre16_get.c' || echo '$(srcdir)/'`pcre16_get.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_get.Tpo $(DEPDIR)/libpcre16_la-pcre16_get.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_get.c' object='libpcre16_la-pcre16_get.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_get.lo `test -f 'pcre16_get.c' || echo '$(srcdir)/'`pcre16_get.c + +libpcre16_la-pcre16_globals.lo: pcre16_globals.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_globals.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_globals.Tpo -c -o libpcre16_la-pcre16_globals.lo `test -f 'pcre16_globals.c' || echo '$(srcdir)/'`pcre16_globals.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_globals.Tpo $(DEPDIR)/libpcre16_la-pcre16_globals.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_globals.c' object='libpcre16_la-pcre16_globals.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_globals.lo `test -f 'pcre16_globals.c' || echo '$(srcdir)/'`pcre16_globals.c + +libpcre16_la-pcre16_jit_compile.lo: pcre16_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_jit_compile.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_jit_compile.Tpo -c -o libpcre16_la-pcre16_jit_compile.lo `test -f 'pcre16_jit_compile.c' || echo '$(srcdir)/'`pcre16_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_jit_compile.Tpo $(DEPDIR)/libpcre16_la-pcre16_jit_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_jit_compile.c' object='libpcre16_la-pcre16_jit_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_jit_compile.lo `test -f 'pcre16_jit_compile.c' || echo '$(srcdir)/'`pcre16_jit_compile.c + +libpcre16_la-pcre16_maketables.lo: pcre16_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_maketables.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_maketables.Tpo -c -o libpcre16_la-pcre16_maketables.lo `test -f 'pcre16_maketables.c' || echo '$(srcdir)/'`pcre16_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_maketables.Tpo $(DEPDIR)/libpcre16_la-pcre16_maketables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_maketables.c' object='libpcre16_la-pcre16_maketables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_maketables.lo `test -f 'pcre16_maketables.c' || echo '$(srcdir)/'`pcre16_maketables.c + +libpcre16_la-pcre16_newline.lo: pcre16_newline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_newline.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_newline.Tpo -c -o libpcre16_la-pcre16_newline.lo `test -f 'pcre16_newline.c' || echo '$(srcdir)/'`pcre16_newline.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_newline.Tpo $(DEPDIR)/libpcre16_la-pcre16_newline.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_newline.c' object='libpcre16_la-pcre16_newline.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_newline.lo `test -f 'pcre16_newline.c' || echo '$(srcdir)/'`pcre16_newline.c + +libpcre16_la-pcre16_ord2utf16.lo: pcre16_ord2utf16.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_ord2utf16.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_ord2utf16.Tpo -c -o libpcre16_la-pcre16_ord2utf16.lo `test -f 'pcre16_ord2utf16.c' || echo '$(srcdir)/'`pcre16_ord2utf16.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_ord2utf16.Tpo $(DEPDIR)/libpcre16_la-pcre16_ord2utf16.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_ord2utf16.c' object='libpcre16_la-pcre16_ord2utf16.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_ord2utf16.lo `test -f 'pcre16_ord2utf16.c' || echo '$(srcdir)/'`pcre16_ord2utf16.c + +libpcre16_la-pcre16_refcount.lo: pcre16_refcount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_refcount.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_refcount.Tpo -c -o libpcre16_la-pcre16_refcount.lo `test -f 'pcre16_refcount.c' || echo '$(srcdir)/'`pcre16_refcount.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_refcount.Tpo $(DEPDIR)/libpcre16_la-pcre16_refcount.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_refcount.c' object='libpcre16_la-pcre16_refcount.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_refcount.lo `test -f 'pcre16_refcount.c' || echo '$(srcdir)/'`pcre16_refcount.c + +libpcre16_la-pcre16_string_utils.lo: pcre16_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_string_utils.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_string_utils.Tpo -c -o libpcre16_la-pcre16_string_utils.lo `test -f 'pcre16_string_utils.c' || echo '$(srcdir)/'`pcre16_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_string_utils.Tpo $(DEPDIR)/libpcre16_la-pcre16_string_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_string_utils.c' object='libpcre16_la-pcre16_string_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_string_utils.lo `test -f 'pcre16_string_utils.c' || echo '$(srcdir)/'`pcre16_string_utils.c + +libpcre16_la-pcre16_study.lo: pcre16_study.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_study.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_study.Tpo -c -o libpcre16_la-pcre16_study.lo `test -f 'pcre16_study.c' || echo '$(srcdir)/'`pcre16_study.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_study.Tpo $(DEPDIR)/libpcre16_la-pcre16_study.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_study.c' object='libpcre16_la-pcre16_study.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_study.lo `test -f 'pcre16_study.c' || echo '$(srcdir)/'`pcre16_study.c + +libpcre16_la-pcre16_tables.lo: pcre16_tables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_tables.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_tables.Tpo -c -o libpcre16_la-pcre16_tables.lo `test -f 'pcre16_tables.c' || echo '$(srcdir)/'`pcre16_tables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_tables.Tpo $(DEPDIR)/libpcre16_la-pcre16_tables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_tables.c' object='libpcre16_la-pcre16_tables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_tables.lo `test -f 'pcre16_tables.c' || echo '$(srcdir)/'`pcre16_tables.c + +libpcre16_la-pcre16_ucd.lo: pcre16_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_ucd.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_ucd.Tpo -c -o libpcre16_la-pcre16_ucd.lo `test -f 'pcre16_ucd.c' || echo '$(srcdir)/'`pcre16_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_ucd.Tpo $(DEPDIR)/libpcre16_la-pcre16_ucd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_ucd.c' object='libpcre16_la-pcre16_ucd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_ucd.lo `test -f 'pcre16_ucd.c' || echo '$(srcdir)/'`pcre16_ucd.c + +libpcre16_la-pcre16_utf16_utils.lo: pcre16_utf16_utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_utf16_utils.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_utf16_utils.Tpo -c -o libpcre16_la-pcre16_utf16_utils.lo `test -f 'pcre16_utf16_utils.c' || echo '$(srcdir)/'`pcre16_utf16_utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_utf16_utils.Tpo $(DEPDIR)/libpcre16_la-pcre16_utf16_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_utf16_utils.c' object='libpcre16_la-pcre16_utf16_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_utf16_utils.lo `test -f 'pcre16_utf16_utils.c' || echo '$(srcdir)/'`pcre16_utf16_utils.c + +libpcre16_la-pcre16_valid_utf16.lo: pcre16_valid_utf16.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_valid_utf16.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_valid_utf16.Tpo -c -o libpcre16_la-pcre16_valid_utf16.lo `test -f 'pcre16_valid_utf16.c' || echo '$(srcdir)/'`pcre16_valid_utf16.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_valid_utf16.Tpo $(DEPDIR)/libpcre16_la-pcre16_valid_utf16.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_valid_utf16.c' object='libpcre16_la-pcre16_valid_utf16.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_valid_utf16.lo `test -f 'pcre16_valid_utf16.c' || echo '$(srcdir)/'`pcre16_valid_utf16.c + +libpcre16_la-pcre16_version.lo: pcre16_version.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_version.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_version.Tpo -c -o libpcre16_la-pcre16_version.lo `test -f 'pcre16_version.c' || echo '$(srcdir)/'`pcre16_version.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_version.Tpo $(DEPDIR)/libpcre16_la-pcre16_version.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_version.c' object='libpcre16_la-pcre16_version.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_version.lo `test -f 'pcre16_version.c' || echo '$(srcdir)/'`pcre16_version.c + +libpcre16_la-pcre16_xclass.lo: pcre16_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre16_xclass.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre16_xclass.Tpo -c -o libpcre16_la-pcre16_xclass.lo `test -f 'pcre16_xclass.c' || echo '$(srcdir)/'`pcre16_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre16_xclass.Tpo $(DEPDIR)/libpcre16_la-pcre16_xclass.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_xclass.c' object='libpcre16_la-pcre16_xclass.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre16_xclass.lo `test -f 'pcre16_xclass.c' || echo '$(srcdir)/'`pcre16_xclass.c + +libpcre16_la-pcre_chartables.lo: pcre_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -MT libpcre16_la-pcre_chartables.lo -MD -MP -MF $(DEPDIR)/libpcre16_la-pcre_chartables.Tpo -c -o libpcre16_la-pcre_chartables.lo `test -f 'pcre_chartables.c' || echo '$(srcdir)/'`pcre_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre16_la-pcre_chartables.Tpo $(DEPDIR)/libpcre16_la-pcre_chartables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_chartables.c' object='libpcre16_la-pcre_chartables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre16_la_CFLAGS) $(CFLAGS) -c -o libpcre16_la-pcre_chartables.lo `test -f 'pcre_chartables.c' || echo '$(srcdir)/'`pcre_chartables.c + +libpcre32_la-pcre32_byte_order.lo: pcre32_byte_order.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_byte_order.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_byte_order.Tpo -c -o libpcre32_la-pcre32_byte_order.lo `test -f 'pcre32_byte_order.c' || echo '$(srcdir)/'`pcre32_byte_order.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_byte_order.Tpo $(DEPDIR)/libpcre32_la-pcre32_byte_order.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_byte_order.c' object='libpcre32_la-pcre32_byte_order.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_byte_order.lo `test -f 'pcre32_byte_order.c' || echo '$(srcdir)/'`pcre32_byte_order.c + +libpcre32_la-pcre32_chartables.lo: pcre32_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_chartables.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_chartables.Tpo -c -o libpcre32_la-pcre32_chartables.lo `test -f 'pcre32_chartables.c' || echo '$(srcdir)/'`pcre32_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_chartables.Tpo $(DEPDIR)/libpcre32_la-pcre32_chartables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_chartables.c' object='libpcre32_la-pcre32_chartables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_chartables.lo `test -f 'pcre32_chartables.c' || echo '$(srcdir)/'`pcre32_chartables.c + +libpcre32_la-pcre32_compile.lo: pcre32_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_compile.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_compile.Tpo -c -o libpcre32_la-pcre32_compile.lo `test -f 'pcre32_compile.c' || echo '$(srcdir)/'`pcre32_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_compile.Tpo $(DEPDIR)/libpcre32_la-pcre32_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_compile.c' object='libpcre32_la-pcre32_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_compile.lo `test -f 'pcre32_compile.c' || echo '$(srcdir)/'`pcre32_compile.c + +libpcre32_la-pcre32_config.lo: pcre32_config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_config.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_config.Tpo -c -o libpcre32_la-pcre32_config.lo `test -f 'pcre32_config.c' || echo '$(srcdir)/'`pcre32_config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_config.Tpo $(DEPDIR)/libpcre32_la-pcre32_config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_config.c' object='libpcre32_la-pcre32_config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_config.lo `test -f 'pcre32_config.c' || echo '$(srcdir)/'`pcre32_config.c + +libpcre32_la-pcre32_dfa_exec.lo: pcre32_dfa_exec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_dfa_exec.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_dfa_exec.Tpo -c -o libpcre32_la-pcre32_dfa_exec.lo `test -f 'pcre32_dfa_exec.c' || echo '$(srcdir)/'`pcre32_dfa_exec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_dfa_exec.Tpo $(DEPDIR)/libpcre32_la-pcre32_dfa_exec.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_dfa_exec.c' object='libpcre32_la-pcre32_dfa_exec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_dfa_exec.lo `test -f 'pcre32_dfa_exec.c' || echo '$(srcdir)/'`pcre32_dfa_exec.c + +libpcre32_la-pcre32_exec.lo: pcre32_exec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_exec.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_exec.Tpo -c -o libpcre32_la-pcre32_exec.lo `test -f 'pcre32_exec.c' || echo '$(srcdir)/'`pcre32_exec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_exec.Tpo $(DEPDIR)/libpcre32_la-pcre32_exec.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_exec.c' object='libpcre32_la-pcre32_exec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_exec.lo `test -f 'pcre32_exec.c' || echo '$(srcdir)/'`pcre32_exec.c + +libpcre32_la-pcre32_fullinfo.lo: pcre32_fullinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_fullinfo.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_fullinfo.Tpo -c -o libpcre32_la-pcre32_fullinfo.lo `test -f 'pcre32_fullinfo.c' || echo '$(srcdir)/'`pcre32_fullinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_fullinfo.Tpo $(DEPDIR)/libpcre32_la-pcre32_fullinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_fullinfo.c' object='libpcre32_la-pcre32_fullinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_fullinfo.lo `test -f 'pcre32_fullinfo.c' || echo '$(srcdir)/'`pcre32_fullinfo.c + +libpcre32_la-pcre32_get.lo: pcre32_get.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_get.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_get.Tpo -c -o libpcre32_la-pcre32_get.lo `test -f 'pcre32_get.c' || echo '$(srcdir)/'`pcre32_get.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_get.Tpo $(DEPDIR)/libpcre32_la-pcre32_get.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_get.c' object='libpcre32_la-pcre32_get.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_get.lo `test -f 'pcre32_get.c' || echo '$(srcdir)/'`pcre32_get.c + +libpcre32_la-pcre32_globals.lo: pcre32_globals.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_globals.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_globals.Tpo -c -o libpcre32_la-pcre32_globals.lo `test -f 'pcre32_globals.c' || echo '$(srcdir)/'`pcre32_globals.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_globals.Tpo $(DEPDIR)/libpcre32_la-pcre32_globals.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_globals.c' object='libpcre32_la-pcre32_globals.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_globals.lo `test -f 'pcre32_globals.c' || echo '$(srcdir)/'`pcre32_globals.c + +libpcre32_la-pcre32_jit_compile.lo: pcre32_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_jit_compile.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_jit_compile.Tpo -c -o libpcre32_la-pcre32_jit_compile.lo `test -f 'pcre32_jit_compile.c' || echo '$(srcdir)/'`pcre32_jit_compile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_jit_compile.Tpo $(DEPDIR)/libpcre32_la-pcre32_jit_compile.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_jit_compile.c' object='libpcre32_la-pcre32_jit_compile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_jit_compile.lo `test -f 'pcre32_jit_compile.c' || echo '$(srcdir)/'`pcre32_jit_compile.c + +libpcre32_la-pcre32_maketables.lo: pcre32_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_maketables.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_maketables.Tpo -c -o libpcre32_la-pcre32_maketables.lo `test -f 'pcre32_maketables.c' || echo '$(srcdir)/'`pcre32_maketables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_maketables.Tpo $(DEPDIR)/libpcre32_la-pcre32_maketables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_maketables.c' object='libpcre32_la-pcre32_maketables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_maketables.lo `test -f 'pcre32_maketables.c' || echo '$(srcdir)/'`pcre32_maketables.c + +libpcre32_la-pcre32_newline.lo: pcre32_newline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_newline.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_newline.Tpo -c -o libpcre32_la-pcre32_newline.lo `test -f 'pcre32_newline.c' || echo '$(srcdir)/'`pcre32_newline.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_newline.Tpo $(DEPDIR)/libpcre32_la-pcre32_newline.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_newline.c' object='libpcre32_la-pcre32_newline.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_newline.lo `test -f 'pcre32_newline.c' || echo '$(srcdir)/'`pcre32_newline.c + +libpcre32_la-pcre32_ord2utf32.lo: pcre32_ord2utf32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_ord2utf32.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_ord2utf32.Tpo -c -o libpcre32_la-pcre32_ord2utf32.lo `test -f 'pcre32_ord2utf32.c' || echo '$(srcdir)/'`pcre32_ord2utf32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_ord2utf32.Tpo $(DEPDIR)/libpcre32_la-pcre32_ord2utf32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_ord2utf32.c' object='libpcre32_la-pcre32_ord2utf32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_ord2utf32.lo `test -f 'pcre32_ord2utf32.c' || echo '$(srcdir)/'`pcre32_ord2utf32.c + +libpcre32_la-pcre32_refcount.lo: pcre32_refcount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_refcount.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_refcount.Tpo -c -o libpcre32_la-pcre32_refcount.lo `test -f 'pcre32_refcount.c' || echo '$(srcdir)/'`pcre32_refcount.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_refcount.Tpo $(DEPDIR)/libpcre32_la-pcre32_refcount.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_refcount.c' object='libpcre32_la-pcre32_refcount.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_refcount.lo `test -f 'pcre32_refcount.c' || echo '$(srcdir)/'`pcre32_refcount.c + +libpcre32_la-pcre32_string_utils.lo: pcre32_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_string_utils.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_string_utils.Tpo -c -o libpcre32_la-pcre32_string_utils.lo `test -f 'pcre32_string_utils.c' || echo '$(srcdir)/'`pcre32_string_utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_string_utils.Tpo $(DEPDIR)/libpcre32_la-pcre32_string_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_string_utils.c' object='libpcre32_la-pcre32_string_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_string_utils.lo `test -f 'pcre32_string_utils.c' || echo '$(srcdir)/'`pcre32_string_utils.c + +libpcre32_la-pcre32_study.lo: pcre32_study.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_study.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_study.Tpo -c -o libpcre32_la-pcre32_study.lo `test -f 'pcre32_study.c' || echo '$(srcdir)/'`pcre32_study.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_study.Tpo $(DEPDIR)/libpcre32_la-pcre32_study.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_study.c' object='libpcre32_la-pcre32_study.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_study.lo `test -f 'pcre32_study.c' || echo '$(srcdir)/'`pcre32_study.c + +libpcre32_la-pcre32_tables.lo: pcre32_tables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_tables.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_tables.Tpo -c -o libpcre32_la-pcre32_tables.lo `test -f 'pcre32_tables.c' || echo '$(srcdir)/'`pcre32_tables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_tables.Tpo $(DEPDIR)/libpcre32_la-pcre32_tables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_tables.c' object='libpcre32_la-pcre32_tables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_tables.lo `test -f 'pcre32_tables.c' || echo '$(srcdir)/'`pcre32_tables.c + +libpcre32_la-pcre32_ucd.lo: pcre32_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_ucd.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_ucd.Tpo -c -o libpcre32_la-pcre32_ucd.lo `test -f 'pcre32_ucd.c' || echo '$(srcdir)/'`pcre32_ucd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_ucd.Tpo $(DEPDIR)/libpcre32_la-pcre32_ucd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_ucd.c' object='libpcre32_la-pcre32_ucd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_ucd.lo `test -f 'pcre32_ucd.c' || echo '$(srcdir)/'`pcre32_ucd.c + +libpcre32_la-pcre32_utf32_utils.lo: pcre32_utf32_utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_utf32_utils.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_utf32_utils.Tpo -c -o libpcre32_la-pcre32_utf32_utils.lo `test -f 'pcre32_utf32_utils.c' || echo '$(srcdir)/'`pcre32_utf32_utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_utf32_utils.Tpo $(DEPDIR)/libpcre32_la-pcre32_utf32_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_utf32_utils.c' object='libpcre32_la-pcre32_utf32_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_utf32_utils.lo `test -f 'pcre32_utf32_utils.c' || echo '$(srcdir)/'`pcre32_utf32_utils.c + +libpcre32_la-pcre32_valid_utf32.lo: pcre32_valid_utf32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_valid_utf32.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_valid_utf32.Tpo -c -o libpcre32_la-pcre32_valid_utf32.lo `test -f 'pcre32_valid_utf32.c' || echo '$(srcdir)/'`pcre32_valid_utf32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_valid_utf32.Tpo $(DEPDIR)/libpcre32_la-pcre32_valid_utf32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_valid_utf32.c' object='libpcre32_la-pcre32_valid_utf32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_valid_utf32.lo `test -f 'pcre32_valid_utf32.c' || echo '$(srcdir)/'`pcre32_valid_utf32.c + +libpcre32_la-pcre32_version.lo: pcre32_version.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_version.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_version.Tpo -c -o libpcre32_la-pcre32_version.lo `test -f 'pcre32_version.c' || echo '$(srcdir)/'`pcre32_version.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_version.Tpo $(DEPDIR)/libpcre32_la-pcre32_version.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_version.c' object='libpcre32_la-pcre32_version.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_version.lo `test -f 'pcre32_version.c' || echo '$(srcdir)/'`pcre32_version.c + +libpcre32_la-pcre32_xclass.lo: pcre32_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre32_xclass.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre32_xclass.Tpo -c -o libpcre32_la-pcre32_xclass.lo `test -f 'pcre32_xclass.c' || echo '$(srcdir)/'`pcre32_xclass.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre32_xclass.Tpo $(DEPDIR)/libpcre32_la-pcre32_xclass.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_xclass.c' object='libpcre32_la-pcre32_xclass.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre32_xclass.lo `test -f 'pcre32_xclass.c' || echo '$(srcdir)/'`pcre32_xclass.c + +libpcre32_la-pcre_chartables.lo: pcre_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -MT libpcre32_la-pcre_chartables.lo -MD -MP -MF $(DEPDIR)/libpcre32_la-pcre_chartables.Tpo -c -o libpcre32_la-pcre_chartables.lo `test -f 'pcre_chartables.c' || echo '$(srcdir)/'`pcre_chartables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcre32_la-pcre_chartables.Tpo $(DEPDIR)/libpcre32_la-pcre_chartables.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_chartables.c' object='libpcre32_la-pcre_chartables.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre32_la_CFLAGS) $(CFLAGS) -c -o libpcre32_la-pcre_chartables.lo `test -f 'pcre_chartables.c' || echo '$(srcdir)/'`pcre_chartables.c + +libpcreposix_la-pcreposix.lo: pcreposix.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcreposix_la_CFLAGS) $(CFLAGS) -MT libpcreposix_la-pcreposix.lo -MD -MP -MF $(DEPDIR)/libpcreposix_la-pcreposix.Tpo -c -o libpcreposix_la-pcreposix.lo `test -f 'pcreposix.c' || echo '$(srcdir)/'`pcreposix.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcreposix_la-pcreposix.Tpo $(DEPDIR)/libpcreposix_la-pcreposix.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcreposix.c' object='libpcreposix_la-pcreposix.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcreposix_la_CFLAGS) $(CFLAGS) -c -o libpcreposix_la-pcreposix.lo `test -f 'pcreposix.c' || echo '$(srcdir)/'`pcreposix.c + +pcre_jit_test-pcre_jit_test.o: pcre_jit_test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_jit_test_CFLAGS) $(CFLAGS) -MT pcre_jit_test-pcre_jit_test.o -MD -MP -MF $(DEPDIR)/pcre_jit_test-pcre_jit_test.Tpo -c -o pcre_jit_test-pcre_jit_test.o `test -f 'pcre_jit_test.c' || echo '$(srcdir)/'`pcre_jit_test.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcre_jit_test-pcre_jit_test.Tpo $(DEPDIR)/pcre_jit_test-pcre_jit_test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_jit_test.c' object='pcre_jit_test-pcre_jit_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_jit_test_CFLAGS) $(CFLAGS) -c -o pcre_jit_test-pcre_jit_test.o `test -f 'pcre_jit_test.c' || echo '$(srcdir)/'`pcre_jit_test.c + +pcre_jit_test-pcre_jit_test.obj: pcre_jit_test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_jit_test_CFLAGS) $(CFLAGS) -MT pcre_jit_test-pcre_jit_test.obj -MD -MP -MF $(DEPDIR)/pcre_jit_test-pcre_jit_test.Tpo -c -o pcre_jit_test-pcre_jit_test.obj `if test -f 'pcre_jit_test.c'; then $(CYGPATH_W) 'pcre_jit_test.c'; else $(CYGPATH_W) '$(srcdir)/pcre_jit_test.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcre_jit_test-pcre_jit_test.Tpo $(DEPDIR)/pcre_jit_test-pcre_jit_test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_jit_test.c' object='pcre_jit_test-pcre_jit_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_jit_test_CFLAGS) $(CFLAGS) -c -o pcre_jit_test-pcre_jit_test.obj `if test -f 'pcre_jit_test.c'; then $(CYGPATH_W) 'pcre_jit_test.c'; else $(CYGPATH_W) '$(srcdir)/pcre_jit_test.c'; fi` + +pcregrep-pcregrep.o: pcregrep.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcregrep_CFLAGS) $(CFLAGS) -MT pcregrep-pcregrep.o -MD -MP -MF $(DEPDIR)/pcregrep-pcregrep.Tpo -c -o pcregrep-pcregrep.o `test -f 'pcregrep.c' || echo '$(srcdir)/'`pcregrep.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcregrep-pcregrep.Tpo $(DEPDIR)/pcregrep-pcregrep.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcregrep.c' object='pcregrep-pcregrep.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcregrep_CFLAGS) $(CFLAGS) -c -o pcregrep-pcregrep.o `test -f 'pcregrep.c' || echo '$(srcdir)/'`pcregrep.c + +pcregrep-pcregrep.obj: pcregrep.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcregrep_CFLAGS) $(CFLAGS) -MT pcregrep-pcregrep.obj -MD -MP -MF $(DEPDIR)/pcregrep-pcregrep.Tpo -c -o pcregrep-pcregrep.obj `if test -f 'pcregrep.c'; then $(CYGPATH_W) 'pcregrep.c'; else $(CYGPATH_W) '$(srcdir)/pcregrep.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcregrep-pcregrep.Tpo $(DEPDIR)/pcregrep-pcregrep.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcregrep.c' object='pcregrep-pcregrep.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcregrep_CFLAGS) $(CFLAGS) -c -o pcregrep-pcregrep.obj `if test -f 'pcregrep.c'; then $(CYGPATH_W) 'pcregrep.c'; else $(CYGPATH_W) '$(srcdir)/pcregrep.c'; fi` + +pcretest-pcretest.o: pcretest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -MT pcretest-pcretest.o -MD -MP -MF $(DEPDIR)/pcretest-pcretest.Tpo -c -o pcretest-pcretest.o `test -f 'pcretest.c' || echo '$(srcdir)/'`pcretest.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcretest-pcretest.Tpo $(DEPDIR)/pcretest-pcretest.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcretest.c' object='pcretest-pcretest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -c -o pcretest-pcretest.o `test -f 'pcretest.c' || echo '$(srcdir)/'`pcretest.c + +pcretest-pcretest.obj: pcretest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -MT pcretest-pcretest.obj -MD -MP -MF $(DEPDIR)/pcretest-pcretest.Tpo -c -o pcretest-pcretest.obj `if test -f 'pcretest.c'; then $(CYGPATH_W) 'pcretest.c'; else $(CYGPATH_W) '$(srcdir)/pcretest.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcretest-pcretest.Tpo $(DEPDIR)/pcretest-pcretest.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcretest.c' object='pcretest-pcretest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -c -o pcretest-pcretest.obj `if test -f 'pcretest.c'; then $(CYGPATH_W) 'pcretest.c'; else $(CYGPATH_W) '$(srcdir)/pcretest.c'; fi` + +pcretest-pcre_printint.o: pcre_printint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -MT pcretest-pcre_printint.o -MD -MP -MF $(DEPDIR)/pcretest-pcre_printint.Tpo -c -o pcretest-pcre_printint.o `test -f 'pcre_printint.c' || echo '$(srcdir)/'`pcre_printint.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcretest-pcre_printint.Tpo $(DEPDIR)/pcretest-pcre_printint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_printint.c' object='pcretest-pcre_printint.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -c -o pcretest-pcre_printint.o `test -f 'pcre_printint.c' || echo '$(srcdir)/'`pcre_printint.c + +pcretest-pcre_printint.obj: pcre_printint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -MT pcretest-pcre_printint.obj -MD -MP -MF $(DEPDIR)/pcretest-pcre_printint.Tpo -c -o pcretest-pcre_printint.obj `if test -f 'pcre_printint.c'; then $(CYGPATH_W) 'pcre_printint.c'; else $(CYGPATH_W) '$(srcdir)/pcre_printint.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcretest-pcre_printint.Tpo $(DEPDIR)/pcretest-pcre_printint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre_printint.c' object='pcretest-pcre_printint.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -c -o pcretest-pcre_printint.obj `if test -f 'pcre_printint.c'; then $(CYGPATH_W) 'pcre_printint.c'; else $(CYGPATH_W) '$(srcdir)/pcre_printint.c'; fi` + +pcretest-pcre16_printint.o: pcre16_printint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -MT pcretest-pcre16_printint.o -MD -MP -MF $(DEPDIR)/pcretest-pcre16_printint.Tpo -c -o pcretest-pcre16_printint.o `test -f 'pcre16_printint.c' || echo '$(srcdir)/'`pcre16_printint.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcretest-pcre16_printint.Tpo $(DEPDIR)/pcretest-pcre16_printint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_printint.c' object='pcretest-pcre16_printint.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -c -o pcretest-pcre16_printint.o `test -f 'pcre16_printint.c' || echo '$(srcdir)/'`pcre16_printint.c + +pcretest-pcre16_printint.obj: pcre16_printint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -MT pcretest-pcre16_printint.obj -MD -MP -MF $(DEPDIR)/pcretest-pcre16_printint.Tpo -c -o pcretest-pcre16_printint.obj `if test -f 'pcre16_printint.c'; then $(CYGPATH_W) 'pcre16_printint.c'; else $(CYGPATH_W) '$(srcdir)/pcre16_printint.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcretest-pcre16_printint.Tpo $(DEPDIR)/pcretest-pcre16_printint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre16_printint.c' object='pcretest-pcre16_printint.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -c -o pcretest-pcre16_printint.obj `if test -f 'pcre16_printint.c'; then $(CYGPATH_W) 'pcre16_printint.c'; else $(CYGPATH_W) '$(srcdir)/pcre16_printint.c'; fi` + +pcretest-pcre32_printint.o: pcre32_printint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -MT pcretest-pcre32_printint.o -MD -MP -MF $(DEPDIR)/pcretest-pcre32_printint.Tpo -c -o pcretest-pcre32_printint.o `test -f 'pcre32_printint.c' || echo '$(srcdir)/'`pcre32_printint.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcretest-pcre32_printint.Tpo $(DEPDIR)/pcretest-pcre32_printint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_printint.c' object='pcretest-pcre32_printint.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -c -o pcretest-pcre32_printint.o `test -f 'pcre32_printint.c' || echo '$(srcdir)/'`pcre32_printint.c + +pcretest-pcre32_printint.obj: pcre32_printint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -MT pcretest-pcre32_printint.obj -MD -MP -MF $(DEPDIR)/pcretest-pcre32_printint.Tpo -c -o pcretest-pcre32_printint.obj `if test -f 'pcre32_printint.c'; then $(CYGPATH_W) 'pcre32_printint.c'; else $(CYGPATH_W) '$(srcdir)/pcre32_printint.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcretest-pcre32_printint.Tpo $(DEPDIR)/pcretest-pcre32_printint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcre32_printint.c' object='pcretest-pcre32_printint.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcretest_CFLAGS) $(CFLAGS) -c -o pcretest-pcre32_printint.obj `if test -f 'pcre32_printint.c'; then $(CYGPATH_W) 'pcre32_printint.c'; else $(CYGPATH_W) '$(srcdir)/pcre32_printint.c'; fi` + +.cc.o: +@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 +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@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 +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@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 +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +libpcrecpp_la-pcrecpp.lo: pcrecpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcrecpp_la_CXXFLAGS) $(CXXFLAGS) -MT libpcrecpp_la-pcrecpp.lo -MD -MP -MF $(DEPDIR)/libpcrecpp_la-pcrecpp.Tpo -c -o libpcrecpp_la-pcrecpp.lo `test -f 'pcrecpp.cc' || echo '$(srcdir)/'`pcrecpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcrecpp_la-pcrecpp.Tpo $(DEPDIR)/libpcrecpp_la-pcrecpp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pcrecpp.cc' object='libpcrecpp_la-pcrecpp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcrecpp_la_CXXFLAGS) $(CXXFLAGS) -c -o libpcrecpp_la-pcrecpp.lo `test -f 'pcrecpp.cc' || echo '$(srcdir)/'`pcrecpp.cc + +libpcrecpp_la-pcre_scanner.lo: pcre_scanner.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcrecpp_la_CXXFLAGS) $(CXXFLAGS) -MT libpcrecpp_la-pcre_scanner.lo -MD -MP -MF $(DEPDIR)/libpcrecpp_la-pcre_scanner.Tpo -c -o libpcrecpp_la-pcre_scanner.lo `test -f 'pcre_scanner.cc' || echo '$(srcdir)/'`pcre_scanner.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcrecpp_la-pcre_scanner.Tpo $(DEPDIR)/libpcrecpp_la-pcre_scanner.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pcre_scanner.cc' object='libpcrecpp_la-pcre_scanner.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcrecpp_la_CXXFLAGS) $(CXXFLAGS) -c -o libpcrecpp_la-pcre_scanner.lo `test -f 'pcre_scanner.cc' || echo '$(srcdir)/'`pcre_scanner.cc + +libpcrecpp_la-pcre_stringpiece.lo: pcre_stringpiece.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcrecpp_la_CXXFLAGS) $(CXXFLAGS) -MT libpcrecpp_la-pcre_stringpiece.lo -MD -MP -MF $(DEPDIR)/libpcrecpp_la-pcre_stringpiece.Tpo -c -o libpcrecpp_la-pcre_stringpiece.lo `test -f 'pcre_stringpiece.cc' || echo '$(srcdir)/'`pcre_stringpiece.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpcrecpp_la-pcre_stringpiece.Tpo $(DEPDIR)/libpcrecpp_la-pcre_stringpiece.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pcre_stringpiece.cc' object='libpcrecpp_la-pcre_stringpiece.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcrecpp_la_CXXFLAGS) $(CXXFLAGS) -c -o libpcrecpp_la-pcre_stringpiece.lo `test -f 'pcre_stringpiece.cc' || echo '$(srcdir)/'`pcre_stringpiece.cc + +pcre_scanner_unittest-pcre_scanner_unittest.o: pcre_scanner_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_scanner_unittest_CXXFLAGS) $(CXXFLAGS) -MT pcre_scanner_unittest-pcre_scanner_unittest.o -MD -MP -MF $(DEPDIR)/pcre_scanner_unittest-pcre_scanner_unittest.Tpo -c -o pcre_scanner_unittest-pcre_scanner_unittest.o `test -f 'pcre_scanner_unittest.cc' || echo '$(srcdir)/'`pcre_scanner_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcre_scanner_unittest-pcre_scanner_unittest.Tpo $(DEPDIR)/pcre_scanner_unittest-pcre_scanner_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pcre_scanner_unittest.cc' object='pcre_scanner_unittest-pcre_scanner_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_scanner_unittest_CXXFLAGS) $(CXXFLAGS) -c -o pcre_scanner_unittest-pcre_scanner_unittest.o `test -f 'pcre_scanner_unittest.cc' || echo '$(srcdir)/'`pcre_scanner_unittest.cc + +pcre_scanner_unittest-pcre_scanner_unittest.obj: pcre_scanner_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_scanner_unittest_CXXFLAGS) $(CXXFLAGS) -MT pcre_scanner_unittest-pcre_scanner_unittest.obj -MD -MP -MF $(DEPDIR)/pcre_scanner_unittest-pcre_scanner_unittest.Tpo -c -o pcre_scanner_unittest-pcre_scanner_unittest.obj `if test -f 'pcre_scanner_unittest.cc'; then $(CYGPATH_W) 'pcre_scanner_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/pcre_scanner_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcre_scanner_unittest-pcre_scanner_unittest.Tpo $(DEPDIR)/pcre_scanner_unittest-pcre_scanner_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pcre_scanner_unittest.cc' object='pcre_scanner_unittest-pcre_scanner_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_scanner_unittest_CXXFLAGS) $(CXXFLAGS) -c -o pcre_scanner_unittest-pcre_scanner_unittest.obj `if test -f 'pcre_scanner_unittest.cc'; then $(CYGPATH_W) 'pcre_scanner_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/pcre_scanner_unittest.cc'; fi` + +pcre_stringpiece_unittest-pcre_stringpiece_unittest.o: pcre_stringpiece_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_stringpiece_unittest_CXXFLAGS) $(CXXFLAGS) -MT pcre_stringpiece_unittest-pcre_stringpiece_unittest.o -MD -MP -MF $(DEPDIR)/pcre_stringpiece_unittest-pcre_stringpiece_unittest.Tpo -c -o pcre_stringpiece_unittest-pcre_stringpiece_unittest.o `test -f 'pcre_stringpiece_unittest.cc' || echo '$(srcdir)/'`pcre_stringpiece_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcre_stringpiece_unittest-pcre_stringpiece_unittest.Tpo $(DEPDIR)/pcre_stringpiece_unittest-pcre_stringpiece_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pcre_stringpiece_unittest.cc' object='pcre_stringpiece_unittest-pcre_stringpiece_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_stringpiece_unittest_CXXFLAGS) $(CXXFLAGS) -c -o pcre_stringpiece_unittest-pcre_stringpiece_unittest.o `test -f 'pcre_stringpiece_unittest.cc' || echo '$(srcdir)/'`pcre_stringpiece_unittest.cc + +pcre_stringpiece_unittest-pcre_stringpiece_unittest.obj: pcre_stringpiece_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_stringpiece_unittest_CXXFLAGS) $(CXXFLAGS) -MT pcre_stringpiece_unittest-pcre_stringpiece_unittest.obj -MD -MP -MF $(DEPDIR)/pcre_stringpiece_unittest-pcre_stringpiece_unittest.Tpo -c -o pcre_stringpiece_unittest-pcre_stringpiece_unittest.obj `if test -f 'pcre_stringpiece_unittest.cc'; then $(CYGPATH_W) 'pcre_stringpiece_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/pcre_stringpiece_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcre_stringpiece_unittest-pcre_stringpiece_unittest.Tpo $(DEPDIR)/pcre_stringpiece_unittest-pcre_stringpiece_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pcre_stringpiece_unittest.cc' object='pcre_stringpiece_unittest-pcre_stringpiece_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre_stringpiece_unittest_CXXFLAGS) $(CXXFLAGS) -c -o pcre_stringpiece_unittest-pcre_stringpiece_unittest.obj `if test -f 'pcre_stringpiece_unittest.cc'; then $(CYGPATH_W) 'pcre_stringpiece_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/pcre_stringpiece_unittest.cc'; fi` + +pcrecpp_unittest-pcrecpp_unittest.o: pcrecpp_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcrecpp_unittest_CXXFLAGS) $(CXXFLAGS) -MT pcrecpp_unittest-pcrecpp_unittest.o -MD -MP -MF $(DEPDIR)/pcrecpp_unittest-pcrecpp_unittest.Tpo -c -o pcrecpp_unittest-pcrecpp_unittest.o `test -f 'pcrecpp_unittest.cc' || echo '$(srcdir)/'`pcrecpp_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcrecpp_unittest-pcrecpp_unittest.Tpo $(DEPDIR)/pcrecpp_unittest-pcrecpp_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pcrecpp_unittest.cc' object='pcrecpp_unittest-pcrecpp_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcrecpp_unittest_CXXFLAGS) $(CXXFLAGS) -c -o pcrecpp_unittest-pcrecpp_unittest.o `test -f 'pcrecpp_unittest.cc' || echo '$(srcdir)/'`pcrecpp_unittest.cc + +pcrecpp_unittest-pcrecpp_unittest.obj: pcrecpp_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcrecpp_unittest_CXXFLAGS) $(CXXFLAGS) -MT pcrecpp_unittest-pcrecpp_unittest.obj -MD -MP -MF $(DEPDIR)/pcrecpp_unittest-pcrecpp_unittest.Tpo -c -o pcrecpp_unittest-pcrecpp_unittest.obj `if test -f 'pcrecpp_unittest.cc'; then $(CYGPATH_W) 'pcrecpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/pcrecpp_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcrecpp_unittest-pcrecpp_unittest.Tpo $(DEPDIR)/pcrecpp_unittest-pcrecpp_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pcrecpp_unittest.cc' object='pcrecpp_unittest-pcrecpp_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcrecpp_unittest_CXXFLAGS) $(CXXFLAGS) -c -o pcrecpp_unittest-pcrecpp_unittest.obj `if test -f 'pcrecpp_unittest.cc'; then $(CYGPATH_W) 'pcrecpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/pcrecpp_unittest.cc'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-man1: $(dist_man_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(dist_man_MANS) $(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-man3: $(dist_man_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(dist_man_MANS) $(man_MANS)'; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.3[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) +install-dist_htmlDATA: $(dist_html_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ + done + +uninstall-dist_htmlDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(htmldir)'; $(am__uninstall_files_from_dir) +install-htmlDATA: $(html_DATA) + @$(NORMAL_INSTALL) + @list='$(html_DATA)'; test -n "$(htmldir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ + done + +uninstall-htmlDATA: + @$(NORMAL_UNINSTALL) + @list='$(html_DATA)'; test -n "$(htmldir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(htmldir)'; $(am__uninstall_files_from_dir) +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) +install-nodist_includeHEADERS: $(nodist_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-nodist_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod u+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \ + $(HEADERS) config.h +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: + 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: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +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) +@WITH_GCOV_FALSE@distclean-local: +@WITH_GCOV_FALSE@clean-local: +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-local clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-local distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +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: + +install-exec-am: install-binPROGRAMS install-binSCRIPTS \ + install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 install-man3 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ + uninstall-dist_docDATA uninstall-dist_htmlDATA \ + uninstall-htmlDATA uninstall-includeHEADERS \ + uninstall-libLTLIBRARIES uninstall-man \ + uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA + +uninstall-man: uninstall-man1 uninstall-man3 + +.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 \ + clean-libtool clean-local clean-noinstPROGRAMS ctags dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \ + dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-libtool distclean-local 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-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 \ + install-pkgconfigDATA install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-binSCRIPTS uninstall-dist_docDATA \ + uninstall-dist_htmlDATA uninstall-htmlDATA \ + uninstall-includeHEADERS uninstall-libLTLIBRARIES \ + uninstall-man uninstall-man1 uninstall-man3 \ + uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA + + +# The only difference between pcre.h.in and pcre.h is the setting of the PCRE +# version number. Therefore, we can create the generic version just by copying. +pcre.h.generic: pcre.h.in configure.ac + rm -f $@ + cp -p pcre.h $@ + +# It is more complicated for config.h.generic. We need the version that results +# from a default configuration. We can get this by doing a configure in a +# temporary directory. However, some trickery is needed, +# because the source directory may already be configured. If you +# just try running configure in a new directory, it complains. For this reason, +# we move config.status out of the way while doing the default configuration. +# The resulting config.h is munged by perl to put #ifdefs round any #defines +# and to get rid of any gcc-specific visibility settings. Make sure that +# PCRE_EXP_DEFN is unset (in case it has visibility settings). +config.h.generic: configure.ac + rm -rf $@ _generic + mkdir _generic + cs=$(srcdir)/config.status; test ! -f $$cs || mv -f $$cs $$cs.aside + cd _generic && $(abs_top_srcdir)/configure || : + cs=$(srcdir)/config.status; test ! -f $$cs.aside || mv -f $$cs.aside $$cs + test -f _generic/config.h + perl -n \ + -e 'BEGIN{$$blank=0;}' \ + -e 'if(/PCRE_EXP_DEFN/){print"/* #undef PCRE_EXP_DEFN */\n";$$blank=0;next;}' \ + -e 'if(/to make a symbol visible/){next;}' \ + -e 'if(/__attribute__ \(\(visibility/){next;}' \ + -e 'if(/^#define\s(?!PACKAGE)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;}' \ + -e 'else {if(/^\s*$$/){print unless $$blank; $$blank=1;} else{print;$$blank=0;}}' \ + _generic/config.h >$@ + rm -rf _generic + +@WITH_REBUILD_CHARTABLES_TRUE@pcre_chartables.c: dftables$(EXEEXT) +@WITH_REBUILD_CHARTABLES_TRUE@ ./dftables$(EXEEXT) $@ + +@WITH_REBUILD_CHARTABLES_FALSE@pcre_chartables.c: $(srcdir)/pcre_chartables.c.dist +@WITH_REBUILD_CHARTABLES_FALSE@ rm -f $@ +@WITH_REBUILD_CHARTABLES_FALSE@ $(LN_S) $(srcdir)/pcre_chartables.c.dist $@ + +# A compatibility line, the old build system worked with 'make test' +test: check ; + +# 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". +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- and 32-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_exec.3 $(DESTDIR)$(man3dir)/pcre16_jit_exec.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 + ln -sf pcre_assign_jit_stack.3 $(DESTDIR)$(man3dir)/pcre32_assign_jit_stack.3 + ln -sf pcre_compile.3 $(DESTDIR)$(man3dir)/pcre32_compile.3 + ln -sf pcre_compile2.3 $(DESTDIR)$(man3dir)/pcre32_compile2.3 + ln -sf pcre_config.3 $(DESTDIR)$(man3dir)/pcre32_config.3 + ln -sf pcre_copy_named_substring.3 $(DESTDIR)$(man3dir)/pcre32_copy_named_substring.3 + ln -sf pcre_copy_substring.3 $(DESTDIR)$(man3dir)/pcre32_copy_substring.3 + ln -sf pcre_dfa_exec.3 $(DESTDIR)$(man3dir)/pcre32_dfa_exec.3 + ln -sf pcre_exec.3 $(DESTDIR)$(man3dir)/pcre32_exec.3 + ln -sf pcre_free_study.3 $(DESTDIR)$(man3dir)/pcre32_free_study.3 + ln -sf pcre_free_substring.3 $(DESTDIR)$(man3dir)/pcre32_free_substring.3 + ln -sf pcre_free_substring_list.3 $(DESTDIR)$(man3dir)/pcre32_free_substring_list.3 + ln -sf pcre_fullinfo.3 $(DESTDIR)$(man3dir)/pcre32_fullinfo.3 + ln -sf pcre_get_named_substring.3 $(DESTDIR)$(man3dir)/pcre32_get_named_substring.3 + ln -sf pcre_get_stringnumber.3 $(DESTDIR)$(man3dir)/pcre32_get_stringnumber.3 + ln -sf pcre_get_stringtable_entries.3 $(DESTDIR)$(man3dir)/pcre32_get_stringtable_entries.3 + ln -sf pcre_get_substring.3 $(DESTDIR)$(man3dir)/pcre32_get_substring.3 + ln -sf pcre_get_substring_list.3 $(DESTDIR)$(man3dir)/pcre32_get_substring_list.3 + ln -sf pcre_jit_exec.3 $(DESTDIR)$(man3dir)/pcre32_jit_exec.3 + ln -sf pcre_jit_stack_alloc.3 $(DESTDIR)$(man3dir)/pcre32_jit_stack_alloc.3 + ln -sf pcre_jit_stack_free.3 $(DESTDIR)$(man3dir)/pcre32_jit_stack_free.3 + ln -sf pcre_maketables.3 $(DESTDIR)$(man3dir)/pcre32_maketables.3 + ln -sf pcre_pattern_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre32_pattern_to_host_byte_order.3 + ln -sf pcre_refcount.3 $(DESTDIR)$(man3dir)/pcre32_refcount.3 + ln -sf pcre_study.3 $(DESTDIR)$(man3dir)/pcre32_study.3 + ln -sf pcre_utf32_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre32_utf32_to_host_byte_order.3 + ln -sf pcre_version.3 $(DESTDIR)$(man3dir)/pcre32_version.3 + +@WITH_GCOV_TRUE@coverage-check: all +@WITH_GCOV_TRUE@ -$(MAKE) $(AM_MAKEFLAGS) -k check + +@WITH_GCOV_TRUE@coverage-baseline: +@WITH_GCOV_TRUE@ $(LCOV) $(coverage_quiet) \ +@WITH_GCOV_TRUE@ --directory $(top_builddir) \ +@WITH_GCOV_TRUE@ --output-file "$(COVERAGE_OUTPUT_FILE)" \ +@WITH_GCOV_TRUE@ --capture \ +@WITH_GCOV_TRUE@ --initial + +@WITH_GCOV_TRUE@coverage-report: +@WITH_GCOV_TRUE@ $(LCOV) $(coverage_quiet) \ +@WITH_GCOV_TRUE@ --directory $(top_builddir) \ +@WITH_GCOV_TRUE@ --capture \ +@WITH_GCOV_TRUE@ --output-file "$(COVERAGE_OUTPUT_FILE).tmp" \ +@WITH_GCOV_TRUE@ --test-name "$(COVERAGE_TEST_NAME)" \ +@WITH_GCOV_TRUE@ --no-checksum \ +@WITH_GCOV_TRUE@ --compat-libtool \ +@WITH_GCOV_TRUE@ $(COVERAGE_LCOV_EXTRA_FLAGS) +@WITH_GCOV_TRUE@ $(LCOV) $(coverage_quiet) \ +@WITH_GCOV_TRUE@ --directory $(top_builddir) \ +@WITH_GCOV_TRUE@ --output-file "$(COVERAGE_OUTPUT_FILE)" \ +@WITH_GCOV_TRUE@ --remove "$(COVERAGE_OUTPUT_FILE).tmp" \ +@WITH_GCOV_TRUE@ "/tmp/*" \ +@WITH_GCOV_TRUE@ "/usr/include/*" \ +@WITH_GCOV_TRUE@ "$(includedir)/*" +@WITH_GCOV_TRUE@ -@rm -f "$(COVERAGE_OUTPUT_FILE).tmp" +@WITH_GCOV_TRUE@ LANG=C $(GENHTML) $(coverage_quiet) \ +@WITH_GCOV_TRUE@ --prefix $(top_builddir) \ +@WITH_GCOV_TRUE@ --output-directory "$(COVERAGE_OUTPUT_DIR)" \ +@WITH_GCOV_TRUE@ --title "$(PACKAGE) $(VERSION) Code Coverage Report" \ +@WITH_GCOV_TRUE@ --show-details "$(COVERAGE_OUTPUT_FILE)" \ +@WITH_GCOV_TRUE@ --legend \ +@WITH_GCOV_TRUE@ $(COVERAGE_GENHTML_EXTRA_FLAGS) +@WITH_GCOV_TRUE@ @echo "Code coverage report written to file://$(abs_builddir)/$(COVERAGE_OUTPUT_DIR)/index.html" + +@WITH_GCOV_TRUE@coverage-reset: +@WITH_GCOV_TRUE@ -$(LCOV) $(coverage_quiet) --zerocounters --directory $(top_builddir) + +@WITH_GCOV_TRUE@coverage-clean-report: +@WITH_GCOV_TRUE@ -rm -f "$(COVERAGE_OUTPUT_FILE)" "$(COVERAGE_OUTPUT_FILE).tmp" +@WITH_GCOV_TRUE@ -rm -rf "$(COVERAGE_OUTPUT_DIR)" + +@WITH_GCOV_TRUE@coverage-clean-data: +@WITH_GCOV_TRUE@ -find $(top_builddir) -name "*.gcda" -delete + +@WITH_GCOV_TRUE@coverage-clean: coverage-reset coverage-clean-report coverage-clean-data +@WITH_GCOV_TRUE@ -find $(top_builddir) -name "*.gcno" -delete + +@WITH_GCOV_TRUE@coverage-distclean: coverage-clean + +@WITH_GCOV_TRUE@coverage: coverage-reset coverage-baseline coverage-check coverage-report +@WITH_GCOV_TRUE@clean-local: coverage-clean +@WITH_GCOV_TRUE@distclean-local: coverage-distclean + +@WITH_GCOV_TRUE@.PHONY: coverage coverage-baseline coverage-check coverage-report coverage-reset coverage-clean-report coverage-clean-data coverage-clean coverage-distclean + +@WITH_GCOV_FALSE@coverage: +@WITH_GCOV_FALSE@ @echo "Configuring with --enable-coverage required to generate code coverage report." + +# 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 --git a/tools/pcre/NEWS b/tools/pcre/NEWS new file mode 100644 index 00000000..ebd9c5ec --- /dev/null +++ b/tools/pcre/NEWS @@ -0,0 +1,611 @@ +News about PCRE releases +------------------------ + +Release 8.32 30-November-2012 +----------------------------- + +This release fixes a number of bugs, but also has some new features. These are +the highlights: + +. There is now support for 32-bit character strings and UTF-32. Like the + 16-bit support, this is done by compiling a separate 32-bit library. + +. \X now matches a Unicode extended grapheme cluster. + +. Case-independent matching of Unicode characters that have more than one + "other case" now makes all three (or more) characters equivalent. This + applies, for example, to Greek Sigma, which has two lowercase versions. + +. Unicode character properties are updated to Unicode 6.2.0. + +. The EBCDIC support, which had decayed, has had a spring clean. + +. A number of JIT optimizations have been added, which give faster JIT + execution speed. In addition, a new direct interface to JIT execution is + available. This bypasses some of the sanity checks of pcre_exec() to give a + noticeable speed-up. + +. A number of issues in pcregrep have been fixed, making it more compatible + with GNU grep. In particular, --exclude and --include (and variants) apply + to all files now, not just those obtained from scanning a directory + recursively. In Windows environments, the default action for directories is + now "skip" instead of "read" (which provokes an error). + +. If the --only-matching (-o) option in pcregrep is specified multiple + times, each one causes appropriate output. For example, -o1 -o2 outputs the + substrings matched by the 1st and 2nd capturing parentheses. A separating + string can be specified by --om-separator (default empty). + +. When PCRE is built via Autotools using a version of gcc that has the + "visibility" feature, it is used to hide internal library functions that are + not part of the public API. + + +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 lookbehind 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 +------------------------ + +This release fixes some bugs in pcregrep, one of which caused the tests to fail +on 64-bit big-endian systems. There are no changes to the code of the library. + + +Release 8.11 10-Dec-2010 +------------------------ + +A number of bugs in the library and in pcregrep have been fixed. As always, see +ChangeLog for details. The following are the non-bug-fix changes: + +. Added --match-limit and --recursion-limit to pcregrep. + +. Added an optional parentheses number to the -o and --only-matching options + of pcregrep. + +. Changed the way PCRE_PARTIAL_HARD affects the matching of $, \z, \Z, \b, and + \B. + +. Added PCRE_ERROR_SHORTUTF8 to make it possible to distinguish between a + bad UTF-8 sequence and one that is incomplete when using PCRE_PARTIAL_HARD. + +. Recognize (*NO_START_OPT) at the start of a pattern to set the PCRE_NO_ + START_OPTIMIZE option, which is now allowed at compile time + + +Release 8.10 25-Jun-2010 +------------------------ + +There are two major additions: support for (*MARK) and friends, and the option +PCRE_UCP, which changes the behaviour of \b, \d, \s, and \w (and their +opposites) so that they make use of Unicode properties. There are also a number +of lesser new features, and several bugs have been fixed. A new option, +--line-buffered, has been added to pcregrep, for use when it is connected to +pipes. + + +Release 8.02 19-Mar-2010 +------------------------ + +Another bug-fix release. + + +Release 8.01 19-Jan-2010 +------------------------ + +This is a bug-fix release. Several bugs in the code itself and some bugs and +infelicities in the build system have been fixed. + + +Release 8.00 19-Oct-09 +---------------------- + +Bugs have been fixed in the library and in pcregrep. There are also some +enhancements. Restrictions on patterns used for partial matching have been +removed, extra information is given for partial matches, the partial matching +process has been improved, and an option to make a partial match override a +full match is available. The "study" process has been enhanced by finding a +lower bound matching length. Groups with duplicate numbers may now have +duplicated names without the use of PCRE_DUPNAMES. However, they may not have +different names. The documentation has been revised to reflect these changes. +The version number has been expanded to 3 digits as it is clear that the rate +of change is not slowing down. + + +Release 7.9 11-Apr-09 +--------------------- + +Mostly bugfixes and tidies with just a couple of minor functional additions. + + +Release 7.8 05-Sep-08 +--------------------- + +More bug fixes, plus a performance improvement in Unicode character property +lookup. + + +Release 7.7 07-May-08 +--------------------- + +This is once again mainly a bug-fix release, but there are a couple of new +features. + + +Release 7.6 28-Jan-08 +--------------------- + +The main reason for having this release so soon after 7.5 is because it fixes a +potential buffer overflow problem in pcre_compile() when run in UTF-8 mode. In +addition, the CMake configuration files have been brought up to date. + + +Release 7.5 10-Jan-08 +--------------------- + +This is mainly a bug-fix release. However the ability to link pcregrep with +libz or libbz2 and the ability to link pcretest with libreadline have been +added. Also the --line-offsets and --file-offsets options were added to +pcregrep. + + +Release 7.4 21-Sep-07 +--------------------- + +The only change of specification is the addition of options to control whether +\R matches any Unicode line ending (the default) or just CR, LF, and CRLF. +Otherwise, the changes are bug fixes and a refactoring to reduce the number of +relocations needed in a shared library. There have also been some documentation +updates, in particular, some more information about using CMake to build PCRE +has been added to the NON-UNIX-USE file. + + +Release 7.3 28-Aug-07 +--------------------- + +Most changes are bug fixes. Some that are not: + +1. There is some support for Perl 5.10's experimental "backtracking control + verbs" such as (*PRUNE). + +2. UTF-8 checking is now as per RFC 3629 instead of RFC 2279; this is more + restrictive in the strings it accepts. + +3. Checking for potential integer overflow has been made more dynamic, and as a + consequence there is no longer a hard limit on the size of a subpattern that + has a limited repeat count. + +4. When CRLF is a valid line-ending sequence, pcre_exec() and pcre_dfa_exec() + no longer advance by two characters instead of one when an unanchored match + fails at CRLF if there are explicit CR or LF matches within the pattern. + This gets rid of some anomalous effects that previously occurred. + +5. Some PCRE-specific settings for varying the newline options at the start of + a pattern have been added. + + +Release 7.2 19-Jun-07 +--------------------- + +WARNING: saved patterns that were compiled by earlier versions of PCRE must be +recompiled for use with 7.2 (necessitated by the addition of \K, \h, \H, \v, +and \V). + +Correction to the notes for 7.1: the note about shared libraries for Windows is +wrong. Previously, three libraries were built, but each could function +independently. For example, the pcreposix library also included all the +functions from the basic pcre library. The change is that the three libraries +are no longer independent. They are like the Unix libraries. To use the +pcreposix functions, for example, you need to link with both the pcreposix and +the basic pcre library. + +Some more features from Perl 5.10 have been added: + + (?-n) and (?+n) relative references for recursion and subroutines. + + (?(-n) and (?(+n) relative references as conditions. + + \k{name} and \g{name} are synonyms for \k. + + \K to reset the start of the matched string; for example, (foo)\Kbar + matches bar preceded by foo, but only sets bar as the matched string. + + (?| introduces a group where the capturing parentheses in each alternative + start from the same number; for example, (?|(abc)|(xyz)) sets capturing + parentheses number 1 in both cases. + + \h, \H, \v, \V match horizontal and vertical whitespace, respectively. + + +Release 7.1 24-Apr-07 +--------------------- + +There is only one new feature in this release: a linebreak setting of +PCRE_NEWLINE_ANYCRLF. It is a cut-down version of PCRE_NEWLINE_ANY, which +recognizes only CRLF, CR, and LF as linebreaks. + +A few bugs are fixed (see ChangeLog for details), but the major change is a +complete re-implementation of the build system. This now has full Autotools +support and so is now "standard" in some sense. It should help with compiling +PCRE in a wide variety of environments. + +NOTE: when building shared libraries for Windows, three dlls are now built, +called libpcre, libpcreposix, and libpcrecpp. Previously, everything was +included in a single dll. + +Another important change is that the dftables auxiliary program is no longer +compiled and run at "make" time by default. Instead, a default set of character +tables (assuming ASCII coding) is used. If you want to use dftables to generate +the character tables as previously, add --enable-rebuild-chartables to the +"configure" command. You must do this if you are compiling PCRE to run on a +system that uses EBCDIC code. + +There is a discussion about character tables in the README file. The default is +not to use dftables so that that there is no problem when cross-compiling. + + +Release 7.0 19-Dec-06 +--------------------- + +This release has a new major number because there have been some internal +upheavals to facilitate the addition of new optimizations and other facilities, +and to make subsequent maintenance and extension easier. Compilation is likely +to be a bit slower, but there should be no major effect on runtime performance. +Previously compiled patterns are NOT upwards compatible with this release. If +you have saved compiled patterns from a previous release, you will have to +re-compile them. Important changes that are visible to users are: + +1. The Unicode property tables have been updated to Unicode 5.0.0, which adds + some more scripts. + +2. The option PCRE_NEWLINE_ANY causes PCRE to recognize any Unicode newline + sequence as a newline. + +3. The \R escape matches a single Unicode newline sequence as a single unit. + +4. New features that will appear in Perl 5.10 are now in PCRE. These include + alternative Perl syntax for named parentheses, and Perl syntax for + recursion. + +5. The C++ wrapper interface has been extended by the addition of a + QuoteMeta function and the ability to allow copy construction and + assignment. + +For a complete list of changes, see the ChangeLog file. + + +Release 6.7 04-Jul-06 +--------------------- + +The main additions to this release are the ability to use the same name for +multiple sets of parentheses, and support for CRLF line endings in both the +library and pcregrep (and in pcretest for testing). + +Thanks to Ian Taylor, the stack usage for many kinds of pattern has been +significantly reduced for certain subject strings. + + +Release 6.5 01-Feb-06 +--------------------- + +Important changes in this release: + +1. A number of new features have been added to pcregrep. + +2. The Unicode property tables have been updated to Unicode 4.1.0, and the + supported properties have been extended with script names such as "Arabic", + and the derived properties "Any" and "L&". This has necessitated a change to + the interal format of compiled patterns. Any saved compiled patterns that + use \p or \P must be recompiled. + +3. The specification of recursion in patterns has been changed so that all + recursive subpatterns are automatically treated as atomic groups. Thus, for + example, (?R) is treated as if it were (?>(?R)). This is necessary because + otherwise there are situations where recursion does not work. + +See the ChangeLog for a complete list of changes, which include a number of bug +fixes and tidies. + + +Release 6.0 07-Jun-05 +--------------------- + +The release number has been increased to 6.0 because of the addition of several +major new pieces of functionality. + +A new function, pcre_dfa_exec(), which implements pattern matching using a DFA +algorithm, has been added. This has a number of advantages for certain cases, +though it does run more slowly, and lacks the ability to capture substrings. On +the other hand, it does find all matches, not just the first, and it works +better for partial matching. The pcrematching man page discusses the +differences. + +The pcretest program has been enhanced so that it can make use of the new +pcre_dfa_exec() matching function and the extra features it provides. + +The distribution now includes a C++ wrapper library. This is built +automatically if a C++ compiler is found. The pcrecpp man page discusses this +interface. + +The code itself has been re-organized into many more files, one for each +function, so it no longer requires everything to be linked in when static +linkage is used. As a consequence, some internal functions have had to have +their names exposed. These functions all have names starting with _pcre_. They +are undocumented, and are not intended for use by outside callers. + +The pcregrep program has been enhanced with new functionality such as +multiline-matching and options for output more matching context. See the +ChangeLog for a complete list of changes to the library and the utility +programs. + + +Release 5.0 13-Sep-04 +--------------------- + +The licence under which PCRE is released has been changed to the more +conventional "BSD" licence. + +In the code, some bugs have been fixed, and there are also some major changes +in this release (which is why I've increased the number to 5.0). Some changes +are internal rearrangements, and some provide a number of new facilities. The +new features are: + +1. There's an "automatic callout" feature that inserts callouts before every + item in the regex, and there's a new callout field that gives the position + in the pattern - useful for debugging and tracing. + +2. The extra_data structure can now be used to pass in a set of character + tables at exec time. This is useful if compiled regex are saved and re-used + at a later time when the tables may not be at the same address. If the + default internal tables are used, the pointer saved with the compiled + pattern is now set to NULL, which means that you don't need to do anything + special unless you are using custom tables. + +3. It is possible, with some restrictions on the content of the regex, to + request "partial" matching. A special return code is given if all of the + subject string matched part of the regex. This could be useful for testing + an input field as it is being typed. + +4. There is now some optional support for Unicode character properties, which + means that the patterns items such as \p{Lu} and \X can now be used. Only + the general category properties are supported. If PCRE is compiled with this + support, an additional 90K data structure is include, which increases the + size of the library dramatically. + +5. There is support for saving compiled patterns and re-using them later. + +6. There is support for running regular expressions that were compiled on a + different host with the opposite endianness. + +7. The pcretest program has been extended to accommodate the new features. + +The main internal rearrangement is that sequences of literal characters are no +longer handled as strings. Instead, each character is handled on its own. This +makes some UTF-8 handling easier, and makes the support of partial matching +possible. Compiled patterns containing long literal strings will be larger as a +result of this change; I hope that performance will not be much affected. + + +Release 4.5 01-Dec-03 +--------------------- + +Again mainly a bug-fix and tidying release, with only a couple of new features: + +1. It's possible now to compile PCRE so that it does not use recursive +function calls when matching. Instead it gets memory from the heap. This slows +things down, but may be necessary on systems with limited stacks. + +2. UTF-8 string checking has been tightened to reject overlong sequences and to +check that a starting offset points to the start of a character. Failure of the +latter returns a new error code: PCRE_ERROR_BADUTF8_OFFSET. + +3. PCRE can now be compiled for systems that use EBCDIC code. + + +Release 4.4 21-Aug-03 +--------------------- + +This is mainly a bug-fix and tidying release. The only new feature is that PCRE +checks UTF-8 strings for validity by default. There is an option to suppress +this, just in case anybody wants that teeny extra bit of performance. + + +Releases 4.1 - 4.3 +------------------ + +Sorry, I forgot about updating the NEWS file for these releases. Please take a +look at ChangeLog. + + +Release 4.0 17-Feb-03 +--------------------- + +There have been a lot of changes for the 4.0 release, adding additional +functionality and mending bugs. Below is a list of the highlights of the new +functionality. For full details of these features, please consult the +documentation. For a complete list of changes, see the ChangeLog file. + +1. Support for Perl's \Q...\E escapes. + +2. "Possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's Java +package. They provide some syntactic sugar for simple cases of "atomic +grouping". + +3. Support for the \G assertion. It is true when the current matching position +is at the start point of the match. + +4. A new feature that provides some of the functionality that Perl provides +with (?{...}). The facility is termed a "callout". The way it is done in PCRE +is for the caller to provide an optional function, by setting pcre_callout to +its entry point. To get the function called, the regex must include (?C) at +appropriate points. + +5. Support for recursive calls to individual subpatterns. This makes it really +easy to get totally confused. + +6. Support for named subpatterns. The Python syntax (?P...) is used to +name a group. + +7. Several extensions to UTF-8 support; it is now fairly complete. There is an +option for pcregrep to make it operate in UTF-8 mode. + +8. The single man page has been split into a number of separate man pages. +These also give rise to individual HTML pages which are put in a separate +directory. There is an index.html page that lists them all. Some hyperlinking +between the pages has been installed. + + +Release 3.5 15-Aug-01 +--------------------- + +1. The configuring system has been upgraded to use later versions of autoconf +and libtool. By default it builds both a shared and a static library if the OS +supports it. You can use --disable-shared or --disable-static on the configure +command if you want only one of them. + +2. The pcretest utility is now installed along with pcregrep because it is +useful for users (to test regexs) and by doing this, it automatically gets +relinked by libtool. The documentation has been turned into a man page, so +there are now .1, .txt, and .html versions in /doc. + +3. Upgrades to pcregrep: + (i) Added long-form option names like gnu grep. + (ii) Added --help to list all options with an explanatory phrase. + (iii) Added -r, --recursive to recurse into sub-directories. + (iv) Added -f, --file to read patterns from a file. + +4. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure +script, to force use of CR or LF instead of \n in the source. On non-Unix +systems, the value can be set in config.h. + +5. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an +absolute limit. Changed the text of the error message to make this clear, and +likewise updated the man page. + +6. The limit of 99 on the number of capturing subpatterns has been removed. +The new limit is 65535, which I hope will not be a "real" limit. + + +Release 3.3 01-Aug-00 +--------------------- + +There is some support for UTF-8 character strings. This is incomplete and +experimental. The documentation describes what is and what is not implemented. +Otherwise, this is just a bug-fixing release. + + +Release 3.0 01-Feb-00 +--------------------- + +1. A "configure" script is now used to configure PCRE for Unix systems. It +builds a Makefile, a config.h file, and the pcre-config script. + +2. PCRE is built as a shared library by default. + +3. There is support for POSIX classes such as [:alpha:]. + +5. There is an experimental recursion feature. + +---------------------------------------------------------------------------- + IMPORTANT FOR THOSE UPGRADING FROM VERSIONS BEFORE 2.00 + +Please note that there has been a change in the API such that a larger +ovector is required at matching time, to provide some additional workspace. +The new man page has details. This change was necessary in order to support +some of the new functionality in Perl 5.005. + + IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.00 + +Another (I hope this is the last!) change has been made to the API for the +pcre_compile() function. An additional argument has been added to make it +possible to pass over a pointer to character tables built in the current +locale by pcre_maketables(). To use the default tables, this new arguement +should be passed as NULL. + + IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.05 + +Yet another (and again I hope this really is the last) change has been made +to the API for the pcre_exec() function. An additional argument has been +added to make it possible to start the match other than at the start of the +subject string. This is important if there are lookbehinds. The new man +page has the details, but you just want to convert existing programs, all +you need to do is to stick in a new fifth argument to pcre_exec(), with a +value of zero. For example, change + + pcre_exec(pattern, extra, subject, length, options, ovec, ovecsize) +to + pcre_exec(pattern, extra, subject, length, 0, options, ovec, ovecsize) + +**** diff --git a/tools/pcre/NON-AUTOTOOLS-BUILD b/tools/pcre/NON-AUTOTOOLS-BUILD new file mode 100644 index 00000000..a4e2e463 --- /dev/null +++ b/tools/pcre/NON-AUTOTOOLS-BUILD @@ -0,0 +1,639 @@ +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 + Building PCRE on native z/OS and z/VM + + +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". If you are going to use CMake, this section does not apply to you; you +can skip ahead to the CMake section. + + (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, you can alter the definition of the NEWLINE macro to + specify what character(s) you want to be interpreted as line terminators. + In an EBCDIC environment, you MUST change NEWLINE, because its default + value is 10, an ASCII LF. The usual EBCDIC newline character is 21 (0x15, + NL), though in some cases it may be 37 (0x25). + + 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_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 + + 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. + + Note that you must still compile pcre_jit_compile.c, even if you have not + defined SUPPORT_JIT in config.h, because when JIT support is not + configured, dummy functions are compiled. When JIT support IS configured, + pcre_jit_compile.c #includes sources from the sljit subdirectory, where + there should be 16 files, all of whose names begin with "sljit". + + (6) 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. + + (7) If you want to build a 16-bit library (as well as, or instead of the 8-bit + or 32-bit libraries) repeat steps 5-6 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 + 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 + + (7') If you want to build a 16-bit library (as well as, or instead of the 8-bit + or 32-bit libraries) repeat steps 5-6 with the following files: + + pcre32_byte_order.c + pcre32_chartables.c + pcre32_compile.c + pcre32_config.c + pcre32_dfa_exec.c + pcre32_exec.c + pcre32_fullinfo.c + pcre32_get.c + pcre32_globals.c + pcre32_jit_compile.c + pcre32_maketables.c + pcre32_newline.c + pcre32_ord2utf32.c + pcre32_refcount.c + pcre32_string_utils.c + pcre32_study.c + pcre32_tables.c + pcre32_ucd.c + pcre32_utf32_utils.c + pcre32_valid_utf32.c + pcre32_version.c + pcre32_xclass.c + + (8) 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. + + (9) The pcretest program can be linked with any combination of the 8-bit, 16-bit + and 32-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. + +(10) 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 more than one of the 8-bit, 16-bit and + 32-bit libraries, you need to run pcretest with the -16 option to do 16-bit + tests and with the -32 option to do 32-bit tests. + + Some tests are relevant only when certain build-time options are selected. + For example, test 4 is for UTF-8/UTF-16/UTF-32 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. + +(11) 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. + +(12) 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. If they are not +followed exactly, errors may occur. In the event that errors do occur, it is +recommended that you delete the CMake cache before attempting to repeat the +CMake build process. In the CMake GUI, the cache can be deleted by selecting +"File > Delete Cache". + +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++. Do not try + to start Cmake from the Windows Start menu, as this can lead to errors. + +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. + + +BUILDING PCRE ON NATIVE Z/OS AND Z/VM + +z/OS and z/VM are operating systems for mainframe computers, produced by IBM. +The character code used is EBCDIC, not ASCII or Unicode. In z/OS, UNIX APIs and +applications can be supported through UNIX System Services, and in such an +environment PCRE can be built in the same way as in other systems. However, in +native z/OS (without UNIX System Services) and in z/VM, special ports are +required. For details, please see this web site: + + http://www.zaconsultants.net + +There is also a mirror here: + + http://www.vsoft-software.com/downloads.html + +========================== +Last Updated: 21 November 2012 diff --git a/tools/pcre/NON-UNIX-USE b/tools/pcre/NON-UNIX-USE new file mode 100644 index 00000000..a25546b6 --- /dev/null +++ b/tools/pcre/NON-UNIX-USE @@ -0,0 +1,7 @@ +Compiling PCRE on non-Unix systems +---------------------------------- + +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. + +#### diff --git a/tools/pcre/PrepareRelease b/tools/pcre/PrepareRelease new file mode 100644 index 00000000..4ec803e5 --- /dev/null +++ b/tools/pcre/PrepareRelease @@ -0,0 +1,253 @@ +#/bin/sh + +# Script to prepare the files for building a PCRE release. It does some +# processing of the documentation, detrails files, and creates pcre.h.generic +# and config.h.generic (for use by builders who can't run ./configure). + +# You must run this script before runnning "make dist". If its first argument +# is "doc", it stops after preparing the documentation. There are no other +# arguments. The script makes use of the following files: + +# 132html A Perl script that converts a .1 or .3 man page into HTML. It +# "knows" the relevant troff constructs that are used in the PCRE +# man pages. + +# CheckMan A Perl script that checks man pages for typos in the mark up. + +# CleanTxt A Perl script that cleans up the output of "nroff -man" by +# removing backspaces and other redundant text so as to produce +# a readable .txt file. + +# Detrail A Perl script that removes trailing spaces from files. + +# doc/index.html.src +# A file that is copied as index.html into the doc/html directory +# when the HTML documentation is built. It works like this so that +# doc/html can be deleted and re-created from scratch. + + +# First, sort out the documentation. Remove pcredemo.3 first because it won't +# pass the markup check (it is created below, using markup that none of the +# other pages use). + +cd doc +echo Processing documentation + +/bin/rm -f pcredemo.3 + +# Check the remaining man pages + +perl ../CheckMan *.1 *.3 +if [ $? != 0 ] ; then exit 1; fi + +# Make Text form of the documentation. It needs some mangling to make it +# tidy for online reading. Concatenate all the .3 stuff, but omit the +# individual function pages. + +cat <pcre.txt +----------------------------------------------------------------------------- +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 +the pcredemo program. There are separate text files for the pcregrep and +pcretest commands. +----------------------------------------------------------------------------- + + +End + +echo "Making pcre.txt" +for file in pcre pcre16 pcre32 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 + perl ../CleanTxt <$file.rawtxt >>pcre.txt + /bin/rm $file.rawtxt + echo "------------------------------------------------------------------------------" >>pcre.txt + if [ "$file" != "pcresample" ] ; then + echo " " >>pcre.txt + echo " " >>pcre.txt + fi +done + +# The three commands +for file in pcretest pcregrep pcre-config ; do + echo Making $file.txt + nroff -c -man $file.1 >$file.rawtxt + perl ../CleanTxt <$file.rawtxt >$file.txt + /bin/rm $file.rawtxt +done + + +# Make pcredemo.3 from the pcredemo.c source file + +echo "Making pcredemo.3" +perl <<"END" >pcredemo.3 + open(IN, "../pcredemo.c") || die "Failed to open pcredemo.c\n"; + open(OUT, ">pcredemo.3") || die "Failed to open pcredemo.3\n"; + print OUT ".\\\" Start example.\n" . + ".de EX\n" . + ". nr mE \\\\n(.f\n" . + ". nf\n" . + ". nh\n" . + ". ft CW\n" . + "..\n" . + ".\n" . + ".\n" . + ".\\\" End example.\n" . + ".de EE\n" . + ". ft \\\\n(mE\n" . + ". fi\n" . + ". hy \\\\n(HY\n" . + "..\n" . + ".\n" . + ".EX\n" ; + while () + { + s/\\/\\e/g; + print OUT; + } + print OUT ".EE\n"; + close(IN); + close(OUT); +END +if [ $? != 0 ] ; then exit 1; fi + + +# Make HTML form of the documentation. + +echo "Making HTML documentation" +/bin/rm html/* +cp index.html.src html/index.html + +for file in *.1 ; do + base=`basename $file .1` + echo " Making $base.html" + perl ../132html -toc $base <$file >html/$base.html +done + +# Exclude table of contents for function summaries. It seems that expr +# forces an anchored regex. Also exclude them for small pages that have +# only one section. + +for file in *.3 ; do + base=`basename $file .3` + toc=-toc + if [ `expr $base : '.*_'` -ne 0 ] ; then toc="" ; fi + if [ "$base" = "pcresample" ] || \ + [ "$base" = "pcrestack" ] || \ + [ "$base" = "pcrecompat" ] || \ + [ "$base" = "pcrelimits" ] || \ + [ "$base" = "pcreperform" ] || \ + [ "$base" = "pcreunicode" ] ; then + toc="" + fi + echo " Making $base.html" + perl ../132html $toc $base <$file >html/$base.html + if [ $? != 0 ] ; then exit 1; fi +done + +# End of documentation processing; stop if only documentation required. + +cd .. +echo Documentation done +if [ "$1" = "doc" ] ; then exit; fi + +# These files are detrailed; do not detrail the test data because there may be +# 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 pcre[16|32]_xx files that just define COMPILE_PCRE16 and then #include the +# common file, because they aren't going to change. + +files="\ + Makefile.am \ + Makefile.in \ + configure.ac \ + README \ + LICENCE \ + COPYING \ + AUTHORS \ + NEWS \ + NON-UNIX-USE \ + NON-AUTOTOOLS-BUILD \ + INSTALL \ + 132html \ + CleanTxt \ + Detrail \ + ChangeLog \ + CMakeLists.txt \ + RunGrepTest \ + RunTest \ + pcre-config.in \ + libpcre.pc.in \ + libpcre16.pc.in \ + libpcre32.pc.in \ + libpcreposix.pc.in \ + libpcrecpp.pc.in \ + config.h.in \ + pcre_chartables.c.dist \ + pcredemo.c \ + pcregrep.c \ + pcretest.c \ + dftables.c \ + pcreposix.c \ + pcreposix.h \ + pcre.h.in \ + pcre_internal.h \ + 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_jit_compile.c \ + pcre_jit_test.c \ + pcre_maketables.c \ + pcre_newline.c \ + pcre_ord2utf8.c \ + pcre16_ord2utf16.c \ + pcre32_ord2utf32.c \ + pcre_printint.c \ + pcre_refcount.c \ + pcre_string_utils.c \ + pcre_study.c \ + pcre_tables.c \ + pcre_ucp_searchfuncs.c \ + pcre_valid_utf8.c \ + pcre_version.c \ + pcre_xclass.c \ + pcre16_utf16_utils.c \ + pcre32_utf32_utils.c \ + pcre16_valid_utf16.c \ + pcre32_valid_utf32.c \ + pcre_scanner.cc \ + pcre_scanner.h \ + pcre_scanner_unittest.cc \ + pcrecpp.cc \ + pcrecpp.h \ + pcrecpparg.h.in \ + pcrecpp_unittest.cc \ + pcre_stringpiece.cc \ + pcre_stringpiece.h.in \ + pcre_stringpiece_unittest.cc \ + perltest.pl \ + ucp.h \ + ucpinternal.h \ + ucptable.h \ + makevp.bat \ + pcre.def \ + libpcre.def \ + libpcreposix.def" + +echo Detrailing +perl ./Detrail $files doc/p* doc/html/* + +echo Done + +#End diff --git a/tools/pcre/README b/tools/pcre/README new file mode 100644 index 00000000..a2c3d9b3 --- /dev/null +++ b/tools/pcre/README @@ -0,0 +1,935 @@ +README file for PCRE (Perl-compatible regular expression library) +----------------------------------------------------------------- + +The latest release of PCRE is always available in three alternative formats +from: + + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.bz2 + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.zip + +There is a mailing list for discussion about the development of PCRE at + + pcre-dev@exim.org + +Please read the NEWS file if you are upgrading from a previous release. +The contents of this README file are: + + The PCRE APIs + Documentation for PCRE + Contributions by users of PCRE + 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 + Testing PCRE + Character tables + File manifest + + +The PCRE APIs +------------- + +PCRE is written in C, and it has its own API. There are three sets of functions, +one for the 8-bit library, which processes strings of bytes, one for the +16-bit library, which processes strings of 16-bit values, and one for the 32-bit +library, which processes strings of 32-bit values. The distribution also +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 +with existing files of that name by distributing it that way. To use PCRE with +an existing program that uses the POSIX API, pcreposix.h will have to be +renamed or pointed at by a link. + +If you are using the POSIX interface to PCRE and there is already a POSIX regex +library installed on your system, as well as worrying about the regex.h header +file (as mentioned above), you must also take care when linking programs to +ensure that they link with PCRE's libpcreposix library. Otherwise they may pick +up the POSIX functions of the same name from the other library. + +One way of avoiding this confusion is to compile PCRE with the addition of +-Dregcomp=PCREregcomp (and similarly for the other POSIX functions) to the +compiler flags (CFLAGS if you are using "configure" -- see below). This has the +effect of renaming the functions so that the names no longer clash. Of course, +you have to do the same thing for your applications, or write them using the +new names. + + +Documentation for PCRE +---------------------- + +If you install PCRE in the normal way on a Unix-like system, you will end up +with a set of man pages whose names all start with "pcre". The one that is just +called "pcre" lists all the others. In addition to these man pages, the PCRE +documentation is supplied in two other forms: + + 1. There are files called doc/pcre.txt, doc/pcregrep.txt, and + doc/pcretest.txt in the source distribution. The first of these is a + concatenation of the text forms of all the section 3 man pages except + those that summarize individual functions. The other two are the text + forms of the section 1 man pages for the pcregrep and pcretest commands. + These text forms are provided for ease of scanning with text editors or + similar tools. They are installed in /share/doc/pcre, where + is the installation prefix (defaulting to /usr/local). + + 2. A set of files containing all the documentation in HTML form, hyperlinked + in various ways, and rooted in a file called index.html, is distributed in + doc/html and installed in /share/doc/pcre/html. + +Users of PCRE have contributed files containing the documentation for various +releases in CHM format. These can be found in the Contrib directory of the FTP +site (see next section). + + +Contributions by users of PCRE +------------------------------ + +You can find contributions from PCRE users in the directory + + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib + +There is a README file giving brief descriptions of what they are. Some are +complete in themselves; others are pointers to URLs containing relevant files. +Some of this material is likely to be well out-of-date. Several of the earlier +contributions provided support for compiling PCRE on various flavours of +Windows (I myself do not use Windows). Nowadays there is more Windows support +in the standard distribution, so these contibutions have been archived. + + +Building PCRE on non-Unix-like systems +-------------------------------------- + +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 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" (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, +the usual methods of changing standard defaults are available. For example: + +CFLAGS='-O2 -Wall' ./configure --prefix=/opt/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 +into /source/pcre/pcre-xxx, but you want to build it in /build/pcre/pcre-xxx: + +cd /build/pcre/pcre-xxx +/source/pcre/pcre-xxx/configure + +PCRE is written in C and is normally compiled as a C library. However, it is +possible to build it as a C++ library, though the provided building apparatus +does not have any features to support this. + +There are some optional features that can be included or omitted from the PCRE +library. 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 + + (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 add + --enable-pcre32 to the "configure" command, the 32-bit library is also built. + If you want only the 16-bit or 32-bit library, use --disable-pcre8 to disable + building the 8-bit library. + +. 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 + the 8-bit library, or UTF-16 Unicode character strings in the 16-bit library, + or UTF-32 Unicode character strings in the 32-bit library, you must add + --enable-utf to the "configure" command. Without it, the code for handling + UTF-8, UTF-16 and UTF-8 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/32, 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, UTF-16 and UTF-32 + 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 or 32-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/32 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 + end of a line. Whatever you specify at build time is the default; the caller + of PCRE can change the selection at run time. The default newline indicator + is a single LF character (the Unix standard). You can specify the default + newline indicator by adding --enable-newline-is-cr or --enable-newline-is-lf + or --enable-newline-is-crlf or --enable-newline-is-anycrlf or + --enable-newline-is-any to the "configure" command, respectively. + + If you specify --enable-newline-is-cr or --enable-newline-is-crlf, some of + the standard tests will fail, because the lines in the test files end with + LF. Even if the files are edited to change the line endings, there are likely + to be some failures. With --enable-newline-is-anycrlf or + --enable-newline-is-any, many tests should succeed, but there may be some + failures. + +. By default, the sequence \R in a pattern matches any Unicode line ending + sequence. This is independent of the option specifying what PCRE considers to + be the end of a line (see above). However, the caller of PCRE can restrict \R + to match only CR, LF, or CRLF. You can make this the default by adding + --enable-bsr-anycrlf to the "configure" command (bsr = "backslash R"). + +. When called via the POSIX interface, PCRE uses malloc() to get additional + storage for processing capturing parentheses if there are more than 10 of + them in a pattern. You can increase this threshold by setting, for example, + + --with-posix-malloc-threshold=20 + + on the "configure" command. + +. PCRE has a counter that can be set to limit the amount of resources it uses. + If the limit is exceeded during a match, the match fails. The default is ten + million. You can change the default by setting, for example, + + --with-match-limit=500000 + + on the "configure" command. This is just the default; individual calls to + pcre_exec() can supply their own value. There is more discussion on the + pcreapi man page. + +. There is a separate counter that limits the depth of recursive function calls + during a matching process. This also has a default of ten million, which is + essentially "unlimited". You can change the default by setting, for example, + + --with-match-limit-recursion=500000 + + Recursive function calls use up the runtime stack; running out of stack can + cause programs to crash in strange ways. There is a discussion about stack + 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. 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. In the 32-bit + library, the only supported link size is 4. + +. 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 + obtained from the heap via the special functions pcre_stack_malloc() and + pcre_stack_free() to save data that would otherwise be saved on the stack. To + build PCRE like this, use + + --disable-stack-for-recursion + + 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 + 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 + tables for ASCII encoding that is part of the distribution. If you specify + + --enable-rebuild-chartables + + a program called dftables is compiled and run in the default C locale when + you obey "make". It builds a source file called pcre_chartables.c. If you do + not specify this option, pcre_chartables.c is created as a copy of + pcre_chartables.c.dist. See "Character tables" below for further information. + +. It is possible to compile PCRE for use on systems that use EBCDIC as their + character code (as opposed to ASCII/Unicode) by specifying + + --enable-ebcdic + + 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/16/32. There is a second option, --enable-ebcdic-nl25, + which specifies that the code value for the EBCDIC NL character is 0x25 + instead of the default 0x15. + +. In environments where valgrind is installed, if you specify + + --enable-valgrind + + PCRE will use valgrind annotations to mark certain memory regions as + unaddressable. This allows it to detect invalid memory accesses, and is + mostly useful for debugging PCRE itself. + +. In environments where the gcc compiler is used and lcov version 1.6 or above + is installed, if you specify + + --enable-coverage + + the build process implements a code coverage report for the test suite. The + report is generated by running "make coverage". If ccache is installed on + your system, it must be disabled when building PCRE for coverage reporting. + You can do this by setting the environment variable CCACHE_DISABLE=1 before + running "make" to build PCRE. + +. 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 + or libedit libraries, by specifying, respectively, + + --enable-pcretest-libreadline or --enable-pcretest-libedit + + If this is done, when pcretest's input is from a terminal, it reads it using + the readline() function. This provides line-editing and history facilities. + Note that libreadline is GPL-licenced, so if you distribute a binary of + pcretest linked in this way, there may be licensing issues. These can be + avoided by linking with libedit (which has a BSD licence) instead. + + 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 + to specify something like LIBS="-lncurses" as well. This is because, to quote + the readline INSTALL, "Readline uses the termcap functions, but does not link + with the termcap or curses library itself, allowing applications which link + with readline the to choose an appropriate library." If you get error + messages about missing functions tgetstr, tgetent, tputs, tgetflag, or tgoto, + this is the problem, and linking with the ncurses library should fix it. + +The "configure" script builds the following files for the basic C library: + +. 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 ) +. libpcre32.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. + +When building the 8-bit library, if a C++ compiler is found, the following +files are also built: + +. 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". This builds the the libraries +libpcre, libpcre16 and/or libpcre32, 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. + +You can use "make install" to install PCRE into live directories on your +system. The following are installed (file names are all relative to the + that is set when "configure" is run): + + Commands (bin): + pcretest + pcregrep (if 8-bit support is enabled) + pcre-config + + Libraries (lib): + libpcre16 (if 16-bit support is enabled) + libpcre32 (if 32-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 + libpcre32.pc + libpcre.pc + libpcreposix.pc + libpcrecpp.pc (if C++ support is enabled) + + Header files (include): + pcre.h + pcreposix.h + pcre_scanner.h ) + pcre_stringpiece.h ) if C++ support is enabled + pcrecpp.h ) + pcrecpparg.h ) + + Man pages (share/man/man{1,3}): + pcregrep.1 + pcretest.1 + pcre-config.1 + pcre.3 + pcre*.3 (lots more pages, all starting "pcre") + + HTML documentation (share/doc/pcre/html): + index.html + *.html (lots more pages, hyperlinked from index.html) + + Text file documentation (share/doc/pcre): + AUTHORS + COPYING + ChangeLog + 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-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 +------------------------------------ + +Running "make install" installs the command pcre-config, which can be used to +recall information about the PCRE configuration and installation. For example: + + pcre-config --version + +prints the version number, and + + pcre-config --libs + +outputs information about where the library is installed. This command can be +included in makefiles for programs that use PCRE, saving the programmer from +having to remember too many details. + +The pkg-config command is another system for saving and retrieving information +about installed libraries. Instead of separate commands for each library, a +single command is used. For example: + + pkg-config --cflags pcre + +The data is held in *.pc files that are installed in a directory called +/lib/pkgconfig. + + +Shared libraries +---------------- + +The default distribution builds PCRE as shared libraries and static libraries, +as long as the operating system supports shared libraries. Shared library +support relies on the "libtool" script which is built as part of the +"configure" process. + +The libtool script is used to compile and link both shared and static +libraries. They are placed in a subdirectory called .libs when they are newly +built. The programs pcretest and pcregrep are built to use these uninstalled +libraries (by means of wrapper scripts in the case of shared libraries). When +you use "make install" to install shared libraries, pcregrep and pcretest are +automatically re-built to use the newly installed shared libraries before being +installed themselves. However, the versions left in the build directory still +use the uninstalled libraries. + +To build PCRE using static libraries only you must use --disable-shared when +configuring it. For example: + +./configure --prefix=/usr/gnu --disable-shared + +Then run "make" in the usual way. Similarly, you can use --disable-static to +build only shared libraries. + + +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 +specify --enable-rebuild-chartables, because if you do, the dftables.c source +file is compiled and run on the local host, in order to generate the inbuilt +character tables (the pcre_chartables.c file). This will probably not work, +because dftables.c needs to be compiled with the local compiler, not the cross +compiler. + +When --enable-rebuild-chartables is not specified, pcre_chartables.c is created +by making a copy of pcre_chartables.c.dist, which is a default set of tables +that assumes ASCII code. Cross-compiling with the default tables should not be +a problem. + +If you need to modify the character tables when cross-compiling, you should +move pcre_chartables.c.dist out of the way, then compile dftables.c by hand and +run it on the local host to make a new version of pcre_chartables.c.dist. +Then when you cross-compile PCRE this new version of the tables will be used. + + +Using HP's ANSI C++ compiler (aCC) +---------------------------------- + +Unless C++ support is disabled by specifying the "--disable-cpp" option of the +"configure" script, you must include the "-AA" option in the CXXFLAGS +environment variable in order for the C++ components to compile correctly. + +Also, note that the aCC compiler on PA-RISC platforms may have a defect whereby +needed libraries fail to get included when specifying the "-AA" compiler +option. If you experience unresolved symbols when linking the C++ programs, +use the workaround of specifying the following environment variable prior to +running the "configure" script: + + CXXLDFLAGS="-lstd_v2 -lCsup_v2" + + +Using Sun's compilers for Solaris +--------------------------------- + +A user reports that the following configurations work on Solaris 9 sparcv9 and +Solaris 9 x86 (32-bit): + + Solaris 9 sparcv9: ./configure --disable-cpp CC=/bin/cc CFLAGS="-m64 -g" + Solaris 9 x86: ./configure --disable-cpp CC=/bin/cc CFLAGS="-g" + + +Using PCRE from MySQL +--------------------- + +On systems where both PCRE and MySQL are installed, it is possible to make use +of PCRE from within MySQL, as an alternative to the built-in pattern matching. +There is a web page that tells you how to do this: + + http://www.mysqludf.org/lib_mysqludf_preg/index.php + + +Making new tarballs +------------------- + +The command "make dist" creates three PCRE tarballs, in tar.gz, tar.bz2, and +zip formats. The command "make distcheck" does the same, but then does a trial +build of the new distribution to ensure that it works. + +If you have modified any of the man page sources in the doc directory, you +should first run the PrepareRelease script before making a distribution. This +script creates the .txt and HTML forms of the documentation from the man pages. + + +Testing PCRE +------------ + +To test the basic PCRE library on a Unix-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 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 relevant testinput files in the testdata +directory, and compares the output with the contents of the corresponding +testoutput files. Some tests are relevant only when certain build-time options +were selected. For example, the tests for UTF-8/16/32 support are run only if +--enable-utf was used. RunTest outputs a comment when it skips a test. + +Many of the tests that are not skipped are run up to three times. The second +run forces pcre_study() to be called for all patterns except for a few in some +tests that are marked "never study" (see the pcretest program for how this is +done). If JIT support is available, the non-DFA tests are run a third time, +this time with a forced pcre_study() with the PCRE_STUDY_JIT_COMPILE option. + +The entire set of tests is run once for each of the 8-bit, 16-bit and 32-bit +libraries that are enabled. If you want to run just one set of tests, call +RunTest with either the -8, -16 or -32 option. + +RunTest uses a file called testtry to hold the main output from pcretest. +Other files whose names begin with "test" are used as working files in some +tests. To run pcretest on just one or more specific test files, give their +numbers as arguments to RunTest, for example: + + RunTest 2 7 11 + +You can also call RunTest with the single argument "list" to cause it to output +a list of tests. + +The first test file can be fed directly into the perltest.pl script to check +that Perl gives the same results. The only difference you should see is in the +first few lines, where the Perl version is given instead of the PCRE version. + +The second set of tests check pcre_fullinfo(), pcre_study(), +pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error +detection, and run-time flags that are specific to PCRE, as well as the POSIX +wrapper API. It also uses the debugging flags to check some of the internals of +pcre_compile(). + +If you build PCRE with a locale setting that is not the standard C locale, the +character tables may be different (see next paragraph). In some cases, this may +cause failures in the second set of tests. For example, in a locale where the +isprint() function yields TRUE for characters in the range 128-255, the use of +[:isascii:] inside a character class defines a different set of characters, and +this shows up in this test as a difference in the compiled code, which is being +listed for checking. Where the comparison test output contains [\x00-\x7f] the +test will contain [\x00-\xff], and similarly in some other cases. This is not a +bug in PCRE. + +The third set of tests checks pcre_maketables(), the facility for building a +set of character tables for a specific locale and using them instead of the +default tables. The tests make use of the "fr_FR" (French) locale. Before +running the test, the script checks for the presence of this locale by running +the "locale" command. If that command fails, or if it doesn't include "fr_FR" +in the list of available locales, the third test cannot be run, and a comment +is output to say why. If running this test produces instances of the error + + ** Failed to set locale "fr_FR" + +in the comparison output, it means that locale is not available on your system, +despite being listed by "locale". This does not mean that PCRE is broken. + +[If you are trying to run this test on Windows, you may be able to get it to +work by changing "fr_FR" to "french" everywhere it occurs. Alternatively, use +RunTest.bat. The version of RunTest.bat included with PCRE 7.4 and above uses +Windows versions of test 2. More info on using RunTest.bat is included in the +document entitled NON-UNIX-USE.] + +The fourth and fifth tests check the UTF-8/16/32 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/32 mode, UTF-8/16/32 mode, and UTF-8/16/32 +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/32-bit mode. +These are tests that generate different output in the two modes. They are for +general cases, UTF-8/16/32 support, and Unicode property support, respectively. + +The twentieth test is run only in 16/32-bit mode. It tests some specific +16/32-bit features of the DFA matching engine. + +The twenty-first and twenty-second tests are run only in 16/32-bit mode, when the +link size is set to 2 for the 16-bit library. They test reloading pre-compiled patterns. + +The twenty-third and twenty-fourth tests are run only in 16-bit mode. They are for +general cases, and UTF-16 support, respectively. + +The twenty-fifth and twenty-sixth tests are run only in 32-bit mode. They are for +general cases, and UTF-32 support, respectively. + +Character tables +---------------- + +For speed, PCRE uses four tables for manipulating and identifying characters +whose code point values are less than 256. The final argument of the +pcre_compile() function is a pointer to a block of memory containing the +concatenated tables. A call to pcre_maketables() can be used to generate a set +of tables in the current locale. If the final argument for pcre_compile() is +passed as NULL, a set of default tables that is built into the binary is used. + +The source file called pcre_chartables.c contains the default set of tables. By +default, this is created as a copy of pcre_chartables.c.dist, which contains +tables for ASCII coding. However, if --enable-rebuild-chartables is specified +for ./configure, a different version of pcre_chartables.c is built by the +program dftables (compiled from dftables.c), which uses the ANSI C character +handling functions such as isalnum(), isalpha(), isupper(), islower(), etc. to +build the table sources. This means that the default C locale which is set for +your system will control the contents of these default tables. You can change +the default tables by editing pcre_chartables.c and then re-building PCRE. If +you do this, you should take care to ensure that the file does not get +automatically re-generated. The best way to do this is to move +pcre_chartables.c.dist out of the way and replace it with your customized +tables. + +When the dftables program is run as a result of --enable-rebuild-chartables, +it uses the default C locale that is set on your system. It does not pay +attention to the LC_xxx environment variables. In other words, it uses the +system's default locale rather than whatever the compiling user happens to have +set. If you really do want to build a source set of character tables in a +locale that is specified by the LC_xxx variables, you can run the dftables +program by hand with the -L option. For example: + + ./dftables -L pcre_chartables.c.special + +The first two 256-byte tables provide lower casing and case flipping functions, +respectively. The next table consists of three 32-byte bit maps which identify +digits, "word" characters, and white space, respectively. These are used when +building 32-byte bit maps that represent character classes for code points less +than 256. + +The final 256-byte table has bits indicating various character types, as +follows: + + 1 white space character + 2 letter + 4 decimal digit + 8 hexadecimal digit + 16 alphanumeric or '_' + 128 regular expression metacharacter or binary zero + +You should not alter the set of characters that contain the 128 bit, as that +will cause PCRE to malfunction. + + +File manifest +------------- + +The distribution should contain the files listed below. Where a file name is +given as pcre[16|32]_xxx it means that there are three files, one with the name +pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx. + +(A) Source files of the PCRE library functions and their headers: + + dftables.c auxiliary program for building pcre_chartables.c + when --enable-rebuild-chartables is specified + + pcre_chartables.c.dist a default set of character tables that assume ASCII + coding; used, unless --enable-rebuild-chartables is + specified, by copying to pcre[16]_chartables.c + + pcreposix.c ) + pcre[16|32]_byte_order.c ) + pcre[16|32]_compile.c ) + pcre[16|32]_config.c ) + pcre[16|32]_dfa_exec.c ) + pcre[16|32]_exec.c ) + pcre[16|32]_fullinfo.c ) + pcre[16|32]_get.c ) sources for the functions in the library, + pcre[16|32]_globals.c ) and some internal functions that they use + pcre[16|32]_jit_compile.c ) + pcre[16|32]_maketables.c ) + pcre[16|32]_newline.c ) + pcre[16|32]_refcount.c ) + pcre[16|32]_string_utils.c ) + pcre[16|32]_study.c ) + pcre[16|32]_tables.c ) + pcre[16|32]_ucd.c ) + pcre[16|32]_version.c ) + pcre[16|32]_xclass.c ) + pcre_ord2utf8.c ) + pcre_valid_utf8.c ) + pcre16_ord2utf16.c ) + pcre16_utf16_utils.c ) + pcre16_valid_utf16.c ) + pcre32_utf32_utils.c ) + pcre32_valid_utf32.c ) + + pcre[16|32]_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" + + pcrecpp.h public header file for the C++ wrapper + pcrecpparg.h.in template for another C++ header file + pcre_scanner.h public header file for C++ scanner functions + pcrecpp.cc ) + pcre_scanner.cc ) source for the C++ wrapper library + + pcre_stringpiece.h.in template for pcre_stringpiece.h, the header for the + C++ stringpiece functions + pcre_stringpiece.cc source for the C++ stringpiece functions + +(B) Source files for programs that use PCRE: + + pcredemo.c simple demonstration of coding calls to PCRE + pcregrep.c source of a grep utility that uses PCRE + pcretest.c comprehensive test program + +(C) Auxiliary files: + + 132html script to turn "man" pages into HTML + AUTHORS information about the author of PCRE + ChangeLog log of changes to the code + CleanTxt script to clean nroff output for txt man pages + Detrail script to remove trailing spaces + HACKING some notes about the internals of PCRE + INSTALL generic installation instructions + LICENCE conditions for the use of PCRE + COPYING the same, using GNU's standard name + Makefile.in ) template for Unix Makefile, which is built by + ) "configure" + Makefile.am ) the automake input that was used to create + ) Makefile.in + NEWS important changes in this release + 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 + RunGrepTest a Unix shell script for pcregrep tests + aclocal.m4 m4 macros (generated by "aclocal") + config.guess ) files used by libtool, + config.sub ) used only when building a shared library + configure a configuring shell script (built by autoconf) + configure.ac ) the autoconf input that was used to build + ) "configure" and config.h + depcomp ) script to find program dependencies, generated by + ) automake + doc/*.3 man page sources for PCRE + doc/*.1 man page sources for pcregrep and pcretest + doc/index.html.src the base HTML page + doc/html/* HTML documentation + doc/pcre.txt plain text version of the man pages + 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 + libpcre32.pc.in template for libpcre32.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 + ltmain.sh file used to build a libtool script + missing ) common stub for a few missing GNU programs while + ) installing, generated by automake + 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 + +(E) Auxiliary files for VPASCAL + + makevp.bat + makevp_c.txt + makevp_l.txt + pcregexp.pas + +(F) Auxiliary files for building PCRE "by hand" + + pcre.h.generic ) a version of the public PCRE header file + ) for use in non-"configure" environments + config.h.generic ) a version of config.h for use in non-"configure" + ) environments + +(F) Miscellaneous + + RunTest.bat a script for running tests under Windows + +Philip Hazel +Email local part: ph10 +Email domain: cam.ac.uk +Last updated: 27 October 2012 diff --git a/tools/pcre/RunGrepTest b/tools/pcre/RunGrepTest new file mode 100644 index 00000000..94fd808f --- /dev/null +++ b/tools/pcre/RunGrepTest @@ -0,0 +1,551 @@ +#! /bin/sh + +# Run pcregrep tests. The assumption is that the PCRE tests check the library +# itself. What we are checking here is the file handling and options that are +# supported by pcregrep. This script must be run in the build directory. + +# 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 + +# Remember the current (build) directory, set the program to be tested, and +# valgrind settings when requested. + +builddir=`pwd` +pcregrep=$builddir/pcregrep + +valgrind= +while [ $# -gt 0 ] ; do + case $1 in + valgrind) valgrind="valgrind -q --leak-check=no --smc-check=all";; + *) echo "RunGrepTest: Unknown argument $1"; exit 1;; + esac + shift +done + +echo " " +pcregrep_version=`$pcregrep -V` +if [ "$valgrind" = "" ] ; then + echo "Testing $pcregrep_version" +else + echo "Testing $pcregrep_version using valgrind" +fi + +# 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" +diff -b /dev/null /dev/null 2>/dev/null && cf="diff -b" +diff -u /dev/null /dev/null 2>/dev/null && cf="diff -u" +diff -ub /dev/null /dev/null 2>/dev/null && cf="diff -ub" + +# If this test is being run from "make check", $srcdir will be set. If not, set +# it to the current or parent directory, whichever one contains the test data. +# Subsequently, we run most of the pcregrep tests in the source directory so +# that the file names in the output are always the same. + +if [ -z "$srcdir" -o ! -d "$srcdir/testdata" ] ; then + 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 utf >/dev/null +utf8=$? + +echo "Testing pcregrep main features" + +echo "---------------------------- Test 1 ------------------------------" >testtry +(cd $srcdir; $valgrind $pcregrep PATTERN ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 2 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep '^PATTERN' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 3 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 4 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -ic PATTERN ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 5 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 6 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 7 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 8 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 9 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 10 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 11 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -vn pattern ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 12 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -ix pattern ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 13 -----------------------------" >>testtry +echo seventeen >testtemp1 +(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist -f $builddir/testtemp1 ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 14 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 15 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep 'abc^*' ./testdata/grepinput) 2>>testtry >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 16 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtry >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 17 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -M 'the\noutput' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 18 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 19 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -Mix 'Pattern' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 20 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 21 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -nA3 'four' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 22 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -nB3 'four' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 23 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -C3 'four' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 24 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -A9 'four' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 25 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -nB9 'four' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 26 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -A9 -B9 'four' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 27 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -A10 'four' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 28 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -nB10 'four' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 29 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -C12 -B10 'four' ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 30 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 31 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 32 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 33 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep 'fox' ./testdata/grepnonexist) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 34 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -s 'fox' ./testdata/grepnonexist) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 35 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --include grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 36 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 37 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep '^(a+)*\d' ./testdata/grepinput) >>testtry 2>teststderr +echo "RC=$?" >>testtry +echo "======== STDERR ========" >>testtry +cat teststderr >>testtry + +echo "---------------------------- Test 38 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep '>\x00<' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 39 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -A1 'before the binary zero' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 40 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -B1 'after the binary zero' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 41 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 42 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 43 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -on 'before|zero|after' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 44 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -on -e before -ezero -e after ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 45 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 46 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -eabc -e '(unclosed' ./testdata/grepinput) 2>>testtry >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 47 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -Fx "AB.VE +elephant" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 48 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -F "AB.VE +elephant" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 49 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -F -e DATA -e "AB.VE +elephant" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 50 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 51 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -Mv "brown\sfox" ./testdata/grepinputv) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 52 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --colour=always jumps ./testdata/grepinputv) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 53 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 54 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 55 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist --color=always ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 56 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -c lazy ./testdata/grepinput*) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 57 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -c -l lazy ./testdata/grepinput*) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 58 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --regex=PATTERN ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 59 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --regexp=PATTERN ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 60 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --regex PATTERN ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 61 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --regexp PATTERN ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 62 -----------------------------" >>testtry +(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 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 64 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o1 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 65 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 66 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o3 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 67 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o12 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 68 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 69 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -vn --colour=always pattern ./testdata/grepinputx) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 70 -----------------------------" >>testtry +(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 +echo testdata/grepinput3 >testtemp1 +(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist --file-list $builddir/testtemp1 "fox|complete|t7") >>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 + +echo "---------------------------- Test 94 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --include grepinput8 'fox' ./testdata/grepinput* | sort) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 95 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist --exclude grepinputv "fox|complete") >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 96 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -L -r --include-dir=testdata --exclude '^(?!grepinput)' 'fox' ./test* | sort) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 97 -----------------------------" >>testtry +echo "grepinput$" >testtemp1 +echo "grepinput8" >>testtemp1 +(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude-from $builddir/testtemp1 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 98 -----------------------------" >>testtry +echo "grepinput$" >testtemp1 +echo "grepinput8" >>testtemp1 +(cd $srcdir; $valgrind $pcregrep -L -r --exclude=grepinput3 --include=grepinput --exclude-from $builddir/testtemp1 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 99 -----------------------------" >>testtry +echo "grepinput$" >testtemp1 +echo "grepinput8" >testtemp2 +(cd $srcdir; $valgrind $pcregrep -L -r --include grepinput --exclude-from $builddir/testtemp1 --exclude-from=$builddir/testtemp2 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 100 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -Ho2 --only-matching=1 -o3 '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 101 ------------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o3 -Ho2 -o12 --only-matching=1 -o3 --colour=always --om-separator='|' '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + + +# Now compare the results. + +$cf $srcdir/testdata/grepoutput testtry +if [ $? != 0 ] ; then exit 1; fi + + +# These tests require UTF-8 support + +if [ $utf8 -ne 0 ] ; then + echo "Testing pcregrep UTF-8 features" + + echo "---------------------------- Test U1 ------------------------------" >testtry + (cd $srcdir; $valgrind $pcregrep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtry + echo "RC=$?" >>testtry + + echo "---------------------------- Test U2 ------------------------------" >>testtry + (cd $srcdir; $valgrind $pcregrep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtry + echo "RC=$?" >>testtry + + $cf $srcdir/testdata/grepoutput8 testtry + if [ $? != 0 ] ; then exit 1; fi + +else + echo "Skipping pcregrep UTF-8 tests: no UTF-8 support in PCRE library" +fi + + +# We go to some contortions to try to ensure that the tests for the various +# newline settings will work in environments where the normal newline sequence +# is not \n. Do not use exported files, whose line endings might be changed. +# Instead, create an input file using printf so that its contents are exactly +# what we want. Note the messy fudge to get printf to write a string that +# starts with a hyphen. These tests are run in the build directory. + +echo "Testing pcregrep newline settings" +printf "abc\rdef\r\nghi\njkl" >testNinput + +printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtry +$valgrind $pcregrep -n -N CR "^(abc|def|ghi|jkl)" testNinput >>testtry + +printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtry +$valgrind $pcregrep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinput >>testtry + +printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtry +pattern=`printf 'def\rjkl'` +$valgrind $pcregrep -n --newline=cr -F "$pattern" testNinput >>testtry + +printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>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 + +printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtry +$valgrind $pcregrep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinput >>testtry + +$cf $srcdir/testdata/grepoutputN testtry +if [ $? != 0 ] ; then exit 1; fi + +exit 0 + +# End diff --git a/tools/pcre/RunTest b/tools/pcre/RunTest new file mode 100644 index 00000000..546e6e53 --- /dev/null +++ b/tools/pcre/RunTest @@ -0,0 +1,1015 @@ +#! /bin/sh + +# Run the PCRE tests using the pcretest program. The appropriate tests are +# selected, depending on which build-time options were used. +# +# 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-, 16- and 32-bit libraries exist are tested. It is also +# possible to select which to test by the arguments -8, -16 or -32. +# +# Other arguments for this script can be individual test numbers, or the word +# "valgrind", "valgrind-log" or "sim" followed by an argument to run cross- +# compiled executables under a simulator, for example: +# +# RunTest 3 sim "qemu-arm -s 8388608" +# +# +# There are two special cases where only one argument is allowed: +# +# If the first and only argument is "ebcdic", the script runs the special +# EBCDIC test that can be useful for checking certain EBCDIC features, even +# when run in an ASCII environment. +# +# 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/32-bit library" +title18="Test 18: Specials for the 16/32-bit library with UTF-16/32 support" +title19="Test 19: Specials for the 16/32-bit library with Unicode property support" +title20="Test 20: DFA specials for the basic 16/32-bit library" +title21="Test 21: Reloads for the basic 16/32-bit library" +title22="Test 22: Reloads for the 16/32-bit library with UTF-16/32 support" +title23="Test 23: Specials for the 16-bit library" +title24="Test 24: Specials for the 16-bit library with UTF-16 support" +title25="Test 25: Specials for the 32-bit library" +title26="Test 26: Specials for the 32-bit library with UTF-32 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 + echo $title23 + echo $title24 + echo $title25 + echo $title26 + exit 0 +fi + +# Set up a suitable "diff" command for comparison. Some systems +# have a diff that lacks a -u option. Try to deal with this. + +cf="diff" +diff -u /dev/null /dev/null 2>/dev/null && cf="diff -u" + +# 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 + + +# ------ Special EBCDIC Test ------- + +if [ $# -eq 1 -a "$1" = "ebcdic" ]; then + ./pcretest -C ebcdic >/dev/null + ebcdic=$? + if [ $ebcdic -ne 1 ] ; then + echo "Cannot run EBCDIC tests: EBCDIC support not compiled" + exit 1 + fi + + for opt in "" "-s" "-dfa" "-s -dfa"; do + ./pcretest -q $opt $testdata/testinputEBC >testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutputEBC testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-dfa" ] ; then echo " OK using DFA" + elif [ "$opt" = "-s -dfa" ] ; then echo " OK using DFA with study" + else echo " OK" + fi + done + +exit 0 +fi + + +# ------ Normal Tests ------ + +# Default values + +valgrind= +sim= +arg8= +arg16= +arg32= + +# 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. + +do1=no +do2=no +do3=no +do4=no +do5=no +do6=no +do7=no +do8=no +do9=no +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 +do23=no +do24=no +do25=no +do26=no + +while [ $# -gt 0 ] ; do + case $1 in + 1) do1=yes;; + 2) do2=yes;; + 3) do3=yes;; + 4) do4=yes;; + 5) do5=yes;; + 6) do6=yes;; + 7) do7=yes;; + 8) do8=yes;; + 9) do9=yes;; + 10) do10=yes;; + 11) do11=yes;; + 12) do12=yes;; + 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;; + 23) do23=yes;; + 24) do24=yes;; + 25) do25=yes;; + 26) do26=yes;; + -8) arg8=yes;; + -16) arg16=yes;; + -32) arg32=yes;; + valgrind) valgrind="valgrind --tool=memcheck -q --smc-check=all";; + valgrind-log) valgrind="valgrind --tool=memcheck --num-callers=30 --leak-check=no --error-limit=no --smc-check=all --log-file=report.%p ";; + sim) shift; sim=$1;; + *) echo "Unknown test number '$1'"; exit 1;; + esac + shift +done + +# Find which optional facilities are available. + +$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 + +# All of 8-bit, 16-bit, and 32-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=$? +$sim ./pcretest -C pcre32 >/dev/null +support32=$? + +# Initialize all bitsizes skipped + +test8=skip +test16=skip +test32=skip + +# If no bitsize arguments, select all that are available + +if [ "$arg8$arg16$arg32" = "" ] ; then + if [ $support8 -ne 0 ] ; then + test8= + fi + if [ $support16 -ne 0 ] ; then + test16=-16 + fi + if [ $support32 -ne 0 ] ; then + test32=-32 + fi + +# Select requested bit sizes + +else + if [ "$arg8" = yes ] ; then + if [ $support8 -eq 0 ] ; then + echo "Cannot run 8-bit library tests: 8-bit library not compiled" + exit 1 + fi + test8= + fi + if [ "$arg16" = yes ] ; then + if [ $support16 -eq 0 ] ; then + echo "Cannot run 16-bit library tests: 16-bit library not compiled" + exit 1 + fi + test16=-16 + fi + if [ "$arg32" = yes ] ; then + if [ $support32 -eq 0 ] ; then + echo "Cannot run 32-bit library tests: 32-bit library not compiled" + exit 1 + fi + test32=-32 + fi +fi + +# UTF support always applies to all 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 support is not configured" + exit 1 + fi + if [ $do5 = yes ] ; then + echo "Can't run test 5 because UTF support is not configured" + exit 1 + fi + 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 + if [ $do6 = yes ] ; then + echo "Can't run test 6 because Unicode property support is not configured" + exit 1 + fi + 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 [ $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 [ $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. 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 -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 -a $do23 = no -a $do24 = no -a \ + $do25 = no -a $do26 = no ] ; then + do1=yes + do2=yes + do3=yes + do4=yes + do5=yes + do6=yes + do7=yes + do8=yes + do9=yes + do10=yes + do11=yes + do12=yes + do13=yes + do14=yes + do15=yes + do16=yes + do17=yes + do18=yes + do19=yes + do20=yes + do21=yes + do22=yes + do23=yes + do24=yes + do25=yes + do26=yes +fi + +# Show which release and which test data + +echo "" +echo PCRE C library tests using test data from $testdata +$sim ./pcretest /dev/null + +for bmode in "$test8" "$test16" "$test32"; do + case "$bmode" in + skip) continue;; + -16) if [ "$test8$test32" != "skipskip" ] ; then echo ""; fi + bits=16; echo "---- Testing 16-bit library ----"; echo "";; + -32) if [ "$test8$test16" != "skipskip" ] ; then echo ""; fi + bits=32; echo "---- Testing 32-bit library ----"; echo "";; + *) bits=8; echo "---- Testing 8-bit library ----"; echo "";; + esac + +# Primary test, compatible with JIT and all versions of Perl >= 5.8 + +if [ $do1 = yes ] ; then + 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 JIT or Perl-compatible: API, errors, internals + +if [ $do2 = yes ] ; then + 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. 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 + if [ $? -eq 0 ] ; then + locale=fr_FR + 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 + else + 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 $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 + done + else + 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 UTF support + +if [ $do4 = yes ] ; then + 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 +fi + +if [ $do5 = yes ] ; then + 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 +fi + +if [ $do6 = yes ] ; then + 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 +fi + +# Test non-Perl-compatible Unicode property support + +if [ $do7 = yes ] ; then + 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 +fi + +# Tests for DFA matching support + +if [ $do8 = yes ] ; then + 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 ${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 +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 output from +# this test is not the same in 8-bit and 16-bit modes. + +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 +fi + +# Test JIT-specific features when JIT is available + +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 +fi + +# Test JIT-specific features when JIT is not available + +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" -o "$bits" = "32" ] ; then + echo " Skipped when running 16/32-bit tests" + else + cp -f $testdata/saved16 testsaved16 + cp -f $testdata/saved32 testsaved32 + 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" -o "$bits" = "32" ] ; then + echo " Skipped when running 16/32-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" -o "$bits" = "32" ] ; then + echo " Skipped when running 16/32-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/32-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/32-bit-specific features (UTF-16/32 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-$bits 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/32-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/32-bit-specific features in DFA non-UTF-16/32 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 -dfa $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/32-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 + cp -f $testdata/saved32LE-1 testsaved32LE-1 + cp -f $testdata/saved32BE-1 testsaved32BE-1 + $sim $valgrind ./pcretest -q $bmode $testdata/testinput21 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput21-$bits testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo " OK" + fi +fi + +# Tests for reloads with 16/32-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 + cp -f $testdata/saved32LE-2 testsaved32LE-2 + cp -f $testdata/saved32BE-2 testsaved32BE-2 + $sim $valgrind ./pcretest -q $bmode $testdata/testinput22 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput22-$bits testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo " OK" + fi +fi + +if [ $do23 = yes ] ; then + echo $title23 + if [ "$bits" = "8" -o "$bits" = "32" ] ; then + echo " Skipped when running 8/32-bit tests" + else + $sim $valgrind ./pcretest -q $bmode $testdata/testinput23 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput23 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo " OK" + fi +fi + +if [ $do24 = yes ] ; then + echo $title24 + if [ "$bits" = "8" -o "$bits" = "32" ] ; then + echo " Skipped when running 8/32-bit tests" + elif [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + $sim $valgrind ./pcretest -q $bmode $testdata/testinput24 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput24 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo " OK" + fi +fi + +if [ $do25 = yes ] ; then + echo $title25 + if [ "$bits" = "8" -o "$bits" = "16" ] ; then + echo " Skipped when running 8/16-bit tests" + else + $sim $valgrind ./pcretest -q $bmode $testdata/testinput25 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput25 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo " OK" + fi +fi + +if [ $do26 = yes ] ; then + echo $title26 + if [ "$bits" = "8" -o "$bits" = "16" ] ; then + echo " Skipped when running 8/16-bit tests" + elif [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + $sim $valgrind ./pcretest -q $bmode $testdata/testinput26 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput26 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo " OK" + fi +fi + +# End of loop for 8/16/32-bit tests +done + +# Clean up local working files +rm -f test3input test3output testNinput testsaved* teststderr teststdout testtry + +# End diff --git a/tools/pcre/RunTest.bat b/tools/pcre/RunTest.bat new file mode 100644 index 00000000..e09b2d29 --- /dev/null +++ b/tools/pcre/RunTest.bat @@ -0,0 +1,616 @@ +@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 +@rem Zoltan Herczeg added libpcre32 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 pcre32 >NUL +set support32=%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 +) + +if %support16% EQU 1 ( +if not exist testout32 md testout32 +if not exist testoutstudy32 md testoutstudy32 +if not exist testoutjit32 md testoutjit32 +) + +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 do21=no +set do22=no +set do23=no +set do24=no +set do25=no +set do26=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 21 22 23 24 25 26) 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 26, 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 + set do21=yes + set do22=yes + set do23=yes + set do24=yes + set do25=yes + set do26=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. +) +if "%mode%" == "-16" ( + if %support16% EQU 0 goto modeSkip + echo. + echo ---- Testing 16-bit library ---- + echo. +) +if "%mode%" == "-32" ( + if %support32% EQU 0 goto modeSkip + echo. + echo ---- Testing 32-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 +if "%do21%" == "yes" call :do21 +if "%do22%" == "yes" call :do22 +if "%do23%" == "yes" call :do23 +if "%do24%" == "yes" call :do24 +if "%do25%" == "yes" call :do25 +if "%do26%" == "yes" call :do26 +:modeSkip +if "%mode%" == "" ( + set mode=-16 + set bits=16 + goto nextMode +) +if "%mode%" == "-16" ( + set mode=-32 + set bits=32 + goto nextMode +) + +@rem If mode is -32, testing is finished +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 +) + +set type= +if [%1]==[11] ( + set type=-%bits% +) +if [%1]==[18] ( + set type=-%bits% +) +if [%1]==[21] ( + set type=-%bits% +) +if [%1]==[22] ( + set type=-%bits% +) + +fc /n %srcdir%\testdata\%testoutput%%type% %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.10)" -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" -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.10)" -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%" -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 (JIT available)" -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 (JIT not available)" -q +goto :eof + +:do14 +if NOT %bits% EQU 8 ( + echo Test 14 Skipped when running 16/32-bit tests. + goto :eof +) + copy /Y %srcdir%\testdata\saved16 testsaved16 + copy /Y %srcdir%\testdata\saved32 testsaved32 + 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/32-bit tests. + goto :eof +) +if %utf% EQU 0 ( + echo Test 15 Skipped due to absence of UTF-%bits% support. + goto :eof +) + call :runsub 15 testout "Specials for the 8-bit library with UTF-%bits% 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/32-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 %bits% EQU 8 ( + echo Test 17 Skipped when running 8-bit tests. + goto :eof +) + call :runsub 17 testout "Specials for the basic 16/32-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 %bits% EQU 8 ( + echo Test 18 Skipped when running 8-bit tests. + goto :eof +) +if %utf% EQU 0 ( + echo Test 18 Skipped due to absence of UTF-%bits% support. + goto :eof +) + call :runsub 18 testout "Specials for the 16/32-bit library with UTF-%bits% support" -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 %bits% EQU 8 ( + 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 16/32-bit library with Unicode property support" -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 %bits% EQU 8 ( + echo Test 20 Skipped when running 8-bit tests. + goto :eof +) + call :runsub 20 testout "DFA specials for the basic 16/32-bit library" -q -dfa + call :runsub 20 testoutstudy "Test with Study Override" -q -dfa -s +goto :eof + +:do21 +if %bits% EQU 8 ( + echo Test 21 Skipped when running 8-bit tests. + goto :eof +) +if NOT %link_size% EQU 2 ( + echo Test 21 Skipped because link size is not 2. + goto :eof +) +copy /Y %srcdir%\testdata\saved8 testsaved8 +copy /Y %srcdir%\testdata\saved16LE-1 testsaved16LE-1 +copy /Y %srcdir%\testdata\saved16BE-1 testsaved16BE-1 +copy /Y %srcdir%\testdata\saved32LE-1 testsaved32LE-1 +copy /Y %srcdir%\testdata\saved32BE-1 testsaved32BE-1 +call :runsub 21 testout "Reloads for the basic 16/32-bit library" -q +call :runsub 21 testoutstudy "Test with Study Override" -q -s +if %jit% EQU 1 call :runsub 21 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do22 +if %bits% EQU 8 ( + echo Test 22 Skipped when running 8-bit tests. + goto :eof +) +if %utf% EQU 0 ( + echo Test 22 Skipped due to absence of UTF-%bits% support. + goto :eof +) +if NOT %link_size% EQU 2 ( + echo Test 22 Skipped because link size is not 2. + goto :eof +) +copy /Y %srcdir%\testdata\saved16LE-2 testsaved16LE-2 +copy /Y %srcdir%\testdata\saved16BE-2 testsaved16BE-2 +copy /Y %srcdir%\testdata\saved32LE-2 testsaved32LE-2 +copy /Y %srcdir%\testdata\saved32BE-2 testsaved32BE-2 +call :runsub 22 testout "Reloads for the 16/32-bit library with UTF-16/32 support" -q +call :runsub 22 testoutstudy "Test with Study Override" -q -s +if %jit% EQU 1 call :runsub 22 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do23 +if NOT %bits% EQU 16 ( + echo Test 23 Skipped when running 8/32-bit tests. + goto :eof +) +call :runsub 23 testout "Specials for the 16-bit library" -q +call :runsub 23 testoutstudy "Test with Study Override" -q -s +if %jit% EQU 1 call :runsub 23 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do24 +if NOT %bits% EQU 16 ( + echo Test 24 Skipped when running 8/32-bit tests. + goto :eof +) +if %utf% EQU 0 ( + echo Test 24 Skipped due to absence of UTF-%bits% support. + goto :eof +) +call :runsub 24 testout "Specials for the 16-bit library with UTF-16 support" -q +call :runsub 24 testoutstudy "Test with Study Override" -q -s +if %jit% EQU 1 call :runsub 24 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do25 +if NOT %bits% EQU 32 ( + echo Test 25 Skipped when running 8/16-bit tests. + goto :eof +) +call :runsub 25 testout "Specials for the 32-bit library" -q +call :runsub 25 testoutstudy "Test with Study Override" -q -s +if %jit% EQU 1 call :runsub 25 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do26 +if NOT %bits% EQU 32 ( + echo Test 26 Skipped when running 8/16-bit tests. + goto :eof +) +if %utf% EQU 0 ( + echo Test 26 Skipped due to absence of UTF-%bits% support. + goto :eof +) +call :runsub 26 testout "Specials for the 32-bit library with UTF-32 support" -q +call :runsub 26 testoutstudy "Test with Study Override" -q -s +if %jit% EQU 1 call :runsub 26 testoutjit "Test with JIT 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 --git a/tools/pcre/aclocal.m4 b/tools/pcre/aclocal.m4 new file mode 100644 index 00000000..56fceecf --- /dev/null +++ b/tools/pcre/aclocal.m4 @@ -0,0 +1,1270 @@ +# generated automatically by aclocal 1.11.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +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'.])]) + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES + + +# PKG_INSTALLDIR(DIRECTORY) +# ------------------------- +# Substitutes the variable pkgconfigdir as the location where a module +# should install pkg-config .pc files. By default the directory is +# $libdir/pkgconfig, but the default can be changed by passing +# DIRECTORY. The user can override through the --with-pkgconfigdir +# parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +]) dnl PKG_INSTALLDIR + + +# PKG_NOARCH_INSTALLDIR(DIRECTORY) +# ------------------------- +# Substitutes the variable noarch_pkgconfigdir as the location where a +# module should install arch-independent pkg-config .pc files. By +# default the directory is $datadir/pkgconfig, but the default can be +# changed by passing DIRECTORY. The user can override through the +# --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +]) dnl PKG_NOARCH_INSTALLDIR + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 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_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.6], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.6])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 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 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# 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 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 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 12 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# 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 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 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 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 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_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 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 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 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 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# 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 6 + +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# 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 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 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_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 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 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# 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 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # 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". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2009, 2011 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 2 + +# 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 +dnl +dnl A few `make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using `$V' instead of `$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001, 2003, 2005, 2011 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_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 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 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 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 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/ax_pthread.m4]) +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) +m4_include([m4/pcre_visibility.m4]) diff --git a/tools/pcre/cmake/COPYING-CMAKE-SCRIPTS b/tools/pcre/cmake/COPYING-CMAKE-SCRIPTS new file mode 100644 index 00000000..4b417765 --- /dev/null +++ b/tools/pcre/cmake/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,22 @@ +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 copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. diff --git a/tools/pcre/cmake/FindEditline.cmake b/tools/pcre/cmake/FindEditline.cmake new file mode 100644 index 00000000..2d0b7cc5 --- /dev/null +++ b/tools/pcre/cmake/FindEditline.cmake @@ -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 --git a/tools/pcre/cmake/FindPackageHandleStandardArgs.cmake b/tools/pcre/cmake/FindPackageHandleStandardArgs.cmake new file mode 100644 index 00000000..151d8125 --- /dev/null +++ b/tools/pcre/cmake/FindPackageHandleStandardArgs.cmake @@ -0,0 +1,58 @@ +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME (DEFAULT_MSG|"Custom failure message") VAR1 ... ) +# This macro is intended to be used in FindXXX.cmake modules files. +# It handles the REQUIRED and QUIET argument to FIND_PACKAGE() and +# it also sets the _FOUND variable. +# The package is found if all variables listed are TRUE. +# Example: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) +# +# LibXml2 is considered to be found, if both LIBXML2_LIBRARIES and +# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. +# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, +# independent whether QUIET was used or not. +# If it is found, the location is reported using the VAR1 argument, so +# here a message "Found LibXml2: /usr/lib/libxml2.so" will be printed out. +# If the second argument is DEFAULT_MSG, the message in the failure case will +# be "Could NOT find LibXml2", if you don't like this message you can specify +# your own custom failure message there. + +MACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FAIL_MSG _VAR1 ) + + IF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + IF (${_NAME}_FIND_REQUIRED) + SET(_FAIL_MESSAGE "Could not find REQUIRED package ${_NAME}") + ELSE (${_NAME}_FIND_REQUIRED) + SET(_FAIL_MESSAGE "Could not find OPTIONAL package ${_NAME}") + ENDIF (${_NAME}_FIND_REQUIRED) + ELSE("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + SET(_FAIL_MESSAGE "${_FAIL_MSG}") + ENDIF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + + STRING(TOUPPER ${_NAME} _NAME_UPPER) + + SET(${_NAME_UPPER}_FOUND TRUE) + IF(NOT ${_VAR1}) + SET(${_NAME_UPPER}_FOUND FALSE) + ENDIF(NOT ${_VAR1}) + + FOREACH(_CURRENT_VAR ${ARGN}) + IF(NOT ${_CURRENT_VAR}) + SET(${_NAME_UPPER}_FOUND FALSE) + ENDIF(NOT ${_CURRENT_VAR}) + ENDFOREACH(_CURRENT_VAR) + + IF (${_NAME_UPPER}_FOUND) + IF (NOT ${_NAME}_FIND_QUIETLY) + MESSAGE(STATUS "Found ${_NAME}: ${${_VAR1}}") + ENDIF (NOT ${_NAME}_FIND_QUIETLY) + ELSE (${_NAME_UPPER}_FOUND) + IF (${_NAME}_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "${_FAIL_MESSAGE}") + ELSE (${_NAME}_FIND_REQUIRED) + IF (NOT ${_NAME}_FIND_QUIETLY) + MESSAGE(STATUS "${_FAIL_MESSAGE}") + ENDIF (NOT ${_NAME}_FIND_QUIETLY) + ENDIF (${_NAME}_FIND_REQUIRED) + ENDIF (${_NAME_UPPER}_FOUND) +ENDMACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS) diff --git a/tools/pcre/cmake/FindReadline.cmake b/tools/pcre/cmake/FindReadline.cmake new file mode 100644 index 00000000..1d4cc558 --- /dev/null +++ b/tools/pcre/cmake/FindReadline.cmake @@ -0,0 +1,29 @@ +# from http://websvn.kde.org/trunk/KDE/kdeedu/cmake/modules/FindReadline.cmake +# http://websvn.kde.org/trunk/KDE/kdeedu/cmake/modules/COPYING-CMAKE-SCRIPTS +# --> BSD licensed +# +# GNU Readline library finder +if(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) + set(READLINE_FOUND TRUE) +else(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) + FIND_PATH(READLINE_INCLUDE_DIR readline/readline.h + /usr/include/readline + ) + +# 2008-04-22 The next clause used to read like this: +# +# FIND_LIBRARY(READLINE_LIBRARY NAMES readline) +# FIND_LIBRARY(NCURSES_LIBRARY NAMES ncurses ) +# include(FindPackageHandleStandardArgs) +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG NCURSES_LIBRARY READLINE_INCLUDE_DIR READLINE_LIBRARY ) +# +# I was advised to modify it such that it will find an ncurses library if +# required, but not if one was explicitly given, that is, it allows the +# default to be overridden. PH + + FIND_LIBRARY(READLINE_LIBRARY NAMES readline) + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG READLINE_INCLUDE_DIR READLINE_LIBRARY ) + + MARK_AS_ADVANCED(READLINE_INCLUDE_DIR READLINE_LIBRARY) +endif(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY) diff --git a/tools/pcre/compile b/tools/pcre/compile new file mode 100644 index 00000000..862a14e8 --- /dev/null +++ b/tools/pcre/compile @@ -0,0 +1,343 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-03-05.13; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free +# Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/tools/pcre/config-cmake.h.in b/tools/pcre/config-cmake.h.in new file mode 100644 index 00000000..a93263fa --- /dev/null +++ b/tools/pcre/config-cmake.h.in @@ -0,0 +1,54 @@ +/* config.h for CMake builds */ + +#cmakedefine HAVE_DIRENT_H 1 +#cmakedefine HAVE_SYS_STAT_H 1 +#cmakedefine HAVE_SYS_TYPES_H 1 +#cmakedefine HAVE_UNISTD_H 1 +#cmakedefine HAVE_WINDOWS_H 1 + +#cmakedefine HAVE_TYPE_TRAITS_H 1 +#cmakedefine HAVE_BITS_TYPE_TRAITS_H 1 + +#cmakedefine HAVE_BCOPY 1 +#cmakedefine HAVE_MEMMOVE 1 +#cmakedefine HAVE_STRERROR 1 +#cmakedefine HAVE_STRTOLL 1 +#cmakedefine HAVE_STRTOQ 1 +#cmakedefine HAVE__STRTOI64 1 + +#cmakedefine PCRE_STATIC 1 + +#cmakedefine SUPPORT_PCRE8 1 +#cmakedefine SUPPORT_PCRE16 1 +#cmakedefine SUPPORT_PCRE32 1 +#cmakedefine SUPPORT_JIT 1 +#cmakedefine SUPPORT_PCREGREP_JIT 1 +#cmakedefine SUPPORT_UTF 1 +#cmakedefine SUPPORT_UCP 1 +#cmakedefine EBCDIC 1 +#cmakedefine EBCDIC_NL25 1 +#cmakedefine BSR_ANYCRLF 1 +#cmakedefine NO_RECURSE 1 + +#cmakedefine HAVE_LONG_LONG 1 +#cmakedefine HAVE_UNSIGNED_LONG_LONG 1 + +#cmakedefine SUPPORT_LIBBZ2 1 +#cmakedefine SUPPORT_LIBZ 1 +#cmakedefine SUPPORT_LIBEDIT 1 +#cmakedefine SUPPORT_LIBREADLINE 1 + +#cmakedefine SUPPORT_VALGRIND 1 +#cmakedefine SUPPORT_GCOV 1 + +#define NEWLINE @NEWLINE@ +#define POSIX_MALLOC_THRESHOLD @PCRE_POSIX_MALLOC_THRESHOLD@ +#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 + +/* end config.h for CMake builds */ diff --git a/tools/pcre/config.guess b/tools/pcre/config.guess new file mode 100644 index 00000000..68194c9c --- /dev/null +++ b/tools/pcre/config.guess @@ -0,0 +1,1552 @@ +#! /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, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-08-14' + +# 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +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, 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." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +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 +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +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" 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) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU/*) + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #ifdef __UCLIBC__ + # ifdef __UCLIBC_CONFIG_VERSION__ + LIBC=uclibc __UCLIBC_CONFIG_VERSION__ + # else + LIBC=uclibc + # endif + #else + # ifdef __dietlibc__ + LIBC=dietlibc + # else + LIBC=gnu + # endif + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # 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 + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # 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'` + # 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 + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # 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} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # 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 ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 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" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + 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); + + 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 + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + 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 ;; + 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}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *: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 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + 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 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + 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 ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + 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} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + 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, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + 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. + # 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 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /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; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + 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 + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + 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` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/tools/pcre/config.h.generic b/tools/pcre/config.h.generic new file mode 100644 index 00000000..98801a81 --- /dev/null +++ b/tools/pcre/config.h.generic @@ -0,0 +1,392 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* PCRE is written in Standard C, but there are a few non-standard things it +can cope with, allowing it to run on SunOS4 and other "close to standard" +systems. + +In environments that support the facilities, config.h.in is converted by +"configure", or config-cmake.h.in is converted by CMake, into config.h. If you +are going to build PCRE "by hand" without using "configure" or CMake, you +should copy the distributed config.h.generic to config.h, and then edit the +macro definitions to be the way you need them. You must then add +-DHAVE_CONFIG_H to all of your compile commands, so that config.h is included +at the start of every source. + +Alternatively, you can avoid editing by using -D on the compiler command line +to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H. + +PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if +HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set +them both to 0; an emulation function will be used. */ + +/* By default, the \R escape sequence matches any Unicode line ending + character or sequence of characters. If BSR_ANYCRLF is defined (to any + value), this is changed so that backslash-R matches only CR, LF, or CRLF. + The build-time default can be overridden by the user of PCRE at runtime. */ +/* #undef BSR_ANYCRLF */ + +/* If you are compiling for a system that uses EBCDIC instead of ASCII + character codes, define this macro to any value. You must also edit the + NEWLINE macro below to set a suitable EBCDIC newline, commonly 21 (0x15). + On systems that can use "configure" or CMake to set EBCDIC, NEWLINE is + automatically adjusted. When EBCDIC is set, PCRE assumes that all input + strings are in EBCDIC. If you do not define this macro, PCRE will assume + input strings are ASCII or UTF-8/16/32 Unicode. It is not possible to build + a version of PCRE that supports both EBCDIC and UTF-8/16/32. */ +/* #undef EBCDIC */ + +/* In an EBCDIC environment, define this macro to any value to arrange for the + NL character to be 0x25 instead of the default 0x15. NL plays the role that + LF does in an ASCII/Unicode environment. The value must also be set in the + NEWLINE macro below. On systems that can use "configure" or CMake to set + EBCDIC_NL25, the adjustment of NEWLINE is automatic. */ +/* #undef EBCDIC_NL25 */ + +/* Define to 1 if you have the `bcopy' function. */ +#ifndef HAVE_BCOPY +#define HAVE_BCOPY 1 +#endif + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BITS_TYPE_TRAITS_H */ + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_BZLIB_H +#define HAVE_BZLIB_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_DIRENT_H +#define HAVE_DIRENT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_DLFCN_H +#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 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_LIMITS_H +#define HAVE_LIMITS_H 1 +#endif + +/* Define to 1 if the system has the type `long long'. */ +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG 1 +#endif + +/* Define to 1 if you have the `memmove' function. */ +#ifndef HAVE_MEMMOVE +#define HAVE_MEMMOVE 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_MEMORY_H +#define HAVE_MEMORY_H 1 +#endif + +/* Define if you have POSIX threads libraries and header files. */ +/* #undef HAVE_PTHREAD */ + +/* Have PTHREAD_PRIO_INHERIT. */ +/* #undef HAVE_PTHREAD_PRIO_INHERIT */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READLINE_HISTORY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READLINE_READLINE_H */ + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_STDLIB_H +#define HAVE_STDLIB_H 1 +#endif + +/* Define to 1 if you have the `strerror' function. */ +#ifndef HAVE_STRERROR +#define HAVE_STRERROR 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_STRING +#define HAVE_STRING 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_STRINGS_H +#define HAVE_STRINGS_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_STRING_H +#define HAVE_STRING_H 1 +#endif + +/* Define to 1 if you have `strtoimax'. */ +/* #undef HAVE_STRTOIMAX */ + +/* Define to 1 if you have `strtoll'. */ +/* #undef HAVE_STRTOLL */ + +/* Define to 1 if you have `strtoq'. */ +#ifndef HAVE_STRTOQ +#define HAVE_STRTOQ 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_SYS_STAT_H +#define HAVE_SYS_STAT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_SYS_TYPES_H +#define HAVE_SYS_TYPES_H 1 +#endif + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TYPE_TRAITS_H */ + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_UNISTD_H +#define HAVE_UNISTD_H 1 +#endif + +/* Define to 1 if the system has the type `unsigned long long'. */ +#ifndef HAVE_UNSIGNED_LONG_LONG +#define HAVE_UNSIGNED_LONG_LONG 1 +#endif + +/* Define to 1 or 0, depending whether the compiler supports simple visibility + declarations. */ +#ifndef HAVE_VISIBILITY +#define HAVE_VISIBILITY 1 +#endif + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if you have the header file. */ +#ifndef HAVE_ZLIB_H +#define HAVE_ZLIB_H 1 +#endif + +/* Define to 1 if you have `_strtoi64'. */ +/* #undef HAVE__STRTOI64 */ + +/* The value of LINK_SIZE determines the number of bytes used to store links + as offsets within the compiled regex. The default is 2, which allows for + compiled patterns up to 64K long. This covers the vast majority of cases. + However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows + for longer patterns in extreme cases. */ +#ifndef LINK_SIZE +#define LINK_SIZE 2 +#endif + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#ifndef LT_OBJDIR +#define LT_OBJDIR ".libs/" +#endif + +/* The value of MATCH_LIMIT determines the default number of times the + internal match() function can be called during a single execution of + pcre_exec(). There is a runtime interface for setting a different limit. + The limit exists in order to catch runaway regular expressions that take + for ever to determine that they do not match. The default is set very large + so that it does not accidentally catch legitimate cases. */ +#ifndef MATCH_LIMIT +#define MATCH_LIMIT 10000000 +#endif + +/* The above limit applies to all calls of match(), whether or not they + increase the recursion depth. In some environments it is desirable to limit + the depth of recursive calls of match() more strictly, in order to restrict + the maximum amount of stack (or heap, if NO_RECURSE is defined) that is + used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of + match(). To have any useful effect, it must be less than the value of + MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is + a runtime method for setting a different limit. */ +#ifndef MATCH_LIMIT_RECURSION +#define MATCH_LIMIT_RECURSION MATCH_LIMIT +#endif + +/* This limit is parameterized just in case anybody ever wants to change it. + Care must be taken if it is increased, because it guards against integer + overflow caused by enormously large patterns. */ +#ifndef MAX_NAME_COUNT +#define MAX_NAME_COUNT 10000 +#endif + +/* This limit is parameterized just in case anybody ever wants to change it. + Care must be taken if it is increased, because it guards against integer + overflow caused by enormously large patterns. */ +#ifndef MAX_NAME_SIZE +#define MAX_NAME_SIZE 32 +#endif + +/* The value of NEWLINE determines the default newline character sequence. + PCRE client programs can override this by selecting other values at run + time. In ASCII environments, the value can be 10 (LF), 13 (CR), or 3338 + (CRLF); in EBCDIC environments the value can be 21 or 37 (LF), 13 (CR), or + 3349 or 3365 (CRLF) because there are two alternative codepoints (0x15 and + 0x25) that are used as the NL line terminator that is equivalent to ASCII + LF. In both ASCII and EBCDIC environments the value can also be -1 (ANY), + or -2 (ANYCRLF). */ +#ifndef NEWLINE +#define NEWLINE 10 +#endif + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* PCRE uses recursive function calls to handle backtracking while matching. + This can sometimes be a problem on systems that have stacks of limited + size. Define NO_RECURSE to any value to get a version that doesn't use + recursion in the match() function; instead it creates its own stack by + steam using pcre_recurse_malloc() to obtain memory from the heap. For more + detail, see the comments and other stuff just above the match() function. + */ +/* #undef NO_RECURSE */ + +/* Name of package */ +#define PACKAGE "pcre" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "PCRE" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "PCRE 8.32" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "pcre" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "8.32" + +/* The value of PCREGREP_BUFSIZE determines the size of buffer used by + pcregrep to hold parts of the file it is searching. 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 + Win32, and it needs some magic to be inserted before the definition + of a function that is exported by the library, define this macro to + contain the relevant magic. If you do not define this macro, a suitable + __declspec value is used for Windows systems; in other environments + "extern" is used for a C compiler and "extern C" for a C++ compiler. + This macro apears at the start of every exported function that is part + of the external API. It does not appear on functions that are "external" + in the C sense, but which are internal to the library. */ +/* #undef PCRE_EXP_DEFN */ + +/* Define to any value if linking statically (TODO: make nice with Libtool) */ +/* #undef PCRE_STATIC */ + +/* When calling PCRE via the POSIX interface, 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 threshold above which the stack is no longer + used is defined by POSIX_MALLOC_THRESHOLD. */ +#ifndef POSIX_MALLOC_THRESHOLD +#define POSIX_MALLOC_THRESHOLD 10 +#endif + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* Define to 1 if you have the ANSI C header files. */ +#ifndef STDC_HEADERS +#define STDC_HEADERS 1 +#endif + +/* Define to allow pcretest and pcregrep to be linked with gcov, so that they + are able to generate code coverage reports. */ +/* #undef SUPPORT_GCOV */ + +/* Define to any value to enable support for Just-In-Time compiling. */ +/* #undef SUPPORT_JIT */ + +/* Define to any value to allow pcregrep to be linked with libbz2, so that it + is able to handle .bz2 files. */ +/* #undef SUPPORT_LIBBZ2 */ + +/* Define to any value to allow pcretest to be linked with libedit. */ +/* #undef SUPPORT_LIBEDIT */ + +/* Define to any value to allow pcretest to be linked with libreadline. */ +/* #undef SUPPORT_LIBREADLINE */ + +/* Define to any value to allow pcregrep to be linked with libz, so that it is + able to handle .gz files. */ +/* #undef SUPPORT_LIBZ */ + +/* Define to any value to enable the 16 bit PCRE library. */ +/* #undef SUPPORT_PCRE16 */ + +/* Define to any value to enable the 32 bit PCRE library. */ +/* #undef SUPPORT_PCRE32 */ + +/* Define to any value to enable the 8 bit PCRE library. */ +#ifndef SUPPORT_PCRE8 +#define SUPPORT_PCRE8 /**/ +#endif + +/* Define to any value to enable JIT support in pcregrep. */ +/* #undef SUPPORT_PCREGREP_JIT */ + +/* Define to any value to enable support for Unicode properties. */ +/* #undef SUPPORT_UCP */ + +/* Define to any value to enable support for the UTF-8/16/32 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/32, but not both at once. */ +/* #undef SUPPORT_UTF */ + +/* Valgrind support to find invalid memory reads. */ +/* #undef SUPPORT_VALGRIND */ + +/* Version number of package */ +#ifndef VERSION +#define VERSION "8.32" +#endif + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +/* #undef int64_t */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ diff --git a/tools/pcre/config.h.in b/tools/pcre/config.h.in new file mode 100644 index 00000000..de19fe01 --- /dev/null +++ b/tools/pcre/config.h.in @@ -0,0 +1,343 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + + +/* PCRE is written in Standard C, but there are a few non-standard things it +can cope with, allowing it to run on SunOS4 and other "close to standard" +systems. + +In environments that support the facilities, config.h.in is converted by +"configure", or config-cmake.h.in is converted by CMake, into config.h. If you +are going to build PCRE "by hand" without using "configure" or CMake, you +should copy the distributed config.h.generic to config.h, and then edit the +macro definitions to be the way you need them. You must then add +-DHAVE_CONFIG_H to all of your compile commands, so that config.h is included +at the start of every source. + +Alternatively, you can avoid editing by using -D on the compiler command line +to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H. + +PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if +HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set +them both to 0; an emulation function will be used. */ + +/* By default, the \R escape sequence matches any Unicode line ending + character or sequence of characters. If BSR_ANYCRLF is defined (to any + value), this is changed so that backslash-R matches only CR, LF, or CRLF. + The build-time default can be overridden by the user of PCRE at runtime. */ +#undef BSR_ANYCRLF + +/* If you are compiling for a system that uses EBCDIC instead of ASCII + character codes, define this macro to any value. You must also edit the + NEWLINE macro below to set a suitable EBCDIC newline, commonly 21 (0x15). + On systems that can use "configure" or CMake to set EBCDIC, NEWLINE is + automatically adjusted. When EBCDIC is set, PCRE assumes that all input + strings are in EBCDIC. If you do not define this macro, PCRE will assume + input strings are ASCII or UTF-8/16/32 Unicode. It is not possible to build + a version of PCRE that supports both EBCDIC and UTF-8/16/32. */ +#undef EBCDIC + +/* In an EBCDIC environment, define this macro to any value to arrange for the + NL character to be 0x25 instead of the default 0x15. NL plays the role that + LF does in an ASCII/Unicode environment. The value must also be set in the + NEWLINE macro below. On systems that can use "configure" or CMake to set + EBCDIC_NL25, the adjustment of NEWLINE is automatic. */ +#undef EBCDIC_NL25 + +/* Define to 1 if you have the `bcopy' function. */ +#undef HAVE_BCOPY + +/* Define to 1 if you have the header file. */ +#undef HAVE_BITS_TYPE_TRAITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_BZLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DIRENT_H + +/* 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 + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if the system has the type `long long'. */ +#undef HAVE_LONG_LONG + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* Have PTHREAD_PRIO_INHERIT. */ +#undef HAVE_PTHREAD_PRIO_INHERIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_READLINE_HISTORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_READLINE_READLINE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have `strtoimax'. */ +#undef HAVE_STRTOIMAX + +/* Define to 1 if you have `strtoll'. */ +#undef HAVE_STRTOLL + +/* Define to 1 if you have `strtoq'. */ +#undef HAVE_STRTOQ + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TYPE_TRAITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the system has the type `unsigned long long'. */ +#undef HAVE_UNSIGNED_LONG_LONG + +/* Define to 1 or 0, depending whether the compiler supports simple visibility + declarations. */ +#undef HAVE_VISIBILITY + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ZLIB_H + +/* Define to 1 if you have `_strtoi64'. */ +#undef HAVE__STRTOI64 + +/* The value of LINK_SIZE determines the number of bytes used to store links + as offsets within the compiled regex. The default is 2, which allows for + compiled patterns up to 64K long. This covers the vast majority of cases. + However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows + for longer patterns in extreme cases. */ +#undef LINK_SIZE + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* The value of MATCH_LIMIT determines the default number of times the + internal match() function can be called during a single execution of + pcre_exec(). There is a runtime interface for setting a different limit. + The limit exists in order to catch runaway regular expressions that take + for ever to determine that they do not match. The default is set very large + so that it does not accidentally catch legitimate cases. */ +#undef MATCH_LIMIT + +/* The above limit applies to all calls of match(), whether or not they + increase the recursion depth. In some environments it is desirable to limit + the depth of recursive calls of match() more strictly, in order to restrict + the maximum amount of stack (or heap, if NO_RECURSE is defined) that is + used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of + match(). To have any useful effect, it must be less than the value of + MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is + a runtime method for setting a different limit. */ +#undef MATCH_LIMIT_RECURSION + +/* This limit is parameterized just in case anybody ever wants to change it. + Care must be taken if it is increased, because it guards against integer + overflow caused by enormously large patterns. */ +#undef MAX_NAME_COUNT + +/* This limit is parameterized just in case anybody ever wants to change it. + Care must be taken if it is increased, because it guards against integer + overflow caused by enormously large patterns. */ +#undef MAX_NAME_SIZE + +/* The value of NEWLINE determines the default newline character sequence. + PCRE client programs can override this by selecting other values at run + time. In ASCII environments, the value can be 10 (LF), 13 (CR), or 3338 + (CRLF); in EBCDIC environments the value can be 21 or 37 (LF), 13 (CR), or + 3349 or 3365 (CRLF) because there are two alternative codepoints (0x15 and + 0x25) that are used as the NL line terminator that is equivalent to ASCII + LF. In both ASCII and EBCDIC environments the value can also be -1 (ANY), + or -2 (ANYCRLF). */ +#undef NEWLINE + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* PCRE uses recursive function calls to handle backtracking while matching. + This can sometimes be a problem on systems that have stacks of limited + size. Define NO_RECURSE to any value to get a version that doesn't use + recursion in the match() function; instead it creates its own stack by + steam using pcre_recurse_malloc() to obtain memory from the heap. For more + detail, see the comments and other stuff just above the match() function. + */ +#undef NO_RECURSE + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* to make a symbol visible */ +#undef PCRECPP_EXP_DECL + +/* to make a symbol visible */ +#undef PCRECPP_EXP_DEFN + +/* The value of PCREGREP_BUFSIZE determines the size of buffer used by + pcregrep to hold parts of the file it is searching. 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 + +/* to make a symbol visible */ +#undef PCREPOSIX_EXP_DECL + +/* to make a symbol visible */ +#undef PCREPOSIX_EXP_DEFN + +/* to make a symbol visible */ +#undef PCRE_EXP_DATA_DEFN + +/* to make a symbol visible */ +#undef PCRE_EXP_DECL + + +/* 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 + of a function that is exported by the library, define this macro to + contain the relevant magic. If you do not define this macro, a suitable + __declspec value is used for Windows systems; in other environments + "extern" is used for a C compiler and "extern C" for a C++ compiler. + This macro apears at the start of every exported function that is part + of the external API. It does not appear on functions that are "external" + in the C sense, but which are internal to the library. */ +#undef PCRE_EXP_DEFN + +/* Define to any value if linking statically (TODO: make nice with Libtool) */ +#undef PCRE_STATIC + +/* When calling PCRE via the POSIX interface, 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 threshold above which the stack is no longer + used is defined by POSIX_MALLOC_THRESHOLD. */ +#undef POSIX_MALLOC_THRESHOLD + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to allow pcretest and pcregrep to be linked with gcov, so that they + are able to generate code coverage reports. */ +#undef SUPPORT_GCOV + +/* Define to any value to enable support for Just-In-Time compiling. */ +#undef SUPPORT_JIT + +/* Define to any value to allow pcregrep to be linked with libbz2, so that it + is able to handle .bz2 files. */ +#undef SUPPORT_LIBBZ2 + +/* Define to any value to allow pcretest to be linked with libedit. */ +#undef SUPPORT_LIBEDIT + +/* Define to any value to allow pcretest to be linked with libreadline. */ +#undef SUPPORT_LIBREADLINE + +/* Define to any value to allow pcregrep to be linked with libz, so that it is + able to handle .gz files. */ +#undef SUPPORT_LIBZ + +/* Define to any value to enable the 16 bit PCRE library. */ +#undef SUPPORT_PCRE16 + +/* Define to any value to enable the 32 bit PCRE library. */ +#undef SUPPORT_PCRE32 + +/* Define to any value to enable the 8 bit PCRE library. */ +#undef SUPPORT_PCRE8 + +/* Define to any value to enable JIT support in pcregrep. */ +#undef SUPPORT_PCREGREP_JIT + +/* Define to any value to enable support for Unicode properties. */ +#undef SUPPORT_UCP + +/* Define to any value to enable support for the UTF-8/16/32 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/32, but not both at once. */ +#undef SUPPORT_UTF + +/* Valgrind support to find invalid memory reads. */ +#undef SUPPORT_VALGRIND + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef int64_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/tools/pcre/config.sub b/tools/pcre/config.sub new file mode 100644 index 00000000..ae2965a1 --- /dev/null +++ b/tools/pcre/config.sub @@ -0,0 +1,1804 @@ +#! /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, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-08-18' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +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, 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." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + 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 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # 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 \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | 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 \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + 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. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # 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-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | 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-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | 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-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsEE* | ee | ps2) + basic_machine=mips64r5900el-scei + case $os in + -linux*) + ;; + *) + os=-elf + ;; + esac + ;; + iop) + basic_machine=mipsel-scei + os=-irx + ;; + dvp) + basic_machine=dvp-scei + os=-elf + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + 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 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + 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 + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # 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 + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -irx* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/tools/pcre/configure b/tools/pcre/configure new file mode 100644 index 00000000..77229ed9 --- /dev/null +++ b/tools/pcre/configure @@ -0,0 +1,21272 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for PCRE 8.32. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +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 +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # 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 + 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 : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + 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" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# 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. +as_fn_error () +{ + 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: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# 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` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='PCRE' +PACKAGE_TARNAME='pcre' +PACKAGE_VERSION='8.32' +PACKAGE_STRING='PCRE 8.32' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_unique_file="pcre.h.in" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +WITH_GCOV_FALSE +WITH_GCOV_TRUE +GCOV_LIBS +GCOV_CXXFLAGS +GCOV_CFLAGS +GENHTML +LCOV +SHTOOL +VALGRIND_LIBS +VALGRIND_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +LIBBZ2 +LIBZ +DISTCHECK_CONFIGURE_FLAGS +EXTRA_LIBPCRECPP_LDFLAGS +EXTRA_LIBPCREPOSIX_LDFLAGS +EXTRA_LIBPCRE32_LDFLAGS +EXTRA_LIBPCRE16_LDFLAGS +EXTRA_LIBPCRE_LDFLAGS +PTHREAD_CFLAGS +PTHREAD_LIBS +PTHREAD_CC +ax_pthread_config +PCRE_STATIC_CFLAG +LIBREADLINE +WITH_VALGRIND_FALSE +WITH_VALGRIND_TRUE +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_PCRE32_FALSE +WITH_PCRE32_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_pcre32 +enable_pcre16 +enable_pcre8 +PCRE_DATE +PCRE_PRERELEASE +PCRE_MINOR +PCRE_MAJOR +HAVE_VISIBILITY +VISIBILITY_CXXFLAGS +VISIBILITY_CFLAGS +CXXCPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +LIBTOOL +OBJDUMP +DLLTOOL +AS +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +EGREP +GREP +CPP +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +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_pcre32 +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 +enable_newline_is_crlf +enable_newline_is_anycrlf +enable_newline_is_any +enable_bsr_anycrlf +enable_ebcdic +enable_ebcdic_nl25 +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 +with_match_limit +with_match_limit_recursion +enable_valgrind +enable_coverage +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP +CXXCPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +VALGRIND_CFLAGS +VALGRIND_LIBS +LCOV +GENHTML' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + 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" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + 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" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + 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" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + 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" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --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" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # 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'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $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}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + 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" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + 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' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +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 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +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" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +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" +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" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # 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.32 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --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 + --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 + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/pcre] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of PCRE 8.32:";; + esac + cat <<\_ACEOF + +Optional Features: + --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] + --enable-static[=PKGS] build static libraries [default=yes] + --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 + --enable-pcre32 enable 32 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 another name for --enable-utf. Kept only for + compatibility reasons + --enable-utf enable UTF-8/16/32 support (incompatible with + --enable-ebcdic) + --enable-unicode-properties + enable Unicode properties support (implies + --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 + use CRLF as newline sequence + --enable-newline-is-anycrlf + use CR, LF, or CRLF as newline sequence + --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-utf; use only in (uncommon) EBCDIC + environments; it implies --enable-rebuild-chartables + --enable-ebcdic-nl25 set EBCDIC code for NL to 0x25 instead of 0x15; it + implies --enable-ebcdic + --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 + --enable-valgrind valgrind support + --enable-coverage enable code coverage reports using gcov + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --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) + --with-match-limit=N default limit on internal looping (default=10000000) + --with-match-limit-recursion=N + default limit on internal recursion + (default=MATCH_LIMIT) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + VALGRIND_CFLAGS + C compiler flags for VALGRIND, overriding pkg-config + VALGRIND_LIBS + linker flags for VALGRIND, overriding pkg-config + LCOV the ltp lcov program + GENHTML the ltp genhtml program + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +PCRE configure 8.32 +generated by GNU Autoconf 2.68 + +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 + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + 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 eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_find_intX_t LINENO BITS VAR +# ----------------------------------- +# Finds a signed integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_intX_t () +{ + 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 eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in int$2_t 'int' 'long int' \ + 'long long int' 'short int' 'signed char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) + < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + case $ac_type in #( + int$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_intX_t + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # 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; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + 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 eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* 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 $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # 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; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +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; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_cxx_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +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; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_mongrel + +# ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES +# --------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_cxx_check_type () +{ + 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 eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_type + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + 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 eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + 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.32, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # 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 +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $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" \ + || { { $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 + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$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 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +am__api_version='1.11' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + 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 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $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 ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + 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;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # 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 +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + 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 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +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 ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip" + $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 +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_STRIP="strip" + $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_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + 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 + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $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 ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +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 ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # 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_AWK="$ac_prog" + $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 +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$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 eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# 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;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + 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 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='pcre' + VERSION='8.32' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + +# 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_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +ac_config_headers="$ac_config_headers config.h" + + +# This was added at the suggestion of libtoolize (03-Jan-10) + + +# The default CFLAGS and CXXFLAGS in Autoconf are "-g -O2" for gcc and just +# "-g" for any other compiler. There doesn't seem to be a standard way of +# getting rid of the -g (which I don't think is needed for a production +# library). This fudge seems to achieve the necessary. First, we remember the +# externally set values of CFLAGS and CXXFLAGS. Then call the AC_PROG_CC and +# AC_PROG_CXX macros to find the compilers - if CFLAGS and CXXFLAGS are not +# set, they will be set to Autoconf's defaults. Afterwards, if the original +# values were not set, remove the -g from the Autoconf defaults. +# (PH 02-May-07) + +remember_set_CFLAGS="$CFLAGS" +remember_set_CXXFLAGS="$CXXFLAGS" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +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 ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # 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_CC="${ac_tool_prefix}gcc" + $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 +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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_CC="gcc" + $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_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + 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 + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +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 ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # 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_CC="${ac_tool_prefix}cc" + $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 +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +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 ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +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 + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $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 + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + 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 ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # 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_CC="$ac_tool_prefix$ac_prog" + $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 +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +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 ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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_CC="$ac_prog" + $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_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + 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 + CC=$ac_ct_CC + fi +fi + +fi + + +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; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +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; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +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; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + 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. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +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 ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $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; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +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 ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +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 ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +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 ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +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 + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + 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 ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # 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_CXX="$ac_tool_prefix$ac_prog" + $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 +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +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 ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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_CXX="$ac_prog" + $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_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + 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 + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $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 ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +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 ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +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 + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + + +if test "x$remember_set_CFLAGS" = "x" +then + if test "$CFLAGS" = "-g -O2" + then + CFLAGS="-O2" + elif test "$CFLAGS" = "-g" + then + CFLAGS="" + fi +fi + +if test "x$remember_set_CXXFLAGS" = "x" +then + if test "$CXXFLAGS" = "-g -O2" + then + CXXFLAGS="-O2" + elif test "$CXXFLAGS" = "-g" + then + CXXFLAGS="" + fi +fi + +# 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_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + CXX=""; CXXCP=""; CXXFLAGS="" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Check for a 64-bit integer type + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $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; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +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; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $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 ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + 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 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + 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 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $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 ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + 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 +" +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 + +fi + +done + + +ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" +case $ac_cv_c_int64_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int64_t $ac_cv_c_int64_t +_ACEOF +;; +esac + + + +# 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_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +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 +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 + +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;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +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 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +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 ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # 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_AS="${ac_tool_prefix}as" + $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 +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # 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_AS="as" + $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_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="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 + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + 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 + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +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 ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # 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_OBJDUMP="${ac_tool_prefix}objdump" + $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 +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # 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_OBJDUMP="objdump" + $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_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="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 + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; +esac + +test -z "$AS" && AS=as + + + + + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4' +macro_revision='1.3293' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $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 && \ + 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 + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $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 ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + 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_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + 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 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +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 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + 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 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $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 +{ $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 ${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. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $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 ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + 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 ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # 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_DUMPBIN="$ac_tool_prefix$ac_prog" + $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 +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +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 ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # 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_DUMPBIN="$ac_prog" + $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_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + 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 + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $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 ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# 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 ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $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 ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +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' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +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 ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # 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_OBJDUMP="${ac_tool_prefix}objdump" + $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 +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # 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_OBJDUMP="objdump" + $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_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="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 + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + +{ $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 ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +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 + + + + + + + + + + + + + + + + + + + + + + +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 + 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 ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # 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_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 +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + 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 ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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_AR="$ac_prog" + $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_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="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 + AR=$ac_ct_AR + fi +fi + +: ${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 + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +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 ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip" + $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 +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_STRIP="strip" + $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_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + 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 + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +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 ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # 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_RANLIB="${ac_tool_prefix}ranlib" + $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 +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # 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_RANLIB="ranlib" + $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_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + 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 + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# 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 ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +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'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + 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 + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + 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 + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + 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 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$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 + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $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 + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + 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 ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +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*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +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 ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # 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_DSYMUTIL="${ac_tool_prefix}dsymutil" + $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 +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # 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_DSYMUTIL="dsymutil" + $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_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + 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 + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +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 ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # 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_NMEDIT="${ac_tool_prefix}nmedit" + $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 +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # 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_NMEDIT="nmedit" + $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_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + 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 + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +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 ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # 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_LIPO="${ac_tool_prefix}lipo" + $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 +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # 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_LIPO="lipo" + $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_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + 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 + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +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 ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # 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_OTOOL="${ac_tool_prefix}otool" + $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 +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # 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_OTOOL="otool" + $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_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + 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 + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +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 ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # 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_OTOOL64="${ac_tool_prefix}otool64" + $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 +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # 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_OTOOL64="otool64" + $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_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + 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 + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $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 ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$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 ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$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 ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +for ac_header in dlfcn.h +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" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +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 + + + + enable_dlopen=no + + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + 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 ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + 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 ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $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 ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | 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). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + lt_prog_compiler_pic='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | 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='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + 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) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $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. +# +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 ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# 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 ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $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 ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $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 ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + 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/;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' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='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 $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + 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 + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + 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 + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + 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' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + 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 + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + 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 +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + 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 "$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" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + 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 +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + 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 "$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, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + 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*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + 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 + ;; + + hpux9*) + if test "$GCC" = yes; then + 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 + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + 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 + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -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 + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (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 ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${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 + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + 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. + # 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) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + 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" +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' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_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' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + 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} $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 \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + 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 $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"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $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 -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # 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 ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + 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}`~ + 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~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + 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 + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + # Handle Gentoo/FreeBSD as it was Linux + case $host_vendor in + gentoo) + version_type=linux ;; + *) + version_type=freebsd-$objformat ;; + esac + + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + linux) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + need_lib_prefix=no + need_version=no + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # 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 ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $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 dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +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 ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $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 shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=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_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +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" = 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 ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $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 dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +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 ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $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 dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=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_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +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 ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $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 dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=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_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $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 ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* 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)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + 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 ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* 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)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $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 ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +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; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # 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 + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $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 +{ $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 ${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. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # 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 $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' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + 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 +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + 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 "$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" + + archive_expsym_cmds_CXX='$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 + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + 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 +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + 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 "$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, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + 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*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${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' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + 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 + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + 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 $pic_flag ${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}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + 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 $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 + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + 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 $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 + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + 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 $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 $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 + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -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 -G -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 + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_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=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + 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 ${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. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + 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. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + 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). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + 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++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $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. +# +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 ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# 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 ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $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 ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$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. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + 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 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # 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 ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + 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}`~ + 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~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + 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 + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + # Handle Gentoo/FreeBSD as it was Linux + case $host_vendor in + gentoo) + version_type=linux ;; + *) + version_type=freebsd-$objformat ;; + esac + + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + linux) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + need_lib_prefix=no + need_version=no + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + + +# Check for GCC visibility feature + + + + VISIBILITY_CFLAGS= + VISIBILITY_CXXFLAGS= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the -Werror option is usable" >&5 +$as_echo_n "checking whether the -Werror option is usable... " >&6; } + if ${pcre_cv_cc_vis_werror+:} false; then : + $as_echo_n "(cached) " >&6 +else + + pcre_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pcre_cv_cc_vis_werror=yes +else + pcre_cv_cc_vis_werror=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$pcre_save_CFLAGS" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pcre_cv_cc_vis_werror" >&5 +$as_echo "$pcre_cv_cc_vis_werror" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for simple visibility declarations" >&5 +$as_echo_n "checking for simple visibility declarations... " >&6; } + if ${pcre_cv_cc_visibility+:} false; then : + $as_echo_n "(cached) " >&6 +else + + pcre_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + if test $pcre_cv_cc_vis_werror = yes; then + CFLAGS="$CFLAGS -Werror" + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void); + void dummyfunc (void) {} + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pcre_cv_cc_visibility=yes +else + pcre_cv_cc_visibility=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$pcre_save_CFLAGS" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pcre_cv_cc_visibility" >&5 +$as_echo "$pcre_cv_cc_visibility" >&6; } + if test $pcre_cv_cc_visibility = yes; then + VISIBILITY_CFLAGS="-fvisibility=hidden" + VISIBILITY_CXXFLAGS="-fvisibility=hidden -fvisibility-inlines-hidden" + HAVE_VISIBILITY=1 + +$as_echo "#define PCRE_EXP_DECL extern __attribute__ ((visibility (\"default\")))" >>confdefs.h + + +$as_echo "#define PCRE_EXP_DEFN __attribute__ ((visibility (\"default\")))" >>confdefs.h + + +$as_echo "#define PCRE_EXP_DATA_DEFN __attribute__ ((visibility (\"default\")))" >>confdefs.h + + +$as_echo "#define PCREPOSIX_EXP_DECL extern __attribute__ ((visibility (\"default\")))" >>confdefs.h + + +$as_echo "#define PCREPOSIX_EXP_DEFN extern __attribute__ ((visibility (\"default\")))" >>confdefs.h + + +$as_echo "#define PCRECPP_EXP_DECL extern __attribute__ ((visibility (\"default\")))" >>confdefs.h + + +$as_echo "#define PCRECPP_EXP_DEFN __attribute__ ((visibility (\"default\")))" >>confdefs.h + + fi + fi + + + + +cat >>confdefs.h <<_ACEOF +#define HAVE_VISIBILITY $HAVE_VISIBILITY +_ACEOF + + + +# Versioning + +PCRE_MAJOR="8" +PCRE_MINOR="32" +PCRE_PRERELEASE="" +PCRE_DATE="2012-11-30" + +if test "$PCRE_MINOR" = "08" -o "$PCRE_MINOR" = "09" +then + echo "***" + echo "*** Minor version number $PCRE_MINOR must not be used. ***" + echo "*** Use only 01 to 07 or 10 onwards, to avoid octal issues. ***" + echo "***" + exit 1 +fi + + + + + + +# Set a more sensible default value for $(htmldir). +if test "x$htmldir" = 'x${docdir}' +then + 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 --enable-pcre32 (disabled by default) +# Check whether --enable-pcre32 was given. +if test "${enable_pcre32+set}" = set; then : + enableval=$enable_pcre32; +else + enable_pcre32=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=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. +if test "${enable_rebuild_chartables+set}" = set; then : + enableval=$enable_rebuild_chartables; +else + enable_rebuild_chartables=no +fi + + +# Handle --enable-utf8 (disabled by default) +# Check whether --enable-utf8 was given. +if test "${enable_utf8+set}" = set; then : + enableval=$enable_utf8; +else + enable_utf8=unset +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 : + enableval=$enable_unicode_properties; +else + enable_unicode_properties=no +fi + + +# Handle newline options +ac_pcre_newline=lf +# Check whether --enable-newline-is-cr was given. +if test "${enable_newline_is_cr+set}" = set; then : + enableval=$enable_newline_is_cr; ac_pcre_newline=cr +fi + +# Check whether --enable-newline-is-lf was given. +if test "${enable_newline_is_lf+set}" = set; then : + enableval=$enable_newline_is_lf; ac_pcre_newline=lf +fi + +# Check whether --enable-newline-is-crlf was given. +if test "${enable_newline_is_crlf+set}" = set; then : + enableval=$enable_newline_is_crlf; ac_pcre_newline=crlf +fi + +# Check whether --enable-newline-is-anycrlf was given. +if test "${enable_newline_is_anycrlf+set}" = set; then : + enableval=$enable_newline_is_anycrlf; ac_pcre_newline=anycrlf +fi + +# Check whether --enable-newline-is-any was given. +if test "${enable_newline_is_any+set}" = set; then : + enableval=$enable_newline_is_any; ac_pcre_newline=any +fi + +enable_newline="$ac_pcre_newline" + +# Handle --enable-bsr-anycrlf +# Check whether --enable-bsr-anycrlf was given. +if test "${enable_bsr_anycrlf+set}" = set; then : + enableval=$enable_bsr_anycrlf; +else + enable_bsr_anycrlf=no +fi + + +# Handle --enable-ebcdic +# Check whether --enable-ebcdic was given. +if test "${enable_ebcdic+set}" = set; then : + enableval=$enable_ebcdic; +else + enable_ebcdic=no +fi + + +# Handle --enable-ebcdic-nl25 +# Check whether --enable-ebcdic-nl25 was given. +if test "${enable_ebcdic_nl25+set}" = set; then : + enableval=$enable_ebcdic_nl25; +else + enable_ebcdic_nl25=no +fi + + +# Handle --disable-stack-for-recursion +# Check whether --enable-stack-for-recursion was given. +if test "${enable_stack_for_recursion+set}" = set; then : + enableval=$enable_stack_for_recursion; +else + enable_stack_for_recursion=yes +fi + + +# Handle --enable-pcregrep-libz +# Check whether --enable-pcregrep-libz was given. +if test "${enable_pcregrep_libz+set}" = set; then : + enableval=$enable_pcregrep_libz; +else + enable_pcregrep_libz=no +fi + + +# Handle --enable-pcregrep-libbz2 +# Check whether --enable-pcregrep-libbz2 was given. +if test "${enable_pcregrep_libbz2+set}" = set; then : + enableval=$enable_pcregrep_libbz2; +else + enable_pcregrep_libbz2=no +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 : + enableval=$enable_pcretest_libreadline; +else + enable_pcretest_libreadline=no +fi + + +# Handle --with-posix-malloc-threshold=NBYTES + +# Check whether --with-posix-malloc-threshold was given. +if test "${with_posix_malloc_threshold+set}" = set; then : + withval=$with_posix_malloc_threshold; +else + with_posix_malloc_threshold=10 +fi + + +# Handle --with-link-size=N + +# Check whether --with-link-size was given. +if test "${with_link_size+set}" = set; then : + withval=$with_link_size; +else + with_link_size=2 +fi + + +# Handle --with-match-limit=N + +# Check whether --with-match-limit was given. +if test "${with_match_limit+set}" = set; then : + withval=$with_match_limit; +else + with_match_limit=10000000 +fi + + +# Handle --with-match-limit_recursion=N +# +# Note: In config.h, the default is to define MATCH_LIMIT_RECURSION +# symbolically as MATCH_LIMIT, which in turn is defined to be some numeric +# value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some +# different numeric value (or even the same numeric value as MATCH_LIMIT, +# though no longer defined in terms of the latter). +# + +# Check whether --with-match-limit-recursion was given. +if test "${with_match_limit_recursion+set}" = set; then : + withval=$with_match_limit_recursion; +else + with_match_limit_recursion=MATCH_LIMIT +fi + + +# Handle --enable-valgrind +# Check whether --enable-valgrind was given. +if test "${enable_valgrind+set}" = set; then : + enableval=$enable_valgrind; +else + enable_valgrind=no +fi + + +# Enable code coverage reports using gcov +# Check whether --enable-coverage was given. +if test "${enable_coverage+set}" = set; then : + enableval=$enable_coverage; +else + enable_coverage=no +fi + + +# 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 + +# Set the default value for pcre32 +if test "x$enable_pcre32" = "xunset" +then + enable_pcre32=no +fi + +# Make sure enable_pcre8 or enable_pcre16 was set +if test "x$enable_pcre8$enable_pcre16$enable_pcre32" = "xnonono" +then + as_fn_error $? "At least one of 8, 16 or 32 bit 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_utf" = "xno" + then + as_fn_error $? "support for Unicode properties requires UTF-8/16/32 support" "$LINENO" 5 + fi + 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 + +# 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 + as_fn_error $? "C++ library requires pcre library with 8 bit characters" "$LINENO" 5 + fi +fi + +# Convert the newline identifier into the appropriate integer value. The first +# three are ASCII values 0x0a, 0x0d, and 0x0d0a, but if EBCDIC is enabled, they +# are changed below. + +case "$enable_newline" in + lf) ac_pcre_newline_value=10 ;; + cr) ac_pcre_newline_value=13 ;; + crlf) ac_pcre_newline_value=3338 ;; + 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 + ;; +esac + +# --enable-ebcdic-nl25 implies --enable-ebcdic +if test "x$enable_ebcdic_nl25" = "xyes"; then + enable_ebcdic=yes +fi + +# Make sure that if enable_ebcdic is set, rebuild_chartables is also enabled, +# and the newline value is adjusted appropriately (CR is still 13, but LF is +# 21 or 37). 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_utf" = "xyes"; then + as_fn_error $? "support for EBCDIC and UTF-8/16/32 cannot be enabled at the same time" "$LINENO" 5 + fi + + if test "x$enable_ebcdic_nl25" = "xno"; then + case "$ac_pcre_newline_value" in + 10) ac_pcre_newline_value=21 ;; + 3338) ac_pcre_newline_value=3349 ;; + esac + else + case "$ac_pcre_newline_value" in + 10) ac_pcre_newline_value=37 ;; + 3338) ac_pcre_newline_value=3365 ;; + esac + fi +fi + +# Check argument to --with-link-size +case "$with_link_size" in + 2|3|4) ;; + *) + as_fn_error $? "invalid argument \"$with_link_size\" to --with-link-size option" "$LINENO" 5 + ;; +esac + + + +# 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 ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +for ac_header in limits.h sys/types.h sys/stat.h dirent.h windows.h +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" +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 + +fi + +done + + +# The files below are C++ header files. +pcre_have_type_traits="0" +pcre_have_bits_type_traits="0" + +if test "x$enable_cpp" = "xyes" -a -z "$CXX"; then + as_fn_error $? "You need a C++ compiler for C++ support." "$LINENO" 5 +fi + +if test "x$enable_cpp" = "xyes" -a -n "$CXX" +then +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +# Older versions of pcre defined pcrecpp::no_arg, but in new versions +# it's called pcrecpp::RE::no_arg. For backwards ABI compatibility, +# we want to make one an alias for the other. Different systems do +# this in different ways. Some systems, for instance, can do it via +# a linker flag: -alias (for os x 10.5) or -i (for os x <=10.4). +OLD_LDFLAGS="$LDFLAGS" +for flag in "-alias,__ZN7pcrecpp2RE6no_argE,__ZN7pcrecpp6no_argE" \ + "-i__ZN7pcrecpp6no_argE:__ZN7pcrecpp2RE6no_argE"; do + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alias support in the linker" >&5 +$as_echo_n "checking for alias support in the linker... " >&6; } + 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. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +namespace pcrecpp { + class RE { static int no_arg; }; + int RE::no_arg; + } +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; + EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS -Wl,$flag"; + break; +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +done +LDFLAGS="$OLD_LDFLAGS" + +# We could be more clever here, given we're doing AC_SUBST with this +# (eg set a var to be the name of the include file we want). But we're not +# so it's easy to change back to 'regular' autoconf vars if we needed to. + +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" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRING 1 +_ACEOF + pcre_have_cpp_headers="1" +else + pcre_have_cpp_headers="0" +fi + +done + +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" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_BITS_TYPE_TRAITS_H 1 +_ACEOF + pcre_have_bits_type_traits="1" +else + pcre_have_bits_type_traits="0" +fi + +done + +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" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_TYPE_TRAITS_H 1 +_ACEOF + pcre_have_type_traits="1" +else + pcre_have_type_traits="0" +fi + +done + + +# (This isn't c++-specific, but is only used in pcrecpp.cc, so try this +# in a c++ context. This matters becuase strtoimax is C99 and may not +# be supported by the C++ compiler.) +# Figure out how to create a longlong from a string: strtoll and +# equiv. It's not enough to call AC_CHECK_FUNCS: hpux has a +# strtoll, for instance, but it only takes 2 args instead of 3! +# We have to call AH_TEMPLATE since AC_DEFINE_UNQUOTED below is complex. + + + + +have_strto_fn=0 +for fn in strtoq strtoll _strtoi64 strtoimax; do + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $fn" >&5 +$as_echo_n "checking for $fn... " >&6; } + if test "$fn" = strtoimax; then + include=stdint.h + else + include=stdlib.h + fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$include> +int +main () +{ +char* e; return $fn("100", &e, 10) + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<_ACEOF +#define HAVE_`echo $fn | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` 1 +_ACEOF + + have_strto_fn=1 + break +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done + +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" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_LONG_LONG 1 +_ACEOF + +pcre_have_long_long="1" +else + pcre_have_long_long="0" +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" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UNSIGNED_LONG_LONG 1 +_ACEOF + +pcre_have_ulong_long="1" +else + pcre_have_ulong_long="0" +fi + +else + pcre_have_long_long="0" + pcre_have_ulong_long="0" +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +# Using AC_SUBST eliminates the need to include config.h in a public .h file + + + +# 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_pcre32" = "xyes"; then + WITH_PCRE32_TRUE= + WITH_PCRE32_FALSE='#' +else + WITH_PCRE32_TRUE='#' + WITH_PCRE32_FALSE= +fi + + if test "x$enable_cpp" = "xyes"; then + WITH_PCRE_CPP_TRUE= + WITH_PCRE_CPP_FALSE='#' +else + WITH_PCRE_CPP_TRUE='#' + WITH_PCRE_CPP_FALSE= +fi + + if test "x$enable_rebuild_chartables" = "xyes"; then + WITH_REBUILD_CHARTABLES_TRUE= + WITH_REBUILD_CHARTABLES_FALSE='#' +else + WITH_REBUILD_CHARTABLES_TRUE='#' + 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 + + if test "x$enable_valgrind" = "xyes"; then + WITH_VALGRIND_TRUE= + WITH_VALGRIND_FALSE='#' +else + WITH_VALGRIND_TRUE='#' + WITH_VALGRIND_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 ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +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" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + + +# Checks for library functions. + +for ac_func in bcopy memmove strerror +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" +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 + +fi +done + + +# Check for the availability of libz (aka zlib) + +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" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ZLIB_H 1 +_ACEOF + HAVE_ZLIB_H=1 +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzopen in -lz" >&5 +$as_echo_n "checking for gzopen in -lz... " >&6; } +if ${ac_cv_lib_z_gzopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $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 gzopen (); +int +main () +{ +return gzopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_z_gzopen=yes +else + ac_cv_lib_z_gzopen=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_z_gzopen" >&5 +$as_echo "$ac_cv_lib_z_gzopen" >&6; } +if test "x$ac_cv_lib_z_gzopen" = xyes; then : + HAVE_LIBZ=1 +fi + + +# Check for the availability of libbz2. Originally we just used AC_CHECK_LIB, +# as for libz. However, this had the following problem, diagnosed and fixed by +# a user: +# +# - libbz2 uses the Pascal calling convention (WINAPI) for the functions +# under Win32. +# - The standard autoconf AC_CHECK_LIB fails to include "bzlib.h", +# therefore missing the function definition. +# - The compiler thus generates a "C" signature for the test function. +# - The linker fails to find the "C" function. +# - PCRE fails to configure if asked to do so against libbz2. +# +# Solution: +# +# - Replace the AC_CHECK_LIB test with a custom test. + +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" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_BZLIB_H 1 +_ACEOF + HAVE_BZLIB_H=1 +fi + +done + +# Original test +# AC_CHECK_LIB([bz2], [BZ2_bzopen], [HAVE_LIBBZ2=1]) +# +# Custom test follows + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libbz2" >&5 +$as_echo_n "checking for libbz2... " >&6; } +OLD_LIBS="$LIBS" +LIBS="$LIBS -lbz2" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_BZLIB_H +#include +#endif +int +main () +{ +return (int)BZ2_bzopen("conftest", "rb"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; };HAVE_LIBBZ2=1; break; +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$OLD_LIBS" + +# Check for the availabiity of libreadline + +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" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_READLINE_READLINE_H 1 +_ACEOF + HAVE_READLINE_H=1 +fi + +done + + 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" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_READLINE_HISTORY_H 1 +_ACEOF + HAVE_HISTORY_H=1 +fi + +done + + { $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 $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="-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 + +PCRE_STATIC_CFLAG="" +if test "x$enable_shared" = "xno" ; then + +$as_echo "#define PCRE_STATIC 1" >>confdefs.h + + PCRE_STATIC_CFLAG="-DPCRE_STATIC" +fi + + +# Here is where pcre specific defines are handled + +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_pcre32" = "yes"; then + +$as_echo "#define SUPPORT_PCRE32 /**/" >>confdefs.h + +fi + +if test "$enable_jit" = "yes"; then + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 +$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } + 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 pthread_join (); +int +main () +{ +return pthread_join (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 +$as_echo "$ax_pthread_ok" >&6; } + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 +$as_echo_n "checking whether pthreads work without any flags... " >&6; } + ;; + + -*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 +$as_echo_n "checking whether pthreads work with $flag... " >&6; } + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + # Extract the first word of "pthread-config", so it can be a program name with args. +set dummy pthread-config; 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_ax_pthread_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ax_pthread_config"; then + ac_cv_prog_ax_pthread_config="$ax_pthread_config" # 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_ax_pthread_config="yes" + $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 + + test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" +fi +fi +ax_pthread_config=$ac_cv_prog_ax_pthread_config +if test -n "$ax_pthread_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 +$as_echo "$ax_pthread_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 +$as_echo_n "checking for the pthreads library -l$flag... " >&6; } + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; } +int +main () +{ +pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 +$as_echo "$ax_pthread_ok" >&6; } + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 +$as_echo_n "checking for joinable pthread attribute... " >&6; } + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +int attr = $attr; return attr /* ; */ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + attr_name=$attr; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 +$as_echo "$attr_name" >&6; } + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + +cat >>confdefs.h <<_ACEOF +#define PTHREAD_CREATE_JOINABLE $attr_name +_ACEOF + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 +$as_echo_n "checking if more special flags are required for pthreads... " >&6; } + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + flag="-mt -D_REENTRANT" + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 +$as_echo "${flag}" >&6; } + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 +$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; } +if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include +int +main () +{ +int i = PTHREAD_PRIO_INHERIT; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_PTHREAD_PRIO_INHERIT=yes +else + ax_cv_PTHREAD_PRIO_INHERIT=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 +$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } + if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then : + +$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h + +fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + for ac_prog in xlc_r cc_r +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 ${ac_cv_prog_PTHREAD_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CC"; then + ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # 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_PTHREAD_CC="$ac_prog" + $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 +PTHREAD_CC=$ac_cv_prog_PTHREAD_CC +if test -n "$PTHREAD_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 +$as_echo "$PTHREAD_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PTHREAD_CC" && break +done +test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" + + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + + + + + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + +$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h + + : +else + ax_pthread_ok=no + as_fn_error $? "JIT support requires pthreads" "$LINENO" 5 +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + CC="$PTHREAD_CC" + CFLAGS="$PTHREAD_CFLAGS $CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + +$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 + +if test "$enable_unicode_properties" = "yes"; then + +$as_echo "#define SUPPORT_UCP /**/" >>confdefs.h + +fi + +if test "$enable_stack_for_recursion" = "no"; then + +$as_echo "#define NO_RECURSE /**/" >>confdefs.h + +fi + +if test "$enable_pcregrep_libz" = "yes"; then + +$as_echo "#define SUPPORT_LIBZ /**/" >>confdefs.h + +fi + +if test "$enable_pcregrep_libbz2" = "yes"; then + +$as_echo "#define SUPPORT_LIBBZ2 /**/" >>confdefs.h + +fi + +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 + +fi + + +cat >>confdefs.h <<_ACEOF +#define NEWLINE $ac_pcre_newline_value +_ACEOF + + +if test "$enable_bsr_anycrlf" = "yes"; then + +$as_echo "#define BSR_ANYCRLF /**/" >>confdefs.h + +fi + + +cat >>confdefs.h <<_ACEOF +#define LINK_SIZE $with_link_size +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define POSIX_MALLOC_THRESHOLD $with_posix_malloc_threshold +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define MATCH_LIMIT $with_match_limit +_ACEOF + + + +cat >>confdefs.h <<_ACEOF +#define MATCH_LIMIT_RECURSION $with_match_limit_recursion +_ACEOF + + + +$as_echo "#define MAX_NAME_SIZE 32" >>confdefs.h + + + +$as_echo "#define MAX_NAME_COUNT 10000" >>confdefs.h + + + + +if test "$enable_ebcdic" = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define EBCDIC /**/ +_ACEOF + +fi + +if test "$enable_ebcdic_nl25" = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define EBCDIC_NL25 /**/ +_ACEOF + +fi + +if test "$enable_valgrind" = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define SUPPORT_VALGRIND /**/ +_ACEOF + +fi + +# Platform specific issues +NO_UNDEFINED= +EXPORT_ALL_SYMBOLS= +case $host_os in + cygwin* | mingw* ) + if test X"$enable_shared" = Xyes; then + NO_UNDEFINED="-no-undefined" + EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols" + fi + ;; +esac + +# The extra LDFLAGS for each particular library +# (Note: The libpcre*_version bits are m4 variables, assigned above) + +EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \ + $NO_UNDEFINED -version-info 3:0:2" + +EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \ + $NO_UNDEFINED -version-info 2:0:2" + +EXTRA_LIBPCRE32_LDFLAGS="$EXTRA_LIBPCRE32_LDFLAGS \ + $NO_UNDEFINED -version-info 0:0:0" + +EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \ + $NO_UNDEFINED -version-info 0:1:0" + +EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \ + $NO_UNDEFINED -version-info 0:0:0 \ + $EXPORT_ALL_SYMBOLS" + + + + + + + +# When we run 'make distcheck', use these arguments. Turning off compiler +# optimization makes it run faster. +DISTCHECK_CONFIGURE_FLAGS="CFLAGS='' CXXFLAGS='' --enable-pcre16 --enable-pcre32 --enable-jit --enable-cpp --enable-unicode-properties" + + +# Check that, if --enable-pcregrep-libz or --enable-pcregrep-libbz2 is +# specified, the relevant library is available. + +if test "$enable_pcregrep_libz" = "yes"; then + if test "$HAVE_ZLIB_H" != "1"; then + echo "** Cannot --enable-pcregrep-libz because zlib.h was not found" + exit 1 + fi + if test "$HAVE_LIBZ" != "1"; then + echo "** Cannot --enable-pcregrep-libz because libz was not found" + exit 1 + fi + LIBZ="-lz" +fi + + +if test "$enable_pcregrep_libbz2" = "yes"; then + if test "$HAVE_BZLIB_H" != "1"; then + echo "** Cannot --enable-pcregrep-libbz2 because bzlib.h was not found" + exit 1 + fi + if test "$HAVE_LIBBZ2" != "1"; then + echo "** Cannot --enable-pcregrep-libbz2 because libbz2 was not found" + exit 1 + fi + LIBBZ2="-lbz2" +fi + + +# 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." + exit 1 + fi + if test "$HAVE_HISTORY_H" != "1"; then + echo "** Cannot --enable-pcretest-readline because readline/history.h was not found." + exit 1 + fi + if test -z "$LIBREADLINE"; then + echo "** Cannot --enable-pcretest-readline because readline library was not found." + exit 1 + fi +fi + +# Check for valgrind + +if test "$enable_valgrind" = "yes"; then + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; 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_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + 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_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; 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_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + 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_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + 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 + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND" >&5 +$as_echo_n "checking for VALGRIND... " >&6; } + +if test -n "$VALGRIND_CFLAGS"; then + pkg_cv_VALGRIND_CFLAGS="$VALGRIND_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"valgrind\""; } >&5 + ($PKG_CONFIG --exists --print-errors "valgrind") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_VALGRIND_CFLAGS=`$PKG_CONFIG --cflags "valgrind" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$VALGRIND_LIBS"; then + pkg_cv_VALGRIND_LIBS="$VALGRIND_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"valgrind\""; } >&5 + ($PKG_CONFIG --exists --print-errors "valgrind") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_VALGRIND_LIBS=`$PKG_CONFIG --libs "valgrind" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + VALGRIND_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "valgrind" 2>&1` + else + VALGRIND_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "valgrind" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$VALGRIND_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (valgrind) were not met: + +$VALGRIND_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables VALGRIND_CFLAGS +and VALGRIND_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables VALGRIND_CFLAGS +and VALGRIND_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + VALGRIND_CFLAGS=$pkg_cv_VALGRIND_CFLAGS + VALGRIND_LIBS=$pkg_cv_VALGRIND_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi +fi + +# test code coverage reporting +if test "$enable_coverage" = "yes"; then + if test "x$GCC" != "xyes"; then + as_fn_error $? "Code coverage reports can only be generated when using GCC" "$LINENO" 5 + fi + + # ccache is incompatible with gcov + # Extract the first word of "shtool", so it can be a program name with args. +set dummy shtool; 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_path_SHTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SHTOOL in + [\\/]* | ?:[\\/]*) + ac_cv_path_SHTOOL="$SHTOOL" # Let the user override the test with a path. + ;; + *) + 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_path_SHTOOL="$as_dir/$ac_word$ac_exec_ext" + $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 + + test -z "$ac_cv_path_SHTOOL" && ac_cv_path_SHTOOL="false" + ;; +esac +fi +SHTOOL=$ac_cv_path_SHTOOL +if test -n "$SHTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHTOOL" >&5 +$as_echo "$SHTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + case `$SHTOOL path $CC` in + *ccache*) cc_ccache=yes;; + *) cc_ccache=no;; + esac + + if test "$cc_ccache" = "yes"; then + if test -z "$CCACHE_DISABLE" -o "$CCACHE_DISABLE" != "1"; then + as_fn_error $? "must export CCACHE_DISABLE=1 to disable ccache for code coverage" "$LINENO" 5 + fi + fi + + + # Extract the first word of "lcov", so it can be a program name with args. +set dummy lcov; 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_path_LCOV+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LCOV in + [\\/]* | ?:[\\/]*) + ac_cv_path_LCOV="$LCOV" # Let the user override the test with a path. + ;; + *) + 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_path_LCOV="$as_dir/$ac_word$ac_exec_ext" + $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 + + test -z "$ac_cv_path_LCOV" && ac_cv_path_LCOV="false" + ;; +esac +fi +LCOV=$ac_cv_path_LCOV +if test -n "$LCOV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV" >&5 +$as_echo "$LCOV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$LCOV" = "xfalse"; then + as_fn_error $? "lcov not found" "$LINENO" 5 + fi + + + # Extract the first word of "genhtml", so it can be a program name with args. +set dummy genhtml; 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_path_GENHTML+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GENHTML in + [\\/]* | ?:[\\/]*) + ac_cv_path_GENHTML="$GENHTML" # Let the user override the test with a path. + ;; + *) + 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_path_GENHTML="$as_dir/$ac_word$ac_exec_ext" + $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 + + test -z "$ac_cv_path_GENHTML" && ac_cv_path_GENHTML="false" + ;; +esac +fi +GENHTML=$ac_cv_path_GENHTML +if test -n "$GENHTML"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GENHTML" >&5 +$as_echo "$GENHTML" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$GENHTML" = "xfalse"; then + as_fn_error $? "genhtml not found" "$LINENO" 5 + fi + + +$as_echo "#define SUPPORT_GCOV 1" >>confdefs.h + + + # And add flags needed for gcov + GCOV_CFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" + GCOV_CXXFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" + GCOV_LIBS="-lgcov" + + + +fi # enable_coverage + + if test "x$enable_coverage" = "xyes"; then + WITH_GCOV_TRUE= + WITH_GCOV_FALSE='#' +else + WITH_GCOV_TRUE='#' + WITH_GCOV_FALSE= +fi + + +# Produce these files, in addition to config.h. +ac_config_files="$ac_config_files Makefile libpcre.pc libpcre16.pc libpcre32.pc libpcreposix.pc libpcrecpp.pc pcre-config pcre.h pcre_stringpiece.h pcrecpparg.h" + + +# Make the generated script files executable. +ac_config_commands="$ac_config_commands script-chmod" + + +# Make sure that pcre_chartables.c is removed in case the method for +# creating it was changed by reconfiguration. +ac_config_commands="$ac_config_commands delete-old-chartables" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + 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;} + 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;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +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$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + 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. +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. +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_PCRE32_TRUE}" && test -z "${WITH_PCRE32_FALSE}"; then + as_fn_error $? "conditional \"WITH_PCRE32\" 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. +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. +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 +if test -z "${WITH_VALGRIND_TRUE}" && test -z "${WITH_VALGRIND_FALSE}"; then + as_fn_error $? "conditional \"WITH_VALGRIND\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_GCOV_TRUE}" && test -z "${WITH_GCOV_FALSE}"; then + as_fn_error $? "conditional \"WITH_GCOV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +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 +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# 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. +as_fn_error () +{ + 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: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + 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" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# 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.32, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +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.32 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +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." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +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 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $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;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +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"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +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_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"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +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"`' +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"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +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_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"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +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"`' +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"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in AS \ +DLLTOOL \ +OBJDUMP \ +SHELL \ +ECHO \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +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 \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +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_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_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 \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_flag_spec_ld_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +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\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "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" ;; + "libpcre32.pc") CONFIG_FILES="$CONFIG_FILES libpcre32.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" ;; + "pcre.h") CONFIG_FILES="$CONFIG_FILES pcre.h" ;; + "pcre_stringpiece.h") CONFIG_FILES="$CONFIG_FILES pcre_stringpiece.h" ;; + "pcrecpparg.h") CONFIG_FILES="$CONFIG_FILES pcrecpparg.h" ;; + "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;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap '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 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || 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. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +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' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + 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 '^'` +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 + + 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 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +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 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[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# 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 >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + 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 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) 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 `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + 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'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +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' "$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 +$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;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) 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 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && 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 "$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 "$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" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Assembler program. +AS=$lt_AS + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Object dumper program. +OBJDUMP=$lt_OBJDUMP + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# 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". +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 + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# 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 + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# 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 + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# 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 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# 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 + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # 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 '$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 + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_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 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# 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 + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + "script-chmod":C) chmod a+x pcre-config ;; + "delete-old-chartables":C) rm -f pcre_chartables.c ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + 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 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 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +# Print out a nice little message after configure is run displaying the +# chosen options. + +ebcdic_nl_code=n/a +if test "$enable_ebcdic_nl25" = "yes"; then + ebcdic_nl_code=0x25 +elif test "$enable_ebcdic" = "yes"; then + ebcdic_nl_code=0x15 +fi + +cat <], + [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'.]) + have_strto_fn=1 + break], + [AC_MSG_RESULT(no)]) +done + +if test "$have_strto_fn" = 1; then + AC_CHECK_TYPES([long long], + [pcre_have_long_long="1"], + [pcre_have_long_long="0"]) + AC_CHECK_TYPES([unsigned long long], + [pcre_have_ulong_long="1"], + [pcre_have_ulong_long="0"]) +else + pcre_have_long_long="0" + pcre_have_ulong_long="0" +fi +AC_SUBST(pcre_have_long_long) +AC_SUBST(pcre_have_ulong_long) + +AC_LANG_POP +fi +# Using AC_SUBST eliminates the need to include config.h in a public .h file +AC_SUBST(pcre_have_type_traits) +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_PCRE32, test "x$enable_pcre32" = "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") +AM_CONDITIONAL(WITH_VALGRIND, test "x$enable_valgrind" = "xyes") + +# Checks for typedefs, structures, and compiler characteristics. + +AC_C_CONST +AC_TYPE_SIZE_T + +# Checks for library functions. + +AC_CHECK_FUNCS(bcopy memmove strerror) + +# Check for the availability of libz (aka zlib) + +AC_CHECK_HEADERS([zlib.h], [HAVE_ZLIB_H=1]) +AC_CHECK_LIB([z], [gzopen], [HAVE_LIBZ=1]) + +# Check for the availability of libbz2. Originally we just used AC_CHECK_LIB, +# as for libz. However, this had the following problem, diagnosed and fixed by +# a user: +# +# - libbz2 uses the Pascal calling convention (WINAPI) for the functions +# under Win32. +# - The standard autoconf AC_CHECK_LIB fails to include "bzlib.h", +# therefore missing the function definition. +# - The compiler thus generates a "C" signature for the test function. +# - The linker fails to find the "C" function. +# - PCRE fails to configure if asked to do so against libbz2. +# +# Solution: +# +# - Replace the AC_CHECK_LIB test with a custom test. + +AC_CHECK_HEADERS([bzlib.h], [HAVE_BZLIB_H=1]) +# Original test +# AC_CHECK_LIB([bz2], [BZ2_bzopen], [HAVE_LIBBZ2=1]) +# +# Custom test follows + +AC_MSG_CHECKING([for libbz2]) +OLD_LIBS="$LIBS" +LIBS="$LIBS -lbz2" +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_BZLIB_H +#include +#endif]], +[[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 + +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]) + +PCRE_STATIC_CFLAG="" +if test "x$enable_shared" = "xno" ; then + AC_DEFINE([PCRE_STATIC], [1], [ + Define to any value if linking statically (TODO: make nice with Libtool)]) + PCRE_STATIC_CFLAG="-DPCRE_STATIC" +fi +AC_SUBST(PCRE_STATIC_CFLAG) + +# Here is where pcre specific defines are handled + +if test "$enable_pcre8" = "yes"; then + AC_DEFINE([SUPPORT_PCRE8], [], [ + Define to any value to enable the 8 bit PCRE library.]) +fi + +if test "$enable_pcre16" = "yes"; then + AC_DEFINE([SUPPORT_PCRE16], [], [ + Define to any value to enable the 16 bit PCRE library.]) +fi + +if test "$enable_pcre32" = "yes"; then + AC_DEFINE([SUPPORT_PCRE32], [], [ + Define to any value to enable the 32 bit PCRE library.]) +fi + +if test "$enable_jit" = "yes"; then + AX_PTHREAD([], [AC_MSG_ERROR([JIT support requires pthreads])]) + CC="$PTHREAD_CC" + CFLAGS="$PTHREAD_CFLAGS $CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_DEFINE([SUPPORT_JIT], [], [ + Define to any value 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 any value to enable JIT support in pcregrep.]) +fi + +if test "$enable_utf" = "yes"; then + AC_DEFINE([SUPPORT_UTF], [], [ + Define to any value to enable support for the UTF-8/16/32 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/32, but not both at once.]) +fi + +if test "$enable_unicode_properties" = "yes"; then + AC_DEFINE([SUPPORT_UCP], [], [ + Define to any value to enable support for Unicode properties.]) +fi + +if test "$enable_stack_for_recursion" = "no"; then + AC_DEFINE([NO_RECURSE], [], [ + PCRE uses recursive function calls to handle backtracking while + matching. This can sometimes be a problem on systems that have + stacks of limited size. Define NO_RECURSE to any value to get a + version that doesn't use recursion in the match() function; instead + it creates its own stack by steam using pcre_recurse_malloc() to obtain + memory from the heap. For more detail, see the comments and other stuff + just above the match() function.]) +fi + +if test "$enable_pcregrep_libz" = "yes"; then + AC_DEFINE([SUPPORT_LIBZ], [], [ + Define to any value to allow pcregrep to be linked with libz, so that it is + able to handle .gz files.]) +fi + +if test "$enable_pcregrep_libbz2" = "yes"; then + AC_DEFINE([SUPPORT_LIBBZ2], [], [ + Define to any value to allow pcregrep to be linked with libbz2, so that it + is able to handle .bz2 files.]) +fi + +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. 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 any value to allow pcretest to be linked with libedit.]) + LIBREADLINE="$LIBEDIT" +elif test "$enable_pcretest_libreadline" = "yes"; then + AC_DEFINE([SUPPORT_LIBREADLINE], [], [ + Define to any value to allow pcretest to be linked with libreadline.]) +fi + +AC_DEFINE_UNQUOTED([NEWLINE], [$ac_pcre_newline_value], [ + The value of NEWLINE determines the default newline character sequence. PCRE + client programs can override this by selecting other values at run time. In + ASCII environments, the value can be 10 (LF), 13 (CR), or 3338 (CRLF); in + EBCDIC environments the value can be 21 or 37 (LF), 13 (CR), or 3349 or 3365 + (CRLF) because there are two alternative codepoints (0x15 and 0x25) that are + used as the NL line terminator that is equivalent to ASCII LF. In both ASCII + and EBCDIC environments the value can also be -1 (ANY), or -2 (ANYCRLF).]) + +if test "$enable_bsr_anycrlf" = "yes"; then + AC_DEFINE([BSR_ANYCRLF], [], [ + By default, the \R escape sequence matches any Unicode line ending + character or sequence of characters. If BSR_ANYCRLF is defined (to any + value), this is changed so that backslash-R matches only CR, LF, or CRLF. + The build-time default can be overridden by the user of PCRE at runtime.]) +fi + +AC_DEFINE_UNQUOTED([LINK_SIZE], [$with_link_size], [ + The value of LINK_SIZE determines the number of bytes used to store + links as offsets within the compiled regex. The default is 2, which + allows for compiled patterns up to 64K long. This covers the vast + majority of cases. However, PCRE can also be compiled to use 3 or 4 + bytes instead. This allows for longer patterns in extreme cases.]) + +AC_DEFINE_UNQUOTED([POSIX_MALLOC_THRESHOLD], [$with_posix_malloc_threshold], [ + When calling PCRE via the POSIX interface, 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 threshold above which + the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD.]) + +AC_DEFINE_UNQUOTED([MATCH_LIMIT], [$with_match_limit], [ + The value of MATCH_LIMIT determines the default number of times the + internal match() function can be called during a single execution of + pcre_exec(). There is a runtime interface for setting a different + limit. The limit exists in order to catch runaway regular + expressions that take for ever to determine that they do not match. + The default is set very large so that it does not accidentally catch + legitimate cases.]) + +AC_DEFINE_UNQUOTED([MATCH_LIMIT_RECURSION], [$with_match_limit_recursion], [ + The above limit applies to all calls of match(), whether or not they + increase the recursion depth. In some environments it is desirable + to limit the depth of recursive calls of match() more strictly, in + order to restrict the maximum amount of stack (or heap, if + NO_RECURSE is defined) that is used. The value of + MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To + have any useful effect, it must be less than the value of + MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. + There is a runtime method for setting a different limit.]) + +AC_DEFINE([MAX_NAME_SIZE], [32], [ + This limit is parameterized just in case anybody ever wants to + change it. Care must be taken if it is increased, because it guards + against integer overflow caused by enormously large patterns.]) + +AC_DEFINE([MAX_NAME_COUNT], [10000], [ + This limit is parameterized just in case anybody ever wants to + change it. Care must be taken if it is increased, because it guards + against integer overflow caused by enormously large patterns.]) + +AH_VERBATIM([PCRE_EXP_DEFN], [ +/* 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 + of a function that is exported by the library, define this macro to + contain the relevant magic. If you do not define this macro, a suitable + __declspec value is used for Windows systems; in other environments + "extern" is used for a C compiler and "extern C" for a C++ compiler. + This macro apears at the start of every exported function that is part + of the external API. It does not appear on functions that are "external" + in the C sense, but which are internal to the library. */ +#undef PCRE_EXP_DEFN]) + +if test "$enable_ebcdic" = "yes"; then + AC_DEFINE_UNQUOTED([EBCDIC], [], [ + If you are compiling for a system that uses EBCDIC instead of ASCII + character codes, define this macro to any value. You must also edit the + NEWLINE macro below to set a suitable EBCDIC newline, commonly 21 (0x15). + On systems that can use "configure" or CMake to set EBCDIC, NEWLINE is + automatically adjusted. When EBCDIC is set, PCRE assumes that all input + strings are in EBCDIC. If you do not define this macro, PCRE will assume + input strings are ASCII or UTF-8/16/32 Unicode. It is not possible to build + a version of PCRE that supports both EBCDIC and UTF-8/16/32.]) +fi + +if test "$enable_ebcdic_nl25" = "yes"; then + AC_DEFINE_UNQUOTED([EBCDIC_NL25], [], [ + In an EBCDIC environment, define this macro to any value to arrange for + the NL character to be 0x25 instead of the default 0x15. NL plays the role + that LF does in an ASCII/Unicode environment. The value must also be set in + the NEWLINE macro below. On systems that can use "configure" or CMake to + set EBCDIC_NL25, the adjustment of NEWLINE is automatic.]) +fi + +if test "$enable_valgrind" = "yes"; then + AC_DEFINE_UNQUOTED([SUPPORT_VALGRIND], [], [ + Valgrind support to find invalid memory reads.]) +fi + +# Platform specific issues +NO_UNDEFINED= +EXPORT_ALL_SYMBOLS= +case $host_os in + cygwin* | mingw* ) + if test X"$enable_shared" = Xyes; then + NO_UNDEFINED="-no-undefined" + EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols" + fi + ;; +esac + +# The extra LDFLAGS for each particular library +# (Note: The libpcre*_version bits are m4 variables, assigned above) + +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_LIBPCRE32_LDFLAGS="$EXTRA_LIBPCRE32_LDFLAGS \ + $NO_UNDEFINED -version-info libpcre32_version" + +EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \ + $NO_UNDEFINED -version-info libpcreposix_version" + +EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \ + $NO_UNDEFINED -version-info libpcrecpp_version \ + $EXPORT_ALL_SYMBOLS" + +AC_SUBST(EXTRA_LIBPCRE_LDFLAGS) +AC_SUBST(EXTRA_LIBPCRE16_LDFLAGS) +AC_SUBST(EXTRA_LIBPCRE32_LDFLAGS) +AC_SUBST(EXTRA_LIBPCREPOSIX_LDFLAGS) +AC_SUBST(EXTRA_LIBPCRECPP_LDFLAGS) + +# When we run 'make distcheck', use these arguments. Turning off compiler +# optimization makes it run faster. +DISTCHECK_CONFIGURE_FLAGS="CFLAGS='' CXXFLAGS='' --enable-pcre16 --enable-pcre32 --enable-jit --enable-cpp --enable-unicode-properties" +AC_SUBST(DISTCHECK_CONFIGURE_FLAGS) + +# Check that, if --enable-pcregrep-libz or --enable-pcregrep-libbz2 is +# specified, the relevant library is available. + +if test "$enable_pcregrep_libz" = "yes"; then + if test "$HAVE_ZLIB_H" != "1"; then + echo "** Cannot --enable-pcregrep-libz because zlib.h was not found" + exit 1 + fi + if test "$HAVE_LIBZ" != "1"; then + echo "** Cannot --enable-pcregrep-libz because libz was not found" + exit 1 + fi + LIBZ="-lz" +fi +AC_SUBST(LIBZ) + +if test "$enable_pcregrep_libbz2" = "yes"; then + if test "$HAVE_BZLIB_H" != "1"; then + echo "** Cannot --enable-pcregrep-libbz2 because bzlib.h was not found" + exit 1 + fi + if test "$HAVE_LIBBZ2" != "1"; then + echo "** Cannot --enable-pcregrep-libbz2 because libbz2 was not found" + exit 1 + fi + LIBBZ2="-lbz2" +fi +AC_SUBST(LIBBZ2) + +# 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." + exit 1 + fi + if test "$HAVE_HISTORY_H" != "1"; then + echo "** Cannot --enable-pcretest-readline because readline/history.h was not found." + exit 1 + fi + if test -z "$LIBREADLINE"; then + echo "** Cannot --enable-pcretest-readline because readline library was not found." + exit 1 + fi +fi + +# Check for valgrind + +if test "$enable_valgrind" = "yes"; then + m4_ifdef([PKG_CHECK_MODULES], + [PKG_CHECK_MODULES([VALGRIND],[valgrind])], + [AC_MSG_ERROR([pkg-config not supported])]) +fi + +# test code coverage reporting +if test "$enable_coverage" = "yes"; then + if test "x$GCC" != "xyes"; then + AC_MSG_ERROR([Code coverage reports can only be generated when using GCC]) + fi + + # ccache is incompatible with gcov + AC_PATH_PROG([SHTOOL],[shtool],[false]) + case `$SHTOOL path $CC` in + *ccache*) cc_ccache=yes;; + *) cc_ccache=no;; + esac + + if test "$cc_ccache" = "yes"; then + if test -z "$CCACHE_DISABLE" -o "$CCACHE_DISABLE" != "1"; then + AC_MSG_ERROR([must export CCACHE_DISABLE=1 to disable ccache for code coverage]) + fi + fi + + AC_ARG_VAR([LCOV],[the ltp lcov program]) + AC_PATH_PROG([LCOV],[lcov],[false]) + if test "x$LCOV" = "xfalse"; then + AC_MSG_ERROR([lcov not found]) + fi + + AC_ARG_VAR([GENHTML],[the ltp genhtml program]) + AC_PATH_PROG([GENHTML],[genhtml],[false]) + if test "x$GENHTML" = "xfalse"; then + AC_MSG_ERROR([genhtml not found]) + fi + + AC_DEFINE([SUPPORT_GCOV],[1], [ + Define to allow pcretest and pcregrep to be linked with gcov, so that they + are able to generate code coverage reports.]) + + # And add flags needed for gcov + GCOV_CFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" + GCOV_CXXFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" + GCOV_LIBS="-lgcov" + AC_SUBST([GCOV_CFLAGS]) + AC_SUBST([GCOV_CXXFLAGS]) + AC_SUBST([GCOV_LIBS]) +fi # enable_coverage + +AM_CONDITIONAL([WITH_GCOV],[test "x$enable_coverage" = "xyes"]) + +# Produce these files, in addition to config.h. +AC_CONFIG_FILES( + Makefile + libpcre.pc + libpcre16.pc + libpcre32.pc + libpcreposix.pc + libpcrecpp.pc + pcre-config + pcre.h + pcre_stringpiece.h + pcrecpparg.h +) + +# Make the generated script files executable. +AC_CONFIG_COMMANDS([script-chmod], [chmod a+x pcre-config]) + +# Make sure that pcre_chartables.c is removed in case the method for +# creating it was changed by reconfiguration. +AC_CONFIG_COMMANDS([delete-old-chartables], [rm -f pcre_chartables.c]) + +AC_OUTPUT + +# Print out a nice little message after configure is run displaying the +# chosen options. + +ebcdic_nl_code=n/a +if test "$enable_ebcdic_nl25" = "yes"; then + ebcdic_nl_code=0x25 +elif test "$enable_ebcdic" = "yes"; then + ebcdic_nl_code=0x15 +fi + +cat <. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' "$nl" < "$tmpdepfile" | +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependent.h'. + # Do two passes, one to just change these to + # '$object: dependent.h' and one to simply 'dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'. + # However on + # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\': + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + # tcc 0.9.26 (FIXME still under development at the moment of writing) + # will emit a similar output, but also prepend the continuation lines + # with horizontal tabulation characters. + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form 'foo.o: dependent.h', + # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'. + # Do two passes, one to just change these to + # '$object: dependent.h' and one to simply 'dependent.h:'. + sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \ + < "$tmpdepfile" > "$depfile" + sed ' + s/[ '"$tab"'][ '"$tab"']*/ /g + s/^ *// + s/ *\\*$// + s/^[^:]*: *// + /^$/d + /:$/d + s/$/ :/ + ' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' "$nl" < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/tools/pcre/dftables.c b/tools/pcre/dftables.c new file mode 100644 index 00000000..1fdc8e0f --- /dev/null +++ b/tools/pcre/dftables.c @@ -0,0 +1,212 @@ +/************************************************* +* 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 is a freestanding support program to generate a file containing +character tables for PCRE. The tables are built according to the current +locale. Now that pcre_maketables is a function visible to the outside world, we +make use of its code from here in order to be consistent. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "pcre_internal.h" + +#define DFTABLES /* pcre_maketables.c notices this */ +#include "pcre_maketables.c" + + +int main(int argc, char **argv) +{ +FILE *f; +int i = 1; +const unsigned char *tables; +const unsigned char *base_of_tables; + +/* By default, the default C locale is used rather than what the building user +happens to have set. However, if the -L option is given, set the locale from +the LC_xxx environment variables. */ + +if (argc > 1 && strcmp(argv[1], "-L") == 0) + { + setlocale(LC_ALL, ""); /* Set from environment variables */ + i++; + } + +if (argc < i + 1) + { + fprintf(stderr, "dftables: one filename argument is required\n"); + return 1; + } + +tables = pcre_maketables(); +base_of_tables = tables; + +f = fopen(argv[i], "wb"); +if (f == NULL) + { + fprintf(stderr, "dftables: failed to open %s for writing\n", argv[1]); + return 1; + } + +/* There are several fprintf() calls here, because gcc in pedantic mode +complains about the very long string otherwise. */ + +fprintf(f, + "/*************************************************\n" + "* Perl-Compatible Regular Expressions *\n" + "*************************************************/\n\n" + "/* This file was automatically written by the dftables auxiliary\n" + "program. It contains character tables that are used when no external\n" + "tables are passed to PCRE by the application that calls it. The tables\n" + "are used only for characters whose code values are less than 256.\n\n"); +fprintf(f, + "The following #includes are present because without them gcc 4.x may remove\n" + "the array definition from the final binary if PCRE is built into a static\n" + "library and dead code stripping is activated. This leads to link errors.\n" + "Pulling in the header ensures that the array gets flagged as \"someone\n" + "outside this compilation unit might reference this\" and so it will always\n" + "be supplied to the linker. */\n\n"); + +/* Force config.h in z/OS */ + +#if defined NATIVE_ZOS +fprintf(f, + "/* For z/OS, config.h is forced */\n" + "#ifndef HAVE_CONFIG_H\n" + "#define HAVE_CONFIG_H 1\n" + "#endif\n\n"); +#endif + +fprintf(f, + "#ifdef HAVE_CONFIG_H\n" + "#include \"config.h\"\n" + "#endif\n\n" + "#include \"pcre_internal.h\"\n\n"); + +fprintf(f, + "const pcre_uint8 PRIV(default_tables)[] = {\n\n" + "/* This table is a lower casing table. */\n\n"); + +fprintf(f, " "); +for (i = 0; i < 256; i++) + { + if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); + fprintf(f, "%3d", *tables++); + if (i != 255) fprintf(f, ","); + } +fprintf(f, ",\n\n"); + +fprintf(f, "/* This table is a case flipping table. */\n\n"); + +fprintf(f, " "); +for (i = 0; i < 256; i++) + { + if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); + fprintf(f, "%3d", *tables++); + if (i != 255) fprintf(f, ","); + } +fprintf(f, ",\n\n"); + +fprintf(f, + "/* This table contains bit maps for various character classes.\n" + "Each map is 32 bytes long and the bits run from the least\n" + "significant end of each byte. The classes that have their own\n" + "maps are: space, xdigit, digit, upper, lower, word, graph\n" + "print, punct, and cntrl. Other classes are built from combinations. */\n\n"); + +fprintf(f, " "); +for (i = 0; i < cbit_length; i++) + { + if ((i & 7) == 0 && i != 0) + { + if ((i & 31) == 0) fprintf(f, "\n"); + fprintf(f, "\n "); + } + fprintf(f, "0x%02x", *tables++); + if (i != cbit_length - 1) fprintf(f, ","); + } +fprintf(f, ",\n\n"); + +fprintf(f, + "/* This table identifies various classes of character by individual bits:\n" + " 0x%02x white space character\n" + " 0x%02x letter\n" + " 0x%02x decimal digit\n" + " 0x%02x hexadecimal digit\n" + " 0x%02x alphanumeric or '_'\n" + " 0x%02x regular expression metacharacter or binary zero\n*/\n\n", + ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word, + ctype_meta); + +fprintf(f, " "); +for (i = 0; i < 256; i++) + { + if ((i & 7) == 0 && i != 0) + { + fprintf(f, " /* "); + if (isprint(i-8)) fprintf(f, " %c -", i-8); + else fprintf(f, "%3d-", i-8); + if (isprint(i-1)) fprintf(f, " %c ", i-1); + else fprintf(f, "%3d", i-1); + fprintf(f, " */\n "); + } + fprintf(f, "0x%02x", *tables++); + if (i != 255) fprintf(f, ","); + } + +fprintf(f, "};/* "); +if (isprint(i-8)) fprintf(f, " %c -", i-8); + else fprintf(f, "%3d-", i-8); +if (isprint(i-1)) fprintf(f, " %c ", i-1); + else fprintf(f, "%3d", i-1); +fprintf(f, " */\n\n/* End of pcre_chartables.c */\n"); + +fclose(f); +free((void *)base_of_tables); +return 0; +} + +/* End of dftables.c */ diff --git a/tools/pcre/doc/html/index.html b/tools/pcre/doc/html/index.html new file mode 100644 index 00000000..21e11eaf --- /dev/null +++ b/tools/pcre/doc/html/index.html @@ -0,0 +1,180 @@ + + + +PCRE specification + + +

Perl-compatible Regular Expressions (PCRE)

+

+The HTML documentation for PCRE comprises the following pages: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
pcre  Introductory page
pcre16  Discussion of the 16-bit PCRE library
pcre32  Discussion of the 32-bit PCRE library
pcre-config  Information about the installation configuration
pcreapi  PCRE's native API
pcrebuild  Options for building PCRE
pcrecallout  The callout facility
pcrecompat  Compability with Perl
pcrecpp  The C++ wrapper for the PCRE library
pcredemo  A demonstration C program that uses the PCRE library
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
pcrepartial  Using PCRE for partial matching
pcrepattern  Specification of the regular expressions supported by PCRE
pcreperform  Some comments on performance
pcreposix  The POSIX API to the PCRE library
pcreprecompile  How to save and re-use compiled patterns
pcresample  Discussion of the pcredemo program
pcrestack  Discussion of PCRE's stack usage
pcresyntax  Syntax quick-reference summary
pcretest  The pcretest command for testing PCRE
pcreunicode  Discussion of Unicode and UTF-8/UTF-16/UTF-32 support
+ +

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

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
pcre_assign_jit_stack  Assign stack for JIT matching
pcre_compile  Compile a regular expression
pcre_compile2  Compile a regular expression (alternate interface)
pcre_config  Show build-time configuration options
pcre_copy_named_substring  Extract named substring into given buffer
pcre_copy_substring  Extract numbered substring into given buffer
pcre_dfa_exec  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_free_substring  Free extracted substring
pcre_free_substring_list  Free list of extracted substrings
pcre_fullinfo  Extract information about a pattern
pcre_get_named_substring  Extract named substring into new memory
pcre_get_stringnumber  Convert captured string name to number
pcre_get_substring  Extract numbered substring into new memory
pcre_get_substring_list  Extract all substrings into new memory
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_utf32_to_host_byte_order  Convert UTF-32 string to host byte order if necessary
pcre_version  Return PCRE version and release date
+ + diff --git a/tools/pcre/doc/html/pcre-config.html b/tools/pcre/doc/html/pcre-config.html new file mode 100644 index 00000000..c2e3ba28 --- /dev/null +++ b/tools/pcre/doc/html/pcre-config.html @@ -0,0 +1,109 @@ + + +pcre-config specification + + +

pcre-config 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
+

+pcre-config [--prefix] [--exec-prefix] [--version] [--libs] +[--libs16] [--libs32] [--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. Some of +the options apply only to the 8-bit, or 16-bit, or 32-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, /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) to the standard output. +

+

+--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 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). +

+

+--libs32 +Writes to the standard output the command line options required to link +with the 32-bit PCRE library (-lpcre32 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 +PCRE's POSIX API wrapper library (-lpcreposix -lpcre on many +systems). +

+

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

+

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

+
SEE ALSO
+

+pcre(3) +

+
AUTHOR
+

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

+
REVISION
+

+Last updated: 24 June 2012 +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre.html b/tools/pcre/doc/html/pcre.html new file mode 100644 index 00000000..edb7479a --- /dev/null +++ b/tools/pcre/doc/html/pcre.html @@ -0,0 +1,204 @@ + + +pcre specification + + +

pcre 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. +
+

+
INTRODUCTION
+

+The PCRE library is a set of functions that implement regular expression +pattern matching using the same syntax and semantics as Perl, with just a few +differences. Some features that appeared in Python and PCRE before they +appeared in Perl are also available using the Python syntax, there is some +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. +

+

+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. +

+

+Starting with release 8.32 it is possible to compile a third separate PCRE +library, which supports 32-bit character strings (including +UTF-32 strings). The build process allows any set of the 8-, 16- and 32-bit +libraries. The work to make this possible was done by Christian Persch. +

+

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

+

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

+

+In addition to the Perl-compatible matching function, PCRE contains an +alternative function that matches the same compiled patterns in a different +way. In certain circumstances, the alternative function has some advantages. +For a discussion of the two matching algorithms, see the +pcrematching +page. +

+

+PCRE is written in C and released as a C library. A number of people have +written wrappers and interfaces of various kinds. In particular, Google Inc. +have provided a comprehensive C++ wrapper for the 8-bit library. This is now +included as part of the PCRE distribution. The +pcrecpp +page has details of this interface. Other people's contributions 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 not +supported by PCRE are given in separate documents. See the +pcrepattern +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 themselves are described in the +pcrebuild +page. Documentation about building PCRE for various operating systems can be +found in the README and NON-AUTOTOOLS_BUILD files in the source +distribution. +

+

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

+
SECURITY CONSIDERATIONS
+

+If you are using PCRE in a non-UTF application that permits users to supply +arbitrary patterns for compilation, you should be aware of a feature that +allows users to turn on UTF support from within a pattern, provided that PCRE +was built with UTF support. For example, an 8-bit pattern that begins with +"(*UTF8)" or "(*UTF)" turns on UTF-8 mode, which interprets patterns and +subjects as strings of UTF-8 characters instead of individual 8-bit characters. +This causes both the pattern and any data against which it is matched to be +checked for UTF-8 validity. If the data string is very long, such a check might +use sufficiently many resources as to cause your application to lose +performance. +

+

+The best way of guarding against this possibility is to use the +pcre_fullinfo() function to check the compiled pattern's options for UTF. +

+

+If your application is one that supports UTF, be aware that validity checking +can take time. If the same data string is to be matched many times, you can use +the PCRE_NO_UTF[8|16|32]_CHECK option for the second and subsequent matches to +save redundant checks. +

+

+Another way that performance can be hit is by running a pattern that has a very +large search tree against a string that will never match. Nested unlimited +repeats in a pattern are a common example. PCRE provides some protection +against this: see the PCRE_EXTRA_MATCH_LIMIT feature in the +pcreapi +page. +

+
USER DOCUMENTATION
+

+The user documentation for PCRE comprises a number of different sections. 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 section, are concatenated, for ease +of searching. The sections are as follows: +

+  pcre              this document
+  pcre16            details of the 16-bit library
+  pcre32            details of the 32-bit library
+  pcre-config       show PCRE installation configuration information
+  pcreapi           details of PCRE's native C API
+  pcrebuild         options for building PCRE
+  pcrecallout       details of the callout feature
+  pcrecompat        discussion of Perl compatibility
+  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 (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 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/32 support
+
+In addition, in the "man" and HTML formats, there is a short page for each +C library function, listing its arguments and results. +

+
AUTHOR
+

+Philip Hazel +
+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: 11 November 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre16.html b/tools/pcre/doc/html/pcre16.html new file mode 100644 index 00000000..179b2ada --- /dev/null +++ b/tools/pcre/doc/html/pcre16.html @@ -0,0 +1,383 @@ + + +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 all 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 "unsigned 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 pcre32_config(), or if the +PCRE_CONFIG_UTF8 or PCRE_CONFIG_UTF32 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  Non-character
+
+

+
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 both the 8-bit and the 32-bit libraries were 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, +16-bit and 32-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: 08 November 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre_assign_jit_stack.html b/tools/pcre/doc/html/pcre_assign_jit_stack.html new file mode 100644 index 00000000..d77d4e1c --- /dev/null +++ b/tools/pcre/doc/html/pcre_assign_jit_stack.html @@ -0,0 +1,76 @@ + + +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); +

+

+void pcre32_assign_jit_stack(pcre32_extra *extra, +pcre32_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|32]_exec() with a pattern that has been successfully +compiled with JIT optimization. The arguments are: +

+  extra     the data pointer returned by pcre[16|32]_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|32]_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|32]_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 --git a/tools/pcre/doc/html/pcre_compile.html b/tools/pcre/doc/html/pcre_compile.html new file mode 100644 index 00000000..01214751 --- /dev/null +++ b/tools/pcre/doc/html/pcre_compile.html @@ -0,0 +1,108 @@ + + +pcre_compile specification + + +

pcre_compile 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 *pcre_compile(const char *pattern, int options, +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); +

+

+pcre32 *pcre32_compile(PCRE_SPTR32 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[16|32]_compile2(), except for the absence of the +errorcodeptr argument. Its arguments are: +

+  pattern       A zero-terminated string containing the
+                  regular expression to be compiled
+  options       Zero or more option bits
+  errptr        Where to put an error message
+  erroffset     Offset in pattern where error was found
+  tableptr      Pointer to character tables, or NULL to
+                  use the built-in default
+
+The option bits are: +
+  PCRE_ANCHORED           Force pattern anchoring
+  PCRE_AUTO_CALLOUT       Compile automatic callouts
+  PCRE_BSR_ANYCRLF        \R matches only CR, LF, or CRLF
+  PCRE_BSR_UNICODE        \R matches all Unicode line endings
+  PCRE_CASELESS           Do caseless matching
+  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 white space and # comments
+  PCRE_EXTRA              PCRE extra features
+                            (not much use currently)
+  PCRE_FIRSTLINE          Force matching to be before newline
+  PCRE_JAVASCRIPT_COMPAT  JavaScript compatibility
+  PCRE_MULTILINE          ^ and $ match newlines within data
+  PCRE_NEWLINE_ANY        Recognize any Unicode newline sequence
+  PCRE_NEWLINE_ANYCRLF    Recognize CR, LF, and CRLF as newline
+                            sequences
+  PCRE_NEWLINE_CR         Set CR as the newline sequence
+  PCRE_NEWLINE_CRLF       Set CRLF as the newline sequence
+  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_UTF32_CHECK     Do not check the pattern for UTF-32
+                            validity (only relevant if
+                            PCRE_UTF32 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_UTF16              Run in pcre16_compile() UTF-16 mode
+  PCRE_UTF32              Run in pcre32_compile() UTF-32 mode
+  PCRE_UTF8               Run in pcre_compile() UTF-8 mode
+
+PCRE must be built with UTF support in order to use PCRE_UTF8/16/32 and +PCRE_NO_UTF8/16/32_CHECK, and with UCP support if PCRE_UCP is used. +

+

+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 +compiling regular expressions with one version of PCRE for use with a different +version is not guaranteed to work and may cause crashes. +

+

+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 --git a/tools/pcre/doc/html/pcre_compile2.html b/tools/pcre/doc/html/pcre_compile2.html new file mode 100644 index 00000000..7d76bd9c --- /dev/null +++ b/tools/pcre/doc/html/pcre_compile2.html @@ -0,0 +1,112 @@ + + +pcre_compile2 specification + + +

pcre_compile2 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 *pcre_compile2(const char *pattern, int options, +int *errorcodeptr, +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); +

+

+pcre32 *pcre32_compile2(PCRE_SPTR32 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[16|32]_compile(), except for the addition of the +errorcodeptr argument. The arguments are: +

+  pattern       A zero-terminated string containing the
+                  regular expression to be compiled
+  options       Zero or more option bits
+  errorcodeptr  Where to put an error code
+  errptr        Where to put an error message
+  erroffset     Offset in pattern where error was found
+  tableptr      Pointer to character tables, or NULL to
+                  use the built-in default
+
+The option bits are: +
+  PCRE_ANCHORED           Force pattern anchoring
+  PCRE_AUTO_CALLOUT       Compile automatic callouts
+  PCRE_BSR_ANYCRLF        \R matches only CR, LF, or CRLF
+  PCRE_BSR_UNICODE        \R matches all Unicode line endings
+  PCRE_CASELESS           Do caseless matching
+  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 white space and # comments
+  PCRE_EXTRA              PCRE extra features
+                            (not much use currently)
+  PCRE_FIRSTLINE          Force matching to be before newline
+  PCRE_JAVASCRIPT_COMPAT  JavaScript compatibility
+  PCRE_MULTILINE          ^ and $ match newlines within data
+  PCRE_NEWLINE_ANY        Recognize any Unicode newline sequence
+  PCRE_NEWLINE_ANYCRLF    Recognize CR, LF, and CRLF as newline
+                            sequences
+  PCRE_NEWLINE_CR         Set CR as the newline sequence
+  PCRE_NEWLINE_CRLF       Set CRLF as the newline sequence
+  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_UTF32_CHECK     Do not check the pattern for UTF-32
+                            validity (only relevant if
+                            PCRE_UTF32 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_UTF16              Run pcre16_compile() in UTF-16 mode
+  PCRE_UTF32              Run pcre32_compile() in UTF-32 mode
+  PCRE_UTF8               Run pcre_compile() in UTF-8 mode
+
+PCRE must be built with UTF support in order to use PCRE_UTF8/16/32 and +PCRE_NO_UTF8/16/32_CHECK, and with UCP support if PCRE_UCP is used. +

+

+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 +compiling regular expressions with one version of PCRE for use with a different +version is not guaranteed to work and may cause crashes. +

+

+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 --git a/tools/pcre/doc/html/pcre_config.html b/tools/pcre/doc/html/pcre_config.html new file mode 100644 index 00000000..fc10d183 --- /dev/null +++ b/tools/pcre/doc/html/pcre_config.html @@ -0,0 +1,91 @@ + + +pcre_config specification + + +

pcre_config 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_config(int what, void *where); +

+

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

+

+int pcre32_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. The +arguments are as follows: +

+  what     A code specifying what information is required
+  where    Points to where to put the data
+
+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
+                            Internal recursion depth limit
+  PCRE_CONFIG_NEWLINE       Value of the default newline sequence:
+                                13 (0x000d)    for CR
+                                10 (0x000a)    for LF
+                              3338 (0x0d0a)    for CRLF
+                                -2             for ANYCRLF
+                                -1             for ANY
+  PCRE_CONFIG_BSR           Indicates what \R matches by default:
+                                 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
+  PCRE_CONFIG_STACKRECURSE  Recursion implementation (1=stack 0=heap)
+  PCRE_CONFIG_UTF16         Availability of UTF-16 support (1=yes
+                               0=no); option for pcre16_config()
+  PCRE_CONFIG_UTF32         Availability of UTF-32 support (1=yes
+                               0=no); option for pcre32_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. That error +is also given if PCRE_CONFIG_UTF16 or PCRE_CONFIG_UTF32 is passed to +pcre_config(), if PCRE_CONFIG_UTF8 or PCRE_CONFIG_UTF32 is passed to +pcre16_config(), or if PCRE_CONFIG_UTF8 or PCRE_CONFIG_UTF16 is passed to +pcre32_config(). +

+

+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 --git a/tools/pcre/doc/html/pcre_copy_named_substring.html b/tools/pcre/doc/html/pcre_copy_named_substring.html new file mode 100644 index 00000000..ae4f6905 --- /dev/null +++ b/tools/pcre/doc/html/pcre_copy_named_substring.html @@ -0,0 +1,65 @@ + + +pcre_copy_named_substring specification + + +

pcre_copy_named_substring 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_copy_named_substring(const pcre *code, +const char *subject, int *ovector, +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); +

+

+int pcre32_copy_named_substring(const pcre32 *code, +PCRE_SPTR32 subject, int *ovector, +int stringcount, PCRE_SPTR32 stringname, +PCRE_UCHAR32 *buffer, int buffersize); +

+
+DESCRIPTION +
+

+This is a convenience function for extracting a captured substring, identified +by name, into a given buffer. The arguments are: +

+  code          Pattern that was successfully matched
+  subject       Subject that has been successfully matched
+  ovector       Offset vector that pcre[16|32]_exec() used
+  stringcount   Value returned by pcre[16|32]_exec()
+  stringname    Name of the required substring
+  buffer        Buffer to receive the string
+  buffersize    Size of buffer
+
+The yield is the length of the substring, PCRE_ERROR_NOMEMORY if the buffer was +too small, or PCRE_ERROR_NOSUBSTRING if the string name is invalid. +

+

+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 --git a/tools/pcre/doc/html/pcre_copy_substring.html b/tools/pcre/doc/html/pcre_copy_substring.html new file mode 100644 index 00000000..12bfb636 --- /dev/null +++ b/tools/pcre/doc/html/pcre_copy_substring.html @@ -0,0 +1,61 @@ + + +pcre_copy_substring specification + + +

pcre_copy_substring 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_copy_substring(const char *subject, int *ovector, +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); +

+

+int pcre32_copy_substring(PCRE_SPTR32 subject, int *ovector, +int stringcount, int stringnumber, PCRE_UCHAR32 *buffer, +int buffersize); +

+
+DESCRIPTION +
+

+This is a convenience function for extracting a captured substring into a given +buffer. The arguments are: +

+  subject       Subject that has been successfully matched
+  ovector       Offset vector that pcre[16|32]_exec() used
+  stringcount   Value returned by pcre[16|32]_exec()
+  stringnumber  Number of the required substring
+  buffer        Buffer to receive the string
+  buffersize    Size of buffer
+
+The yield is the length of the string, PCRE_ERROR_NOMEMORY if the buffer was +too small, or PCRE_ERROR_NOSUBSTRING if the string number is invalid. +

+

+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 --git a/tools/pcre/doc/html/pcre_dfa_exec.html b/tools/pcre/doc/html/pcre_dfa_exec.html new file mode 100644 index 00000000..663e1d0f --- /dev/null +++ b/tools/pcre/doc/html/pcre_dfa_exec.html @@ -0,0 +1,128 @@ + + +pcre_dfa_exec specification + + +

pcre_dfa_exec 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_dfa_exec(const pcre *code, const pcre_extra *extra, +const char *subject, int length, int startoffset, +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); +

+

+int pcre32_dfa_exec(const pcre32 *code, const pcre32_extra *extra, +PCRE_SPTR32 subject, int length, int startoffset, +int options, int *ovector, int ovecsize, +int *workspace, int wscount); +

+
+DESCRIPTION +
+

+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[16|32]_exec(). The arguments for this function +are: +

+  code         Points to the compiled pattern
+  extra        Points to an associated pcre[16|32]_extra structure,
+                 or is NULL
+  subject      Points to the subject string
+  length       Length of the subject string, in bytes
+  startoffset  Offset in bytes in the subject at which to
+                 start matching
+  options      Option bits
+  ovector      Points to a vector of ints for result offsets
+  ovecsize     Number of elements in the vector
+  workspace    Points to a vector of ints used as working space
+  wscount      Number of elements in the vector
+
+The options are: +
+  PCRE_ANCHORED          Match only at the first position
+  PCRE_BSR_ANYCRLF       \R matches only CR, LF, or CRLF
+  PCRE_BSR_UNICODE       \R matches all Unicode line endings
+  PCRE_NEWLINE_ANY       Recognize any Unicode newline sequence
+  PCRE_NEWLINE_ANYCRLF   Recognize CR, LF, & CRLF as newline sequences
+  PCRE_NEWLINE_CR        Recognize CR as the only newline sequence
+  PCRE_NEWLINE_CRLF      Recognize CRLF as the only newline sequence
+  PCRE_NEWLINE_LF        Recognize LF as the only newline sequence
+  PCRE_NOTBOL            Subject is not the beginning of a line
+  PCRE_NOTEOL            Subject is not the end of a line
+  PCRE_NOTEMPTY          An empty string is not a valid match
+  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_UTF32_CHECK    Do not check the subject for UTF-32
+                           validity (only relevant if PCRE_UTF32
+                           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)
+  PCRE_PARTIAL           ) Return PCRE_ERROR_PARTIAL for a partial
+  PCRE_PARTIAL_SOFT      )   match if no full matches are found
+  PCRE_PARTIAL_HARD      Return PCRE_ERROR_PARTIAL for a partial match
+                           even if there is a full match as well
+  PCRE_DFA_SHORTEST      Return only the shortest match
+  PCRE_DFA_RESTART       Restart after a partial match
+
+There are restrictions on what may appear in a pattern when using this matching +function. Details are given in the +pcrematching +documentation. For details of partial matching, see the +pcrepartial +page. +

+

+A pcre[16|32]_extra structure contains the following fields: +

+  flags            Bits indicating which fields are set
+  study_data       Opaque data from pcre[16|32]_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
+  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, +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 +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre_exec.html b/tools/pcre/doc/html/pcre_exec.html new file mode 100644 index 00000000..e4ddf9a8 --- /dev/null +++ b/tools/pcre/doc/html/pcre_exec.html @@ -0,0 +1,110 @@ + + +pcre_exec specification + + +

pcre_exec 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_exec(const pcre *code, const pcre_extra *extra, +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); +

+

+int pcre32_exec(const pcre32 *code, const pcre32_extra *extra, +PCRE_SPTR32 subject, int length, int startoffset, +int options, int *ovector, int ovecsize); +

+
+DESCRIPTION +
+

+This function matches a compiled regular expression against a given subject +string, using a matching algorithm that is similar to Perl's. It returns +offsets to captured substrings. Its arguments are: +

+  code         Points to the compiled pattern
+  extra        Points to an associated pcre[16|32]_extra structure,
+                 or is NULL
+  subject      Points to the subject string
+  length       Length of the subject string, in bytes
+  startoffset  Offset in bytes in the subject at which to
+                 start matching
+  options      Option bits
+  ovector      Points to a vector of ints for result offsets
+  ovecsize     Number of elements in the vector (a multiple of 3)
+
+The options are: +
+  PCRE_ANCHORED          Match only at the first position
+  PCRE_BSR_ANYCRLF       \R matches only CR, LF, or CRLF
+  PCRE_BSR_UNICODE       \R matches all Unicode line endings
+  PCRE_NEWLINE_ANY       Recognize any Unicode newline sequence
+  PCRE_NEWLINE_ANYCRLF   Recognize CR, LF, & CRLF as newline sequences
+  PCRE_NEWLINE_CR        Recognize CR as the only newline sequence
+  PCRE_NEWLINE_CRLF      Recognize CRLF as the only newline sequence
+  PCRE_NEWLINE_LF        Recognize LF as the only newline sequence
+  PCRE_NOTBOL            Subject string is not the beginning of a line
+  PCRE_NOTEOL            Subject string is not the end of a line
+  PCRE_NOTEMPTY          An empty string is not a valid match
+  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_UTF32_CHECK    Do not check the subject for UTF-32
+                           validity (only relevant if PCRE_UTF32
+                           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)
+  PCRE_PARTIAL           ) Return PCRE_ERROR_PARTIAL for a partial
+  PCRE_PARTIAL_SOFT      )   match if no full matches are found
+  PCRE_PARTIAL_HARD      Return PCRE_ERROR_PARTIAL for a partial match
+                           if that is found before a full match
+
+For details of partial matching, see the +pcrepartial +page. A pcre_extra structure contains the following fields: +
+  flags            Bits indicating which fields are set
+  study_data       Opaque data from pcre[16|32]_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
+  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, +PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT. +

+

+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 --git a/tools/pcre/doc/html/pcre_free_study.html b/tools/pcre/doc/html/pcre_free_study.html new file mode 100644 index 00000000..7f9e10e8 --- /dev/null +++ b/tools/pcre/doc/html/pcre_free_study.html @@ -0,0 +1,46 @@ + + +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); +

+

+void pcre32_free_study(pcre32_extra *extra); +

+
+DESCRIPTION +
+

+This function is used to free the memory used for the data generated by a call +to pcre[16|32]_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 --git a/tools/pcre/doc/html/pcre_free_substring.html b/tools/pcre/doc/html/pcre_free_substring.html new file mode 100644 index 00000000..1fe66107 --- /dev/null +++ b/tools/pcre/doc/html/pcre_free_substring.html @@ -0,0 +1,46 @@ + + +pcre_free_substring specification + + +

pcre_free_substring 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_substring(const char *stringptr); +

+

+void pcre16_free_substring(PCRE_SPTR16 stringptr); +

+

+void pcre32_free_substring(PCRE_SPTR32 stringptr); +

+
+DESCRIPTION +
+

+This is a convenience function for freeing the store obtained by a previous +call to pcre[16|32]_get_substring() or pcre[16|32]_get_named_substring(). +Its only argument is a pointer to 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 --git a/tools/pcre/doc/html/pcre_free_substring_list.html b/tools/pcre/doc/html/pcre_free_substring_list.html new file mode 100644 index 00000000..c0861780 --- /dev/null +++ b/tools/pcre/doc/html/pcre_free_substring_list.html @@ -0,0 +1,46 @@ + + +pcre_free_substring_list specification + + +

pcre_free_substring_list 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_substring_list(const char **stringptr); +

+

+void pcre16_free_substring_list(PCRE_SPTR16 *stringptr); +

+

+void pcre32_free_substring_list(PCRE_SPTR32 *stringptr); +

+
+DESCRIPTION +
+

+This is a convenience function for freeing the store obtained by a previous +call to pcre[16|32]_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 +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre_fullinfo.html b/tools/pcre/doc/html/pcre_fullinfo.html new file mode 100644 index 00000000..d353432b --- /dev/null +++ b/tools/pcre/doc/html/pcre_fullinfo.html @@ -0,0 +1,108 @@ + + +pcre_fullinfo specification + + +

pcre_fullinfo 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_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); +

+

+int pcre32_fullinfo(const pcre32 *code, const pcre32_extra *extra, +int what, void *where); +

+
+DESCRIPTION +
+

+This function returns information about a compiled pattern. Its arguments are: +

+  code                      Compiled regular expression
+  extra                     Result of pcre[16|32]_study() or NULL
+  what                      What information is required
+  where                     Where to put the information
+
+The following information is available: +
+  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 data unit for a match, or
+                              -1 for start of string
+                                 or after newline, or
+                              -2 otherwise
+  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_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
+  PCRE_INFO_NAMETABLE       Pointer to name table
+  PCRE_INFO_OKPARTIAL       Return 1 if partial matching can be tried
+                              (always returns 1 after release 8.00)
+  PCRE_INFO_OPTIONS         Option bits used for compilation
+  PCRE_INFO_SIZE            Size of compiled pattern
+  PCRE_INFO_STUDYSIZE       Size of study data
+  PCRE_INFO_FIRSTCHARACTER      Fixed first data unit for a match
+  PCRE_INFO_FIRSTCHARACTERFLAGS Returns
+                                  1 if there is a first data character set, which can
+                                    then be retrieved using PCRE_INFO_FIRSTCHARACTER,
+                                  2 if the first character is at the start of the data
+                                    string or after a newline, and
+                                  0 otherwise
+  PCRE_INFO_REQUIREDCHAR      Literal last data unit required
+  PCRE_INFO_REQUIREDCHARFLAGS Returns 1 if the last data character is set (which can then
+                              be retrieved using PCRE_INFO_REQUIREDCHAR); 0 otherwise
+
+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       PCRE_SPTR32           (32-bit library)
+  PCRE_INFO_NAMETABLE       const unsigned char * (8-bit library)
+  PCRE_INFO_OPTIONS         unsigned long int
+  PCRE_INFO_SIZE            size_t
+  PCRE_INFO_FIRSTCHARACTER  uint32_t
+  PCRE_INFO_REQUIREDCHAR    uint32_t
+
+The yield of the function is zero on success or: +
+  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
+
+

+

+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 --git a/tools/pcre/doc/html/pcre_get_named_substring.html b/tools/pcre/doc/html/pcre_get_named_substring.html new file mode 100644 index 00000000..6150ad71 --- /dev/null +++ b/tools/pcre/doc/html/pcre_get_named_substring.html @@ -0,0 +1,68 @@ + + +pcre_get_named_substring specification + + +

pcre_get_named_substring 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_get_named_substring(const pcre *code, +const char *subject, int *ovector, +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); +

+

+int pcre32_get_named_substring(const pcre32 *code, +PCRE_SPTR32 subject, int *ovector, +int stringcount, PCRE_SPTR32 stringname, +PCRE_SPTR32 *stringptr); +

+
+DESCRIPTION +
+

+This is a convenience function for extracting a captured substring by name. The +arguments are: +

+  code          Compiled pattern
+  subject       Subject that has been successfully matched
+  ovector       Offset vector that pcre[16|32]_exec() used
+  stringcount   Value returned by pcre[16|32]_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[16|32]_malloc(). The convenience function +pcre[16|32]_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 +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre_get_stringnumber.html b/tools/pcre/doc/html/pcre_get_stringnumber.html new file mode 100644 index 00000000..08967de3 --- /dev/null +++ b/tools/pcre/doc/html/pcre_get_stringnumber.html @@ -0,0 +1,57 @@ + + +pcre_get_stringnumber specification + + +

pcre_get_stringnumber 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_get_stringnumber(const pcre *code, +const char *name); +

+

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

+

+int pcre32_get_stringnumber(const pcre32 *code, +PCRE_SPTR32 name); +

+
+DESCRIPTION +
+

+This convenience function finds the number of a named substring capturing +parenthesis in a compiled pattern. Its arguments are: +

+  code    Compiled regular expression
+  name    Name whose number is required
+
+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[16|32]_get_stringnumber(). You can obtain the complete list by calling +pcre[16|32]_get_stringtable_entries(). +

+

+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 --git a/tools/pcre/doc/html/pcre_get_stringtable_entries.html b/tools/pcre/doc/html/pcre_get_stringtable_entries.html new file mode 100644 index 00000000..38f9c0c9 --- /dev/null +++ b/tools/pcre/doc/html/pcre_get_stringtable_entries.html @@ -0,0 +1,60 @@ + + +pcre_get_stringtable_entries specification + + +

pcre_get_stringtable_entries 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_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); +

+

+int pcre32_get_stringtable_entries(const pcre32 *code, +PCRE_SPTR32 name, PCRE_UCHAR32 **first, PCRE_UCHAR32 **last); +

+
+DESCRIPTION +
+

+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[16|32]_get_stringnumber() +instead. +

+  code    Compiled regular expression
+  name    Name whose entries required
+  first   Where to return a pointer to the first entry
+  last    Where to return a pointer to the last entry
+
+The yield of the function is the length of each entry, or +PCRE_ERROR_NOSUBSTRING if none are found. +

+

+There is a complete description of the PCRE native API, including the format of +the table entries, in the +pcreapi +page, and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre_get_substring.html b/tools/pcre/doc/html/pcre_get_substring.html new file mode 100644 index 00000000..2a5a610f --- /dev/null +++ b/tools/pcre/doc/html/pcre_get_substring.html @@ -0,0 +1,64 @@ + + +pcre_get_substring specification + + +

pcre_get_substring 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_get_substring(const char *subject, int *ovector, +int stringcount, int stringnumber, +const char **stringptr); +

+

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

+

+int pcre32_get_substring(PCRE_SPTR32 subject, int *ovector, +int stringcount, int stringnumber, +PCRE_SPTR32 *stringptr); +

+
+DESCRIPTION +
+

+This is a convenience function for extracting a captured substring. The +arguments are: +

+  subject       Subject that has been successfully matched
+  ovector       Offset vector that pcre[16|32]_exec() used
+  stringcount   Value returned by pcre[16|32]_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[16|32]_malloc(). The convenience function +pcre[16|32]_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 +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre_get_substring_list.html b/tools/pcre/doc/html/pcre_get_substring_list.html new file mode 100644 index 00000000..85edef4b --- /dev/null +++ b/tools/pcre/doc/html/pcre_get_substring_list.html @@ -0,0 +1,61 @@ + + +pcre_get_substring_list specification + + +

pcre_get_substring_list 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_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); +

+

+int pcre32_get_substring_list(PCRE_SPTR32 subject, +int *ovector, int stringcount, PCRE_SPTR32 **listptr); +

+
+DESCRIPTION +
+

+This is a convenience function for extracting a list of all the captured +substrings. The arguments are: +

+  subject       Subject that has been successfully matched
+  ovector       Offset vector that pcre[16|32]_exec used
+  stringcount   Value returned by pcre[16|32]_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[16|32]_malloc(). The convenience function +pcre[16|32]_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 +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre_jit_exec.html b/tools/pcre/doc/html/pcre_jit_exec.html new file mode 100644 index 00000000..0c63503a --- /dev/null +++ b/tools/pcre/doc/html/pcre_jit_exec.html @@ -0,0 +1,108 @@ + + +pcre_jit_exec specification + + +

pcre_jit_exec 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_jit_exec(const pcre *code, const pcre_extra *extra, +const char *subject, int length, int startoffset, +int options, int *ovector, int ovecsize, +pcre_jit_stack *jstack); +

+

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

+

+int pcre32_jit_exec(const pcre32 *code, const pcre32_extra *extra, +PCRE_SPTR32 subject, int length, int startoffset, +int options, int *ovector, int ovecsize, +pcre_jit_stack *jstack); +

+
+DESCRIPTION +
+

+This function matches a compiled regular expression that has been successfully +studied with one of the JIT options against a given subject string, using a +matching algorithm that is similar to Perl's. It is a "fast path" interface to +JIT, and it bypasses some of the sanity checks that pcre_exec() applies. +It returns offsets to captured substrings. Its arguments are: +

+  code         Points to the compiled pattern
+  extra        Points to an associated pcre[16|32]_extra structure,
+                 or is NULL
+  subject      Points to the subject string
+  length       Length of the subject string, in bytes
+  startoffset  Offset in bytes in the subject at which to
+                 start matching
+  options      Option bits
+  ovector      Points to a vector of ints for result offsets
+  ovecsize     Number of elements in the vector (a multiple of 3)
+  jstack       Pointer to a JIT stack
+
+The allowed options are: +
+  PCRE_NOTBOL            Subject string is not the beginning of a line
+  PCRE_NOTEOL            Subject string is not the end of a line
+  PCRE_NOTEMPTY          An empty string is not a valid match
+  PCRE_NOTEMPTY_ATSTART  An empty string at the start of the subject
+                           is not a valid match
+  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_UTF32_CHECK    Do not check the subject for UTF-32
+                           validity (only relevant if PCRE_UTF32
+                           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)
+  PCRE_PARTIAL           ) Return PCRE_ERROR_PARTIAL for a partial
+  PCRE_PARTIAL_SOFT      )   match if no full matches are found
+  PCRE_PARTIAL_HARD      Return PCRE_ERROR_PARTIAL for a partial match
+                           if that is found before a full match
+
+However, the PCRE_NO_UTF[8|16|32]_CHECK options have no effect, as this check +is never applied. For details of partial matching, see the +pcrepartial +page. A pcre_extra structure contains the following fields: +
+  flags            Bits indicating which fields are set
+  study_data       Opaque data from pcre[16|32]_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
+  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, +PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT. +

+

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

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre_jit_stack_alloc.html b/tools/pcre/doc/html/pcre_jit_stack_alloc.html new file mode 100644 index 00000000..4153ee59 --- /dev/null +++ b/tools/pcre/doc/html/pcre_jit_stack_alloc.html @@ -0,0 +1,55 @@ + + +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); +

+

+pcre32_jit_stack *pcre32_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|32]_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|32]_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 --git a/tools/pcre/doc/html/pcre_jit_stack_free.html b/tools/pcre/doc/html/pcre_jit_stack_free.html new file mode 100644 index 00000000..8bd06e46 --- /dev/null +++ b/tools/pcre/doc/html/pcre_jit_stack_free.html @@ -0,0 +1,48 @@ + + +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); +

+

+void pcre32_jit_stack_free(pcre32_jit_stack *stack); +

+
+DESCRIPTION +
+

+This function is used to free a JIT stack that was created by +pcre[16|32]_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 --git a/tools/pcre/doc/html/pcre_maketables.html b/tools/pcre/doc/html/pcre_maketables.html new file mode 100644 index 00000000..3a7b5ebc --- /dev/null +++ b/tools/pcre/doc/html/pcre_maketables.html @@ -0,0 +1,48 @@ + + +pcre_maketables specification + + +

pcre_maketables 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> +

+

+const unsigned char *pcre_maketables(void); +

+

+const unsigned char *pcre16_maketables(void); +

+

+const unsigned char *pcre32_maketables(void); +

+
+DESCRIPTION +
+

+This function builds a set of character tables for character values less than +256. These can be passed to pcre[16|32]_compile() to override PCRE's +internal, built-in tables (which were made by pcre[16|32]_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 +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre_pattern_to_host_byte_order.html b/tools/pcre/doc/html/pcre_pattern_to_host_byte_order.html new file mode 100644 index 00000000..68d6f5a1 --- /dev/null +++ b/tools/pcre/doc/html/pcre_pattern_to_host_byte_order.html @@ -0,0 +1,58 @@ + + +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); +

+

+int pcre32_pattern_to_host_byte_order(pcre32 *code, +pcre32_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|32]_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 --git a/tools/pcre/doc/html/pcre_refcount.html b/tools/pcre/doc/html/pcre_refcount.html new file mode 100644 index 00000000..bfb92e6d --- /dev/null +++ b/tools/pcre/doc/html/pcre_refcount.html @@ -0,0 +1,51 @@ + + +pcre_refcount specification + + +

pcre_refcount 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_refcount(pcre *code, int adjust); +

+

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

+

+int pcre32_refcount(pcre32 *code, int adjust); +

+
+DESCRIPTION +
+

+This function is used to maintain a reference count inside a data block that +contains a compiled pattern. Its arguments are: +

+  code                      Compiled regular expression
+  adjust                    Adjustment to reference value
+
+The yield of the function is the adjusted reference value, which is constrained +to lie between 0 and 65535. +

+

+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 --git a/tools/pcre/doc/html/pcre_study.html b/tools/pcre/doc/html/pcre_study.html new file mode 100644 index 00000000..2baf54c4 --- /dev/null +++ b/tools/pcre/doc/html/pcre_study.html @@ -0,0 +1,68 @@ + + +pcre_study specification + + +

pcre_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> +

+

+pcre_extra *pcre_study(const pcre *code, int options, +const char **errptr); +

+

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

+

+pcre32_extra *pcre32_study(const pcre32 *code, int options, +const char **errptr); +

+
+DESCRIPTION +
+

+This function studies a compiled pattern, to see if additional information can +be extracted that might speed up matching. Its arguments are: +

+  code       A compiled regular expression
+  options    Options for pcre[16|32]_study()
+  errptr     Where to put an error message
+
+If the function succeeds, it returns a value that can be passed to +pcre[16|32]_exec() or pcre[16|32]_dfa_exec() via their extra +arguments. +

+

+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. +

+

+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 +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcre_utf16_to_host_byte_order.html b/tools/pcre/doc/html/pcre_utf16_to_host_byte_order.html new file mode 100644 index 00000000..164e2365 --- /dev/null +++ b/tools/pcre/doc/html/pcre_utf16_to_host_byte_order.html @@ -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 --git a/tools/pcre/doc/html/pcre_version.html b/tools/pcre/doc/html/pcre_version.html new file mode 100644 index 00000000..d33e7189 --- /dev/null +++ b/tools/pcre/doc/html/pcre_version.html @@ -0,0 +1,46 @@ + + +pcre_version specification + + +

pcre_version 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> +

+

+const char *pcre_version(void); +

+

+const char *pcre16_version(void); +

+

+const char *pcre32_version(void); +

+
+DESCRIPTION +
+

+This function (even in the 16-bit and 32-bit libraries) 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 +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcreapi.html b/tools/pcre/doc/html/pcreapi.html new file mode 100644 index 00000000..59398df3 --- /dev/null +++ b/tools/pcre/doc/html/pcreapi.html @@ -0,0 +1,2786 @@ + + +pcreapi specification + + +

pcreapi 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 NATIVE API BASIC FUNCTIONS
+

+pcre *pcre_compile(const char *pattern, int options, +const char **errptr, int *erroffset, +const unsigned char *tableptr); +

+

+pcre *pcre_compile2(const char *pattern, int options, +int *errorcodeptr, +const char **errptr, int *erroffset, +const unsigned char *tableptr); +

+

+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); +

+

+int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, +const char *subject, int length, int startoffset, +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, +char *buffer, int buffersize); +

+

+int pcre_copy_substring(const char *subject, int *ovector, +int stringcount, int stringnumber, char *buffer, +int buffersize); +

+

+int pcre_get_named_substring(const pcre *code, +const char *subject, int *ovector, +int stringcount, const char *stringname, +const char **stringptr); +

+

+int pcre_get_stringnumber(const pcre *code, +const char *name); +

+

+int pcre_get_stringtable_entries(const pcre *code, +const char *name, char **first, char **last); +

+

+int pcre_get_substring(const char *subject, int *ovector, +int stringcount, int stringnumber, +const char **stringptr); +

+

+int pcre_get_substring_list(const char *subject, +int *ovector, int stringcount, const char ***listptr); +

+

+void pcre_free_substring(const char *stringptr); +

+

+void pcre_free_substring_list(const char **stringptr); +

+
PCRE NATIVE API AUXILIARY FUNCTIONS
+

+int pcre_jit_exec(const pcre *code, const pcre_extra *extra, +const char *subject, int length, int startoffset, +int options, int *ovector, int ovecsize, +pcre_jit_stack *jstack); +

+

+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_refcount(pcre *code, int adjust); +

+

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

+

+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); +

+

+void (*pcre_free)(void *); +

+

+void *(*pcre_stack_malloc)(size_t); +

+

+void (*pcre_stack_free)(void *); +

+

+int (*pcre_callout)(pcre_callout_block *); +

+
PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES
+

+As well as support for 8-bit character strings, PCRE also supports 16-bit +strings (from release 8.30) and 32-bit strings (from release 8.32), by means of +two additional libraries. They can be built as well as, or instead of, the +8-bit library. To avoid too much complication, this document describes the +8-bit versions of the functions, with only occasional references to the 16-bit +and 32-bit libraries. +

+

+The 16-bit and 32-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_ or pcre32_ instead of +pcre_. For every option that has UTF8 in its name (for example, +PCRE_UTF8), there are corresponding 16-bit and 32-bit names with UTF8 replaced +by UTF16 or UTF32, respectively. This facility is in fact just cosmetic; the +16-bit and 32-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, or 32-bit data +quantities and UTF-32 when using the 32-bit library, unless specified +otherwise. More details of the specific differences for the 16-bit and 32-bit +libraries are given in the +pcre16 +and +pcre32 +pages. +

+
PCRE API OVERVIEW
+

+PCRE has its own native API, which is described in this document. There are +also some wrapper functions (for the 8-bit library only) that 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 (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_malloc() 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 simplest +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 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. +

+

+From release 8.32 there is also a direct interface for JIT execution, which +gives improved performance. The JIT-specific 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 +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 +documentation. +

+

+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: +

+  pcre_copy_substring()
+  pcre_copy_named_substring()
+  pcre_get_substring()
+  pcre_get_named_substring()
+  pcre_get_substring_list()
+  pcre_get_stringnumber()
+  pcre_get_stringtable_entries()
+
+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 built are used. +

+

+The function pcre_fullinfo() is used to find out information about a +compiled pattern. The function pcre_version() returns a pointer to a +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 of +object-oriented applications. +

+

+The global variables pcre_malloc and pcre_free initially contain +the entry points of the standard malloc() and free() functions, +respectively. PCRE calls the memory management functions via these variables, +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 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 environments 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 +documentation. +

+

+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 +pcrecallout +documentation. +

+
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 (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 standard. 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 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 character 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 advancement 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, which is +controlled in a similar way, but by separate options. +

+
MULTITHREADING
+

+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 matching, so +the same compiled pattern can safely be used by several threads at once. +

+

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

+
SAVING PRECOMPILED PATTERNS FOR LATER USE
+

+The compiled form of a regular expression can be saved and re-used at a later +time, possibly by a different program, and even on a host other than the one on +which it was compiled. Details are given in the +pcreprecompile +documentation, which includes a description of the +pcre_pattern_to_host_byte_order() function. However, compiling a 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
+

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

+

+The function pcre_config() makes it possible for a PCRE client to +discover which optional features have been compiled into the PCRE library. The +pcrebuild +documentation has more details about these optional features. +

+

+The first argument for pcre_config() is an integer, specifying which +information is required; the second argument is a pointer to a variable into +which the information is placed. The returned value is zero on success, or the +negative error code PCRE_ERROR_BADOPTION if the value in the first argument is +not recognized. The following information is 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. This value should normally be given to the 8-bit +version of this function, pcre_config(). If it is given to the 16-bit +or 32-bit version of this function, the result is 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 +or 32-bit version of this function, the result is PCRE_ERROR_BADOPTION. +
+  PCRE_CONFIG_UTF32
+
+The output is an integer that is set to one if UTF-32 support is available; +otherwise it is set to zero. This value should normally be given to the 32-bit +version of this function, pcre32_config(). If it is given to the 8-bit +or 16-bit version of this function, the result is 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 +that is recognized as meaning "newline". The values that are supported in +ASCII/Unicode environments are: 10 for LF, 13 for CR, 3338 for CRLF, -2 for +ANYCRLF, and -1 for ANY. In EBCDIC environments, CR, ANYCRLF, and ANY yield the +same values. However, the value for LF is normally 21, though some EBCDIC +environments use 37. The corresponding values for CRLF are 3349 and 3365. The +default should normally correspond 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 matches only CR, LF, +or CRLF. The default can be overridden when a pattern 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. For the 8-bit library, the value can +be 2, 3, or 4. For the 16-bit library, the value is either 2 or 4 and is still +a number of bytes. For the 32-bit 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 given in +the +pcreposix +documentation. +
+  PCRE_CONFIG_MATCH_LIMIT
+
+The output is a long integer that gives the default limit for the number 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() below. +
+  PCRE_CONFIG_STACKRECURSE
+
+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 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 blocks on the heap, thus +avoiding the use of the stack. +

+
COMPILING A PATTERN
+

+pcre *pcre_compile(const char *pattern, int options, +const char **errptr, int *erroffset, +const unsigned char *tableptr); +pcre *pcre_compile2(const char *pattern, int options, +int *errorcodeptr, +const char **errptr, int *erroffset, +const unsigned char *tableptr); +

+

+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 +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 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 does not +depend on memory location, the complete pcre data block is not +fully relocatable, because it may contain a copy of the tableptr +argument, which is an address (see below). +

+

+The options argument contains various bit settings that affect the +compilation. 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_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 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. 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 sometimes point +into the middle of a UTF-8 character. +

+

+If pcre_compile2() is used instead of pcre_compile(), and the +errorcodeptr 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 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_compile(): +

+  pcre *re;
+  const char *error;
+  int erroffset;
+  re = pcre_compile(
+    "^A.*Z",          /* the pattern */
+    0,                /* default options */
+    &error,           /* for error message */
+    &erroffset,       /* for error offset */
+    NULL);            /* use default character tables */
+
+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 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 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, 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 setting 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 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. +
+  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 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 character 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 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 such as [^a] always matches newline +characters, independent of the setting of this option. +
+  PCRE_DUPNAMES
+
+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 the +pcrepattern +documentation. +
+  PCRE_EXTENDED
+
+If this bit is set, white space data characters in the pattern are totally +ignored except when escaped or inside a character class. White space does not +include the VT character (code 11). In addition, 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 +"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 +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. White space characters +may never appear within special character sequences in a pattern, for example +within the sequence (?( that introduces 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 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 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 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 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 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 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
+
+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 changed within a pattern by a +(?m) option setting. If there are no newlines in a subject string, or no +occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no effect. +

+  PCRE_NEWLINE_CR
+  PCRE_NEWLINE_LF
+  PCRE_NEWLINE_CRLF
+  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 that any of the three +preceding sequences should be recognized. Setting PCRE_NEWLINE_ANY specifies +that any Unicode newline sequence should be recognized. +

+

+In an ASCII/Unicode environment, 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). For the 8-bit library, the last two are +recognized only in UTF-8 mode. +

+

+When PCRE is compiled to run in an EBCDIC (mainframe) environment, the code for +CR is 0x0d, the same as ASCII. However, the character code for LF is normally +0x15, though in some EBCDIC environments 0x25 is used. Whichever of these is +not LF is made to correspond to Unicode's NEL character. EBCDIC codes are all +less than 256. For more details, see the +pcrebuild +documentation. +

+

+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 sensible. For example, +PCRE_NEWLINE_CR with PCRE_NEWLINE_LF is equivalent to 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 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 +data. +

+

+The newline option that is set at compile time becomes the default that is used +for pcre_exec() and pcre_dfa_exec(), but it can be overridden. +

+  PCRE_NO_AUTO_CAPTURE
+
+If this option is set, it disables the use of numbered capturing parentheses 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 matching 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 +property 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 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 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 +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 only. If the same string is being matched +many times, the option can be safely set for the second and subsequent +matchings to improve performance. +

+
COMPILATION ERROR CODES
+

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

+   0  no error
+   1  \ at end of pattern
+   2  \c at end of pattern
+   3  unrecognized character follows \
+   4  numbers out of order in {} quantifier
+   5  number too big in {} quantifier
+   6  missing terminating ] for character class
+   7  invalid escape sequence in character class
+   8  range out of order in character class
+   9  nothing to repeat
+  10  [this code is not in use]
+  11  internal error: unexpected repeat
+  12  unrecognized character after (? or (?-
+  13  POSIX named classes are supported only within a class
+  14  missing )
+  15  reference to non-existent subpattern
+  16  erroffset passed as NULL
+  17  unknown option bit(s) set
+  18  missing ) after comment
+  19  [this code is not in use]
+  20  regular expression is too large
+  21  failed to get memory
+  22  unmatched parentheses
+  23  internal error: code overflow
+  24  unrecognized character after (?<
+  25  lookbehind assertion is not fixed length
+  26  malformed number or name after (?(
+  27  conditional group contains more than two branches
+  28  assertion expected after (?(
+  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 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{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 (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 in 8-bit non-UTF-8 mode
+  52  internal error: overran compiling workspace
+  53  internal error: previously-checked referenced subpattern
+        not found
+  54  DEFINE group contains more than one branch
+  55  repeating a DEFINE group is not allowed
+  56  inconsistent NEWLINE options
+  57  \g is not followed by a braced, angle-bracketed, or quoted
+        name/number or by a plain number
+  58  a numbered reference must not be zero
+  59  an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)
+  60  (*VERB) not recognized
+  61  number is too big
+  62  subpattern name expected
+  63  digit expected after (?+
+  64  ] is an invalid data character in JavaScript compatibility mode
+  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 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
+  77  invalid UTF-32 string (specifically UTF-32)
+
+The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may +be used if the limits were changed when PCRE was built. +

+
STUDYING A PATTERN
+

+pcre_extra *pcre_study(const pcre *code, int options +const char **errptr); +

+

+If a compiled pattern is going to be used several times, it is worth spending +more time analyzing it in order to speed up the time taken for matching. The +function pcre_study() takes a pointer to a compiled pattern as its first +argument. If studying the pattern produces additional information that will +help speed up matching, pcre_study() returns a pointer to a +pcre_extra block, in which the study_data field points to the +results of the study. +

+

+The returned value from pcre_study() can be passed directly to +pcre_exec() or pcre_dfa_exec(). However, a pcre_extra block +also contains other fields that can be set by the caller before the block is +passed; these are described +below +in the section on matching a pattern. +

+

+If studying the pattern does not produce any useful information, +pcre_study() returns NULL by default. In that circumstance, if the +calling program wants to pass any of the other fields to pcre_exec() or +pcre_dfa_exec(), it must set up its own pcre_extra block. However, +if pcre_study() is called with the PCRE_STUDY_EXTRA_NEEDED option, it +returns a pcre_extra block even if studying did not find any additional +information. It may still return NULL, however, if an error occurs in +pcre_study(). +

+

+The second argument of pcre_study() contains option bits. There are three +further options in addition to PCRE_STUDY_EXTRA_NEEDED: +

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

+

+JIT compilation is a heavyweight optimization. It can take some time for +patterns to be analyzed, and for one-off matches and simple 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 +studying succeeds (even if no data is returned), the variable it points to is +set to NULL. Otherwise it is set to point to a textual error message. This is a +static string that is part of the library. You must not try to free it. You +should test the error pointer for NULL after calling pcre_study(), to be +sure that it has run successfully. +

+

+When you are finished with a pattern, you can free the memory used for 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): +

+  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 */
+    &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 +mean that there are any strings of that length that match, but it does +guarantee that no shorter strings match. The value is used to avoid wasting +time by trying to match strings that are shorter than the lower bound. You can +find out the value in a calling program via the pcre_fullinfo() function. +

+

+Studying a pattern is also useful for non-anchored patterns that do not have a +single fixed starting character. A bitmap of possible starting bytes is +created. This speeds up finding a position in the subject at which to start +matching. (In 16-bit mode, the bitmap is used for 16-bit values less than 256. +In 32-bit mode, the bitmap is used for 32-bit values less than 256.) +

+

+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
+

+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. +

+

+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 characters. However, when +PCRE is built, it is possible to cause the internal 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 +application that calls PCRE. These may be created in a different locale from +the default. As more and more applications change to using Unicode, 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 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; 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 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() +and normally also by pcre_exec(). Thus, by default, for any single +pattern, 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 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
+

+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 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_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 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() */
+    sd,               /* result of pcre_study(), or NULL */
+    PCRE_INFO_SIZE,   /* what is required */
+    &length);         /* where to put the data */
+
+The possible values for the third argument are defined in pcre.h, and are +as follows: +
+  PCRE_INFO_BACKREFMAX
+
+Return the number of the highest back reference in the pattern. The fourth +argument should point to an int variable. Zero is returned if there are +no back references. +
+  PCRE_INFO_CAPTURECOUNT
+
+Return the number of capturing subpatterns in the pattern. The fourth argument +should point to an int variable. +
+  PCRE_INFO_DEFAULT_TABLES
+
+Return a pointer to the internal default character tables within PCRE. The +fourth argument should point to an unsigned char * variable. This +information call is provided for internal use by the pcre_study() +function. External callers can cause PCRE to use its internal tables by passing +a NULL table pointer. +
+  PCRE_INFO_FIRSTBYTE
+
+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. In the 32-bit library the value can be up to 0x10ffff. +

+

+If there is no fixed first value, and if either +
+
+(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch +starts with "^", or +
+
+(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set +(if it were set, the pattern would be anchored), +
+
+-1 is returned, indicating that the pattern matches only at the start of a +subject string or after any newline within the string. Otherwise -2 is +returned. For anchored patterns, -2 is returned. +

+

+Since for the 32-bit library using the non-UTF-32 mode, this function is unable +to return the full 32-bit range of the character, this value is deprecated; +instead the PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER values +should be used. +

+  PCRE_INFO_FIRSTTABLE
+
+If the pattern was studied, and this resulted in the construction of a 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
+
+Return 1 if the pattern contains any explicit matches for CR or LF characters, +otherwise 0. The fourth argument should point to an int variable. An +explicit match is either a literal CR or LF character, or \r or \n. +
+  PCRE_INFO_JCHANGED
+
+Return 1 if the (?J) or (?-J) option setting is used in the pattern, otherwise +0. The fourth argument should point to an int variable. (?J) and +(?-J) set and unset the local PCRE_DUPNAMES option, respectively. +
+  PCRE_INFO_JIT
+
+Return 1 if the pattern was studied with one of the JIT options, and +just-in-time compiling was successful. The fourth argument should point to an +int variable. A return value of 0 means that JIT support is not available +in this version of PCRE, or that the pattern was not studied with a JIT option, +or that the JIT compiler could not handle this 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 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. +

+

+Since for the 32-bit library using the non-UTF-32 mode, this function is unable +to return the full 32-bit range of the character, this value is deprecated; +instead the PCRE_INFO_REQUIREDCHARFLAGS and PCRE_INFO_REQUIREDCHAR values should +be used. +

+  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, 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
+  PCRE_INFO_NAMETABLE
+
+PCRE supports the use of named as well as numbered capturing parentheses. The +names are just an additional way of identifying the parentheses, which still +acquire numbers. Several convenience functions such as +pcre_get_named_substring() are provided for extracting captured +substrings by name. It is also possible to extract the data directly, by first +converting the name to a number in order to access the correct pointers in the +output vector (described with pcre_exec() below). To do the conversion, +you need to use the name-to-number map, which is described by these three +values. +

+

+The map consists of a number of fixed-size entries. PCRE_INFO_NAMECOUNT 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. 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. +In the 32-bit library, the pointer points to 32-bit data units, the first of +which contains the parenthesis number. The rest +of the entry is the corresponding name, zero terminated. +

+

+The names are in alphabetical order. Duplicate names may appear if (?| is used +to create multiple groups with the same number, as described in the +section on duplicate subpattern numbers +in the +pcrepattern +page. Duplicate names for subpatterns with different numbers are permitted only +if PCRE_DUPNAMES is set. In all cases of duplicate names, they appear in the +table in the order in which they were found in the pattern. In the absence of +(?| this is the order of increasing number; when (?| is used this is not +necessarily the case because later subpatterns may have lower numbers. +

+

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

+  (?<date> (?<year>(\d\d)?\d\d) - (?<month>\d\d) - (?<day>\d\d) )
+
+There are four named subpatterns, so the table has four entries, and each entry +in the table is eight bytes long. The table is as follows, with non-printing +bytes shows in hexadecimal, and undefined bytes shown as ??: +
+  00 01 d  a  t  e  00 ??
+  00 05 d  a  y  00 ?? ??
+  00 04 m  o  n  t  h  00
+  00 02 y  e  a  r  00 ??
+
+When writing code to extract data from named subpatterns using the +name-to-number map, remember that the length of the entries is likely to be +different for each compiled pattern. +
+  PCRE_INFO_OKPARTIAL
+
+Return 1 if the pattern can be used for partial matching with +pcre_exec(), otherwise 0. The fourth argument should point to an +int variable. From release 8.00, this always returns 1, because the +restrictions that previously applied to partial matching have been lifted. The +pcrepartial +documentation gives details of partial matching. +
+  PCRE_INFO_OPTIONS
+
+Return a copy of the options with which the pattern was compiled. The fourth +argument should point to an unsigned long int variable. These option bits +are those specified in the call to pcre_compile(), modified by any +top-level option settings at the start of the pattern itself. In other words, +they are the options that will be in force when matching starts. For example, +if the pattern /(?im)abc(?-i)d/ is compiled with the PCRE_EXTENDED option, the +result is PCRE_CASELESS, PCRE_MULTILINE, and PCRE_EXTENDED. +

+

+A pattern is automatically anchored by PCRE if all of its top-level +alternatives begin with one of the following: +

+  ^     unless PCRE_MULTILINE is set
+  \A    always
+  \G    always
+  .*    if PCRE_DOTALL is set and there are no back references to the subpattern in which .* appears
+
+For such patterns, the PCRE_ANCHORED bit is set in the options returned by +pcre_fullinfo(). +
+  PCRE_INFO_SIZE
+
+Return the size of the compiled pattern in bytes (for both libraries). The +fourth argument should point to a size_t variable. This value does not +include the size of the pcre structure that is returned by +pcre_compile(). The value that is passed as the argument to +pcre_malloc() when pcre_compile() is getting memory in which to +place the compiled data is the value returned by this option plus the size of +the pcre structure. Studying a compiled pattern, with or without JIT, +does not alter the value returned by this option. +
+  PCRE_INFO_STUDYSIZE
+
+Return the size in bytes of the data block pointed to by the study_data +field in a pcre_extra block. If pcre_extra is NULL, or there is no +study data, zero is returned. The fourth argument should point to a +size_t variable. The study_data field is set by pcre_study() +to record information that will speed up matching (see the section entitled +"Studying a pattern" +above). The format of the study_data block is private, but its length +is made available via this option so that it can be saved and restored (see the +pcreprecompile +documentation for details). +
+  PCRE_INFO_FIRSTCHARACTERFLAGS
+
+Return information about the first data unit of any matched string, for a +non-anchored pattern. The fourth argument should point to an int +variable. +

+

+If there is a fixed first value, for example, the letter "c" from a pattern +such as (cat|cow|coyote), 1 is returned, and the character value can be +retrieved using PCRE_INFO_FIRSTCHARACTER. +

+

+If there is no fixed first value, and if either +
+
+(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch +starts with "^", or +
+
+(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set +(if it were set, the pattern would be anchored), +
+
+2 is returned, indicating that the pattern matches only at the start of a +subject string or after any newline within the string. Otherwise 0 is +returned. For anchored patterns, 0 is returned. +

+  PCRE_INFO_FIRSTCHARACTER
+
+Return the fixed first character value, if PCRE_INFO_FIRSTCHARACTERFLAGS +returned 1; otherwise returns 0. The fourth argument should point to an +uint_t variable. +

+

+In the 8-bit library, the value is always less than 256. In the 16-bit library +the value can be up to 0xffff. In the 32-bit library in UTF-32 mode the value +can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode. +

+

+If there is no fixed first value, and if either +
+
+(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch +starts with "^", or +
+
+(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set +(if it were set, the pattern would be anchored), +
+
+-1 is returned, indicating that the pattern matches only at the start of a +subject string or after any newline within the string. Otherwise -2 is +returned. For anchored patterns, -2 is returned. +

+  PCRE_INFO_REQUIREDCHARFLAGS
+
+Returns 1 if there is a rightmost literal data unit that must exist in any +matched string, other than at its start. The fourth argument should point to +an int variable. If there is no such value, 0 is returned. If returning +1, the character value itself can be retrieved using PCRE_INFO_REQUIREDCHAR. +

+

+For anchored patterns, a last literal value is recorded only if it follows +something of variable length. For example, for the pattern /^a\d+z\d+/ the +returned value 1 (with "z" returned from PCRE_INFO_REQUIREDCHAR), but for +/^a\dz\d/ the returned value is 0. +

+  PCRE_INFO_REQUIREDCHAR
+
+Return the value of the rightmost literal data unit that must exist in any +matched string, other than at its start, if such a value has been recorded. The +fourth argument should point to an uint32_t variable. If there is no such +value, 0 is returned. +

+
REFERENCE COUNTS
+

+int pcre_refcount(pcre *code, int adjust); +

+

+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, 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 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 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 whose byte-order +is different. (This seems a highly unlikely scenario.) +

+
MATCHING A PATTERN: THE TRADITIONAL FUNCTION
+

+int pcre_exec(const pcre *code, const pcre_extra *extra, +const char *subject, int length, int startoffset, +int options, int *ovector, int ovecsize); +

+

+The function pcre_exec() is called to match a subject string against a +compiled pattern, which is passed in the code argument. If the +pattern was studied, the result of the study should be passed in the +extra argument. You can call pcre_exec() with the same code +and extra 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. +

+

+In most applications, the pattern will have been compiled (and optionally +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 discussion +about this, see the +pcreprecompile +documentation. +

+

+Here is an example of a simple call to pcre_exec(): +

+  int rc;
+  int ovector[30];
+  rc = pcre_exec(
+    re,             /* result of pcre_compile() */
+    NULL,           /* we didn't study the pattern */
+    "some string",  /* the subject string */
+    11,             /* the length of the subject string */
+    0,              /* start at offset 0 in the subject */
+    0,              /* default options */
+    ovector,        /* vector of integers for substring information */
+    30);            /* number of elements (NOT size in bytes) */
+
+

+
+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 +additional 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;
+
+In the 16-bit version of this structure, the mark field has type +"PCRE_UCHAR16 **". +
+
+In the 32-bit version of this structure, the mark field has type +"PCRE_UCHAR32 **". +

+

+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_STUDY_DATA
+  PCRE_EXTRA_TABLES
+
+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 +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. +

+

+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 +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 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 recursive. +This limit is of use only if it is set smaller than match_limit. +

+

+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" feature, +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 argument. +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 +documentation for a discussion of saving compiled patterns for later use. +

+

+If PCRE_EXTRA_MARK is set in the flags field, the mark field must +be set to point to a suitable variable. If the pattern contains any +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 is set to NULL. For details of the +backtracking control verbs, see the section entitled +"Backtracking control" +in the +pcrepattern +documentation. +

+
+Option bits for pcre_exec() +
+

+The unused bits of the options argument for pcre_exec() must be +zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx, +PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, +PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and +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
+
+The PCRE_ANCHORED option limits pcre_exec() to matching at the first +matching position. If a pattern was compiled with PCRE_ANCHORED, or turned out +to be anchored by virtue of its contents, it cannot be made unachored at +matching time. +
+  PCRE_BSR_ANYCRLF
+  PCRE_BSR_UNICODE
+
+These options (which are mutually exclusive) control what the \R escape +sequence matches. The choice is either to match only CR, LF, or CRLF, or to +match any Unicode newline sequence. These options override the choice that was +made or defaulted when the pattern was compiled. +
+  PCRE_NEWLINE_CR
+  PCRE_NEWLINE_LF
+  PCRE_NEWLINE_CRLF
+  PCRE_NEWLINE_ANYCRLF
+  PCRE_NEWLINE_ANY
+
+These options override the newline definition that was chosen or defaulted when +the pattern was compiled. For details, see the description of +pcre_compile() above. During matching, the newline choice affects the +behaviour of the dot, circumflex, and dollar metacharacters. It may also alter +the way the match position is advanced after a match failure for an unanchored +pattern. +

+

+When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is set, and a +match attempt for an unanchored pattern fails when the current position is at a +CRLF sequence, and the pattern contains no explicit matches for CR or LF +characters, the match position is advanced by two characters instead of one, in +other words, to after the CRLF. +

+

+The above rule is a compromise that makes the most common cases work as +expected. For example, if the pattern is .+A (and the PCRE_DOTALL option is not +set), it does not match the string "\r\nA" because, after failing at the +start, it skips both the CR and the LF before retrying. However, the pattern +[\r\n]A does match that string, because it contains an explicit CR or LF +reference, and so advances only by one character after the first failure. +

+

+An explicit match for CR of LF is either a literal appearance of one of those +characters, or one of the \r or \n escape sequences. Implicit matches such as +[^X] do not count, nor does \s (which includes CR and LF in the characters +that it matches). +

+

+Notwithstanding the above, anomalous effects may still occur when CRLF is a +valid newline sequence and explicit \r or \n escapes appear in the pattern. +

+  PCRE_NOTBOL
+
+This option specifies that first character of the subject string is not the +beginning of a line, so the circumflex metacharacter should not match before +it. Setting this without PCRE_MULTILINE (at compile time) causes circumflex +never to match. This option affects only the behaviour of the circumflex +metacharacter. It does not affect \A. +
+  PCRE_NOTEOL
+
+This option specifies that the end of the subject string is not the end of a +line, so the dollar metacharacter should not match it nor (except in multiline +mode) a newline immediately before it. Setting this without PCRE_MULTILINE (at +compile time) causes dollar never to match. This option affects only the +behaviour of the dollar metacharacter. It does not affect \Z or \z. +
+  PCRE_NOTEMPTY
+
+An empty string is not considered to be a valid match if this option is set. If +there are alternatives in the pattern, they are tried. If all the alternatives +match the empty string, the entire match fails. For example, if the pattern +
+  a?b?
+
+is applied to a string not beginning with "a" or "b", it matches an empty +string at the start of the subject. With PCRE_NOTEMPTY set, this match is not +valid, so PCRE searches further into the string for occurrences of "a" or "b". +
+  PCRE_NOTEMPTY_ATSTART
+
+This is like PCRE_NOTEMPTY, except that an empty string match that is not at +the start of the subject is permitted. If the pattern is anchored, such a match +can occur only if the pattern contains \K. +

+

+Perl has no direct equivalent of PCRE_NOTEMPTY or PCRE_NOTEMPTY_ATSTART, but it +does make a special case of a pattern match of the empty string within its +split() function, and when using the /g modifier. It is possible to +emulate Perl's behaviour after matching a null string by first trying the match +again at the same offset with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then +if that fails, by advancing the starting offset (see below) and trying an +ordinary match again. There is some code that demonstrates how to do this in +the +pcredemo +sample program. In the most general case, you have to check to see if the +newline convention recognizes CRLF as a newline, and if so, and the current +character is CR followed by LF, advance the starting offset by two characters +instead of one. +

+  PCRE_NO_START_OPTIMIZE
+
+There are a number of optimizations that pcre_exec() uses at the start of +a match, in order to speed up the process. For example, if it is known that an +unanchored match must start with a specific character, it searches the subject +for that character, and fails immediately if it cannot find it, without +actually running the main matching function. This means that a special item +such as (*COMMIT) at the start of a pattern is not considered until after a +suitable starting point for the match has been found. When callouts or (*MARK) +items are in use, these "start-up" optimizations can cause them to be skipped +if the pattern is never actually used. The start-up optimizations are in effect +a pre-scan of the subject that takes place before the pattern is run. +

+

+The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, possibly +causing performance to suffer, but ensuring that in cases where the result is +"no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) +are considered at every possible starting position in the subject string. If +PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching +time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, +matching is always done using interpretively. +

+

+Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. +Consider the pattern +

+  (*COMMIT)ABC
+
+When this is compiled, PCRE records the fact that a match must start with the +character "A". Suppose the subject string is "DEFABC". The start-up +optimization scans along the subject, finds "A" and runs the first match +attempt from there. The (*COMMIT) item means that the pattern must match the +current starting position, which in this case, it does. However, if the same +match is run with PCRE_NO_START_OPTIMIZE set, the initial scan along the +subject string does not happen. The first match attempt is run starting from +"D" and when this fails, (*COMMIT) prevents any further matches being tried, so +the overall result is "no match". If the pattern is studied, more start-up +optimizations may be used. For example, a minimum length for the subject may be +recorded. Consider the pattern +
+  (*MARK:A)(X|Y)
+
+The minimum length for a match is one character. If the subject is "ABC", there +will be attempts to match "ABC", "BC", "C", and then finally an empty string. +If the pattern is studied, the final attempt does not take place, because PCRE +knows that the subject is too short, and so the (*MARK) is never encountered. +In this case, studying the pattern does not affect the overall match result, +which is still "no match", but it does affect the auxiliary information that is +returned. +
+  PCRE_NO_UTF8_CHECK
+
+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 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. +

+

+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 +compatibility, 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 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 considered to be more +important that an alternative complete match. +

+

+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 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, +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 subject). 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 success. +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, 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 string again, but with startoffset +set to 4, it finds the second occurrence 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 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 again. There is some code that demonstrates how to +do this in the +pcredemo +sample program. In the most general case, you have to check to see if the +newline convention recognizes CRLF as a newline, and if so, and the current +character is CR followed by LF, advance the starting offset by two characters +instead of one. +

+

+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 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 substring. 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 vector 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 substrings, +each substring using a pair of integers. The remaining third of the vector is +used as workspace by pcre_exec() while matching capturing subpatterns, +and is not available for passing back information. The number passed in +ovecsize should always be a multiple of three. If it is not, it is +rounded down. +

+

+When a match is successful, information about captured substrings is returned +in pairs of integers, starting at the beginning of ovector, and +continuing up to two-thirds of its length at the most. The first element of +each pair is set to the byte offset of the first character in a substring, and +the second is set to the byte offset of the first character after the end of a +substring. Note: these values are always byte offsets, even in UTF-8 +mode. They are not character counts. +

+

+The first pair of integers, ovector[0] and ovector[1], identify the +portion of the subject string matched by the entire pattern. The next pair is +used for the first capturing subpattern, and so on. The value 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 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, it is +used as far as possible (up to two-thirds of its length), and the function +returns a value of zero. If neither the actual string matched nor any captured +substrings are of interest, pcre_exec() may be called with ovector +passed as NULL and ovecsize as zero. However, if the 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 +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 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 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 corresponding 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, of course) are set to -1. +

+

+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 +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 +defined in the header file: +

+  PCRE_ERROR_NOMATCH        (-1)
+
+The subject string did not match the pattern. +
+  PCRE_ERROR_NULL           (-2)
+
+Either code or subject was passed as NULL, or ovector was +NULL and ovecsize was not zero. +
+  PCRE_ERROR_BADOPTION      (-3)
+
+An unrecognized bit was set in the options argument. +
+  PCRE_ERROR_BADMAGIC       (-4)
+
+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 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 overwriting +of the compiled pattern. +
+  PCRE_ERROR_NOMEMORY       (-6)
+
+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 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-for-recursion. +

+  PCRE_ERROR_NOSUBSTRING    (-7)
+
+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 +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. See the +pcrecallout +documentation for details. +
+  PCRE_ERROR_BADUTF8        (-10)
+
+A string that contains an invalid UTF-8 byte sequence was passed as a subject, +and the PCRE_NO_UTF8_CHECK option was not set. If the size of the output vector +(ovecsize) is at least 2, the byte offset to the start of the the invalid +UTF-8 character is placed in the first 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 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)
+
+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 onwards, there are no +restrictions on partial matching. +
+  PCRE_ERROR_INTERNAL       (-14)
+
+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)
+
+This error is given if the value of the ovecsize argument is negative. +
+  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 +description above. +
+  PCRE_ERROR_BADNEWLINE     (-23)
+
+An invalid combination of PCRE_NEWLINE_xxx options was given. +
+  PCRE_ERROR_BADOFFSET      (-24)
+
+The value of startoffset was negative or greater than the length of the +subject, that is, the value in length. +
+  PCRE_ERROR_SHORTUTF8      (-25)
+
+This error is returned instead of PCRE_ERROR_BADUTF8 when the subject string +ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD option is set. +Information about the failure is returned as for PCRE_ERROR_BADUTF8. It is in +fact sufficient to detect this case, but this special error code for +PCRE_PARTIAL_HARD precedes the 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 or 32-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. +
+  PCRE_ERROR_JIT_BADOPTION
+
+This error is returned when a pattern that was successfully studied using a JIT +compile option is being matched, but the matching mode (partial or complete +match) does not correspond to any JIT compilation mode. When the JIT fast path +function is used, this error may be also given for invalid options. See the +pcrejit +documentation for more details. +
+  PCRE_ERROR_BADLENGTH      (-32)
+
+This error is given if pcre_exec() is called with a negative value for +the length argument. +

+

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

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

+This section applies only to the 8-bit library. The corresponding information +for the 16-bit and 32-bit libraries is given in the +pcre16 +and +pcre32 +pages. +

+

+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. +
+  PCRE_UTF8_ERR2
+
+Non-character. These are the last two characters in each plane (0xfffe, 0xffff, +0x1fffe, 0x1ffff .. 0x10fffe, 0x10ffff), and the characters 0xfdd0..0xfdef. +

+
EXTRACTING CAPTURED SUBSTRINGS BY NUMBER
+

+int pcre_copy_substring(const char *subject, int *ovector, +int stringcount, int stringnumber, char *buffer, +int buffersize); +

+

+int pcre_get_substring(const char *subject, int *ovector, +int stringcount, int stringnumber, +const char **stringptr); +

+

+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 +pcre_copy_substring(), pcre_get_substring(), and +pcre_get_substring_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_substring(). +Unfortunately, the interface to pcre_get_substring_list() is 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 functions: +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 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 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_substring(), +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 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 substrings +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 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 empty +string. This can be distinguished from a genuine zero-length substring by +inspecting the appropriate offset in ovector, which is negative for unset +substrings. +

+

+The two convenience functions pcre_free_substring() and +pcre_free_substring_list() can be used to free the memory returned by +a previous call of pcre_get_substring() or +pcre_get_substring_list(), respectively. 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 special interface to another programming language that cannot use +pcre_free directly; it is for these cases that the functions are +provided. +

+
EXTRACTING CAPTURED SUBSTRINGS BY NAME
+

+int pcre_get_stringnumber(const pcre *code, +const char *name); +

+

+int pcre_copy_named_substring(const pcre *code, +const char *subject, int *ovector, +int stringcount, const char *stringname, +char *buffer, int buffersize); +

+

+int pcre_get_named_substring(const pcre *code, +const char *subject, int *ovector, +int stringcount, const char *stringname, +const char **stringptr); +

+

+To extract a substring by name, you first have to find associated number. +For example, for this pattern +

+  (a+)b(?<xxx>\d+)...
+
+the number of the subpattern called "xxx" is 2. If the name is known to 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 compiled +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 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 differences: +

+

+First, instead of a substring number, a substring name is given. Second, 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 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 +appropriate. 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 +subpatterns 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. +

+
DUPLICATE SUBPATTERN NAMES
+

+int pcre_get_stringtable_entries(const pcre *code, +const char *name, char **first, char **last); +

+

+When a pattern is compiled with the PCRE_DUPNAMES option, names for subpatterns +are not required to be unique. (Duplicate names are always allowed for +subpatterns with the same number, created by using the (?| feature. Indeed, if +such subpatterns are named, they are required to 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 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, 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 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 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 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
+

+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 of the callout facility, which is described in +the +pcrecallout +documentation. +

+

+What you have to do is to insert a callout right at the end of the pattern. +When your callout function is called, extract and save the current 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 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
+

+int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, +const char *subject, int length, int startoffset, +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. Nevertheless, 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 +documentation. +

+

+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 +different 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 keeping track of +multiple paths through the pattern tree. More 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(): +

+  int rc;
+  int ovector[10];
+  int wspace[20];
+  rc = pcre_dfa_exec(
+    re,             /* result of pcre_compile() */
+    NULL,           /* we didn't study the pattern */
+    "some string",  /* the subject string */
+    11,             /* the length of the subject string */
+    0,              /* start at offset 0 in the subject */
+    0,              /* default options */
+    ovector,        /* vector of integers for substring information */
+    10,             /* number of elements (NOT size in bytes) */
+    wspace,         /* working space vector */
+    20);            /* number of elements (NOT size in bytes) */
+
+

+
+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_NEWLINE_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_PARTIAL_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 subject +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 +examples, in the +pcrepartial +documentation. +
+  PCRE_DFA_SHORTEST
+
+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 alternative 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 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 +substring 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, if the pattern +

+  <.*>
+
+is matched against the string +
+  This is <something> <something else> <something further> no more
+
+the three matched strings are +
+  <something>
+  <something> <something else>
+  <something> <something else> <something further>
+
+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 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. Unlike pcre_exec(), pcre_dfa_exec() can use +the entire ovector for returning matched strings. +

+
+Error returns from pcre_dfa_exec() +
+

+The pcre_dfa_exec() function returns a negative number when it fails. +Many of the errors are the same as for pcre_exec(), and these are +described +above. +There are in addition the following errors that are specific to +pcre_dfa_exec(): +

+  PCRE_ERROR_DFA_UITEM      (-16)
+
+This return is given if pcre_dfa_exec() encounters an item in the pattern +that it does not support, for instance, the use of \C or a back reference. +
+  PCRE_ERROR_DFA_UCOND      (-17)
+
+This return is given if pcre_dfa_exec() encounters a condition item that +uses a back reference for the condition, or a test for recursion in a specific +group. These are not supported. +
+  PCRE_ERROR_DFA_UMLIMIT    (-18)
+
+This return is given if pcre_dfa_exec() is called with an extra +block that contains a setting of the match_limit or +match_limit_recursion fields. This is not supported (these fields are +meaningless for DFA matching). +
+  PCRE_ERROR_DFA_WSSIZE     (-19)
+
+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 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
+

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

+
AUTHOR
+

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

+
REVISION
+

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

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcrebuild.html b/tools/pcre/doc/html/pcrebuild.html new file mode 100644 index 00000000..6eb169b3 --- /dev/null +++ b/tools/pcre/doc/html/pcrebuild.html @@ -0,0 +1,517 @@ + + +pcrebuild specification + + +

pcrebuild 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 BUILD-TIME OPTIONS
+

+This document describes the optional features of PCRE that can be selected when +the library is compiled. It assumes use of the configure script, where +the optional features are selected or deselected by providing options to +configure before running the make command. However, the same +options can be selected in both Unix-like and non-Unix-like environments using +the GUI facility of cmake-gui if you are using CMake instead of +configure to build PCRE. +

+

+There is a lot more information about building PCRE without using +configure (including information about using CMake or building "by +hand") in the file called NON-AUTOTOOLS-BUILD, which is part of the PCRE +distribution. You should consult this file as well as the README file if +you are building in a non-Unix-like environment. +

+

+The complete list of options for configure (which includes the standard +ones such as the selection of the installation directory) can be obtained by +running +

+  ./configure --help
+
+The following sections include descriptions of options whose names begin with +--enable or --disable. These settings specify changes to the defaults for the +configure command. Because of the way that configure works, +--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. +

+
BUILDING 8-BIT, 16-BIT AND 32-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 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. You can also build a separate +library, called libpcre32, in which strings are contained in vectors of +32-bit data units and interpreted either as single-unit characters or UTF-32 +strings, by adding +
+  --enable-pcre32
+
+to the configure command. If you do not want the 8-bit library, add +
+  --disable-pcre8
+
+as well. At least one of the three 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 or +32-bit libraries. +

+
BUILDING SHARED AND STATIC LIBRARIES
+

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

+  --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, UTF-16 AND UTF-32 SUPPORT
+

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

+  --enable-utf
+
+to the configure command. This setting applies to all three libraries, +adding support for UTF-8 to the 8-bit library, support for UTF-16 to the 16-bit +library, and support for UTF-32 to the to the 32-bit library. There are no +separate options for enabling UTF-8, UTF-16 and UTF-32 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 another 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, UTF-16 or +UTF-32. As well as compiling PCRE with this option, you also have have to set +the PCRE_UTF8, PCRE_UTF16 or PCRE_UTF32 option (as appropriate) when you call +one of the pattern 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 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 support, even if you have +not explicitly requested it. +

+

+Including Unicode property support adds around 30K of tables to the PCRE +library. Only the general category properties such as Lu and Nd 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 the end +of a line. This is the normal newline character on Unix-like systems. You can +compile PCRE to use carriage return (CR) instead, by adding +

+  --enable-newline-is-cr
+
+to the configure command. There is also a --enable-newline-is-lf option, +which explicitly specifies linefeed as the newline character. +
+
+Alternatively, you can specify that line endings are to be indicated by the two +character sequence CRLF. If you want this, add +
+  --enable-newline-is-crlf
+
+to the configure command. There is a fourth option, specified by +
+  --enable-newline-is-anycrlf
+
+which causes PCRE to recognize any of the three sequences CR, LF, or CRLF as +indicating a line ending. Finally, a fifth option, specified by +
+  --enable-newline-is-any
+
+causes PCRE to recognize any Unicode newline sequence. +

+

+Whatever line ending convention is selected when PCRE is built can be +overridden when the library functions are called. At build time it is +conventional to use the standard for your operating system. +

+
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 +

+  --enable-bsr-anycrlf
+
+the default is changed so that \R matches only CR, LF, or CRLF. Whatever is +selected when PCRE is built can be overridden when the library functions are +called. +

+
POSIX MALLOC USAGE
+

+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 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 +

+  --with-posix-malloc-threshold=20
+
+to the configure command. +

+
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, in the 8-bit and 16-bit libraries, 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 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. For the +16-bit library, a value of 3 is rounded up to 4. In these libraries, using +longer offsets slows down the operation of PCRE because it has to load +additional data when handling them. For the 32-bit library the value is always +4 and cannot be overridden; the value of --with-link-size is ignored. +

+
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 +environments where the size of the stack is limited, this can severely 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 +documentation.) 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 +management 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 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 repeatedly +(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 +documentation. 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 +pcre_dfa_exec() matching function. +

+

+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-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 by adding, for example, +

+  --with-match-limit-recursion=10000
+
+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 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 the +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
+

+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, however, be compiled to run in an +EBCDIC environment by adding +

+  --enable-ebcdic
+
+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-utf. +

+

+The EBCDIC character that corresponds to an ASCII LF is assumed to have the +value 0x15 by default. However, in some EBCDIC environments, 0x25 is used. In +such an environment you should use +

+  --enable-ebcdic-nl25
+
+as well as, or instead of, --enable-ebcdic. The EBCDIC character for CR has the +same value as in ASCII, namely, 0x0d. Whichever of 0x15 and 0x25 is not +chosen as LF is made to correspond to the Unicode NEL character (which, in +Unicode, is 0x85). +

+

+The options that select newline behaviour, such as --enable-newline-is-cr, +and equivalent run-time options, refer to these character values in an EBCDIC +environment. +

+
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 +them with libz or libbz2, respectively, by adding one or both of +

+  --enable-pcregrep-libz
+  --enable-pcregrep-libbz2
+
+to the configure command. These options naturally require that the +relevant 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 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 +

+  --enable-pcretest-libreadline
+
+to the configure command, pcretest is linked with the +libreadline library, and when its input is from a terminal, it reads it +using the readline() function. This provides line-editing and history +facilities. Note that libreadline is GPL-licensed, so if you distribute a +binary of pcretest linked in this way, there may be licensing issues. +

+

+Setting this option causes the -lreadline option to be added to the +pcretest build. In many operating environments with a sytem-installed +libreadline this is sufficient. However, in some environments (e.g. +if an unmodified distribution version of readline is in use), some extra +configuration may be necessary. The INSTALL file for libreadline says +this: +

+  "Readline uses the termcap functions, but does not link with the
+  termcap or curses library itself, allowing applications which link
+  with readline the to choose an appropriate library."
+
+If your environment has not been set up so that an appropriate library is +automatically included, you may need to add something like +
+  LIBS="-ncurses"
+
+immediately before the configure command. +

+
DEBUGGING WITH VALGRIND SUPPORT
+

+By adding the +

+  --enable-valgrind
+
+option to to the configure command, PCRE will use valgrind annotations +to mark certain memory regions as unaddressable. This allows it to detect +invalid memory accesses, and is mostly useful for debugging PCRE itself. +

+
CODE COVERAGE REPORTING
+

+If your C compiler is gcc, you can build a version of PCRE that can generate a +code coverage report for its test suite. To enable this, you must install +lcov version 1.6 or above. Then specify +

+  --enable-coverage
+
+to the configure command and build PCRE in the usual way. +

+

+Note that using ccache (a caching C compiler) is incompatible with code +coverage reporting. If you have configured ccache to run automatically +on your system, you must set the environment variable +

+  CCACHE_DISABLE=1
+
+before running make to build PCRE, so that ccache is not used. +

+

+When --enable-coverage is used, the following addition targets are added to the +Makefile: +

+  make coverage
+
+This creates a fresh coverage report for the PCRE test suite. It is equivalent +to running "make coverage-reset", "make coverage-baseline", "make check", and +then "make coverage-report". +
+  make coverage-reset
+
+This zeroes the coverage counters, but does nothing else. +
+  make coverage-baseline
+
+This captures baseline coverage information. +
+  make coverage-report
+
+This creates the coverage report. +
+  make coverage-clean-report
+
+This removes the generated coverage report without cleaning the coverage data +itself. +
+  make coverage-clean-data
+
+This removes the captured coverage data without removing the coverage files +created at compile time (*.gcno). +
+  make coverage-clean
+
+This cleans all coverage data including the generated coverage report. For more +information about code coverage, see the gcov and lcov +documentation. +

+
SEE ALSO
+

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

+
AUTHOR
+

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

+
REVISION
+

+Last updated: 30 October 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcrecallout.html b/tools/pcre/doc/html/pcrecallout.html new file mode 100644 index 00000000..b28e347f --- /dev/null +++ b/tools/pcre/doc/html/pcrecallout.html @@ -0,0 +1,243 @@ + + +pcrecallout specification + + +

pcrecallout 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_callout)(pcre_callout_block *); +

+

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

+

+int (*pcre32_callout)(pcre32_callout_block *); +

+
DESCRIPTION
+

+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 (pcre16_callout for the 16-bit +library, pcre32_callout for the 32-bit library). By default, this +variable contains NULL, which disables all calling out. +

+

+Within a regular expression, (?C) indicates the points at which the external +function is to be called. 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 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}|--)
+
+it is processed as if it were +
+
+(?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255) +
+
+Notice that there is a callout before and after each parenthesis and +alternation bar. Automatic callouts can be used for tracking the progress of +pattern matching. The +pcretest +command has an option that sets automatic callouts; when it is used, the output +indicates how the pattern is matched. This is useful information when you are +trying to optimize the performance of a particular pattern. +

+

+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 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", 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 patterns, if it has +been scanned far enough. +

+

+You can disable these optimizations by passing the PCRE_NO_START_OPTIMIZE +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 or pcre[16|32]_callout is called +(if it is set). This applies to both normal and DFA matching. The only +argument to the callout function is a pointer to a pcre_callout +or pcre[16|32]_callout block. +These structures contains the following fields: +

+  int           version;
+  int           callout_number;
+  int          *offset_vector;
+  const char   *subject;           (8-bit version)
+  PCRE_SPTR16   subject;           (16-bit version)
+  PCRE_SPTR32   subject;           (32-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)
+  const PCRE_UCHAR32  *mark;       (32-bit version)
+
+The version field is an integer containing the version number of the +block format. The initial version was 0; the current version is 2. The version +number will change again in future if additional fields are added, but the +intention is never to remove any of the existing fields. +

+

+The callout_number field contains the number of the callout, as compiled +into the pattern (that is, the number after ?C for manual callouts, and 255 for +automatically generated callouts). +

+

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

+

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

+

+The start_match field normally contains the offset within the subject at +which the current match attempt started. However, if the escape sequence \K +has been encountered, this value is changed to reflect the modified starting +point. If the pattern is not anchored, the callout function may be called +several times from the same point in the pattern for different starting points +in the subject. +

+

+The current_position field contains the offset within the subject of the +current match pointer. +

+

+When the pcre_exec() or pcre[16|32]_exec() is used, the +capture_top field contains one more than the number of the highest +numbered 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 for the DFA matching functions. +

+

+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 pcre[16|32]_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 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 pcre[16|32]_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, 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 standard "no match" failure. +The error number PCRE_ERROR_CALLOUT is reserved for use by callout functions; +it will never be used by PCRE itself. +

+
AUTHOR
+

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

+
REVISION
+

+Last updated: 24 June 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcrecompat.html b/tools/pcre/doc/html/pcrecompat.html new file mode 100644 index 00000000..0637781b --- /dev/null +++ b/tools/pcre/doc/html/pcrecompat.html @@ -0,0 +1,216 @@ + + +pcrecompat specification + + +

pcrecompat 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. +
+
+DIFFERENCES BETWEEN PCRE AND PERL +
+

+This document describes the differences in the ways that PCRE and Perl handle +regular expressions. The differences described here are with respect to Perl +versions 5.10 and above. +

+

+1. PCRE has only a subset of Perl's 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 assertions 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 succeeding), but only if the +negative lookahead assertion contains just one branch. +

+

+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 normal 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 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 +built with Unicode character property support. The properties that can be +tested with \p and \P are limited to the general category properties 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 representation 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. 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 +following examples: +

+    Pattern            PCRE matches      Perl matches
+
+    \Qabc$xyz\E        abc$xyz           abc followed by the contents of $xyz
+    \Qabc\$xyz\E       abc\$xyz          abc\$xyz
+    \Qabc\E\$\Qxyz\E   abc$xyz           abc$xyz
+
+The \Q...\E sequence is recognized both inside and outside character classes. +

+

+8. 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 +the +pcrecallout +documentation for details. +

+

+9. 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. 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. +

+

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

+

+12. PCRE's handling of duplicate subpattern numbers and duplicate 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), +where the two capturing parentheses have the same number but different names, +is not supported, and causes an error at compile time. If it were allowed, it +would not be possible to distinguish which parentheses matched, because both +names map to capturing subpattern number 1. To avoid this confusing situation, +an error is given at compile time. +

+

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

+

+14. PCRE provides some extensions to the Perl regular expression 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: +
+
+(a) Although lookbehind assertions in PCRE must match fixed length strings, +each alternative branch of a lookbehind assertion can match a different length +of string. Perl requires them all to have the same length. +
+
+(b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $ +meta-character matches only at the very end of the string. +
+
+(c) If PCRE_EXTRA is set, a backslash followed by a letter with no special +meaning is faulted. Otherwise, like Perl, the backslash is quietly ignored. +(Perl can be made to issue a warning.) +
+
+(d) If PCRE_UNGREEDY is set, the greediness of the repetition quantifiers is +inverted, that is, by default they are not greedy, but if followed by a +question mark they are. +
+
+(e) PCRE_ANCHORED can be used at matching time to force a pattern to be tried +only at the first matching position in the subject string. +
+
+(f) The PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, and +PCRE_NO_AUTO_CAPTURE options for pcre_exec() have no Perl equivalents. +
+
+(g) The \R escape sequence can be restricted to match only CR, LF, or CRLF +by the PCRE_BSR_ANYCRLF option. +
+
+(h) The callout facility is PCRE-specific. +
+
+(i) The partial matching facility is PCRE-specific. +
+
+(j) Patterns compiled by PCRE can be saved and re-used at a later time, even on +different hosts that have the other endianness. However, this does not apply to +optimized data created by the just-in-time compiler. +
+
+(k) The alternative matching functions (pcre_dfa_exec(), +pcre16_dfa_exec() and pcre32_dfa_exec(),) match in a different way +and are not Perl-compatible. +
+
+(l) PCRE recognizes some special sequences such as (*CR) at the start of +a pattern that set overall options that cannot be changed within the pattern. +

+
+AUTHOR +
+

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

+
+REVISION +
+

+Last updated: 25 August 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcrecpp.html b/tools/pcre/doc/html/pcrecpp.html new file mode 100644 index 00000000..b7eac3a3 --- /dev/null +++ b/tools/pcre/doc/html/pcrecpp.html @@ -0,0 +1,368 @@ + + +pcrecpp specification + + +

pcrecpp 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 OF C++ WRAPPER
+

+#include <pcrecpp.h> +

+
DESCRIPTION
+

+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. Note that the C++ wrapper supports only the original 8-bit +PCRE library. There is no 16-bit or 32-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 sub-strings that +match sub-patterns into them. +

+  Example: successful match
+     pcrecpp::RE re("h.*o");
+     re.FullMatch("hello");
+
+  Example: unsuccessful match (requires full match):
+     pcrecpp::RE re("e");
+     !re.FullMatch("hello");
+
+  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. Either could correctly be +used for any of these examples. +

+

+You must supply extra pointer arguments to extract matched subpieces. +

+  Example: extracts "ruby" into "s" and 1234 into "i"
+     int i;
+     string s;
+     pcrecpp::RE re("(\\w+):(\\d+)");
+     re.FullMatch("ruby:1234", &s, &i);
+
+  Example: does not try to extract any extra sub-patterns
+     re.FullMatch("ruby:1234", &s);
+
+  Example: does not try to extract into NULL
+     re.FullMatch("ruby:1234", NULL, &i);
+
+  Example: integer overflow causes failure
+     !re.FullMatch("ruby:1234567891234", NULL, &i);
+
+  Example: fails because there aren't enough sub-patterns:
+     !pcrecpp::RE("\\w+:\\d+").FullMatch("ruby:1234", &s);
+
+  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 +type, or one of: +
+   string        (matched piece is copied to string)
+   StringPiece   (StringPiece is mutated to point to matched piece)
+   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 satisfied: +
+  a. "text" matches "pattern" exactly;
+
+  b. The number of matched sub-patterns is >= number of supplied
+     pointers;
+
+  c. The "i"th argument has a suitable type for holding the
+     string captured as the "i"th sub-pattern. If you pass in
+     void * NULL for the "i"th argument, or a non-void * NULL
+     of the correct type, or pass fewer arguments than the
+     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 +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 +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 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, 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 "1\.5\-2\.0\?". +

+
PARTIAL MATCHES
+

+You can use the "PartialMatch" operation when you want the pattern +to match any substring of the text. +

+  Example: simple search for a string:
+     pcrecpp::RE("ell").PartialMatch("hello");
+
+  Example: find first number in a string:
+     int number;
+     pcrecpp::RE re("(\\d+)");
+     re.PartialMatch("x*100 + 20", &number);
+     assert(number == 100);
+
+

+
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 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 of a multi-byte character. +

+  Example:
+     pcrecpp::RE_Options options;
+     options.set_utf8();
+     pcrecpp::RE re(utf8_pattern, options);
+     re.FullMatch(utf8_string);
+
+  Example: using the convenience function UTF8():
+     pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8());
+     re.FullMatch(utf8_string);
+
+NOTE: The UTF8 flag is ignored if pcre was not configured with the +
+      --enable-utf8 flag.
+
+

+
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. Currently, the following modifiers are +supported: +

+   modifier              description               Perl corresponding
+
+   PCRE_CASELESS         case insensitive match      /i
+   PCRE_MULTILINE        multiple lines match        /m
+   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 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 +capture, while (ab|cd) does. +

+

+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 +instance, PCRE_CASELESS is handled by +

+  bool caseless()
+
+which returns true if the modifier is set, and +
+  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 +execution 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 RE_Options object, set the appropriate options, and pass this +object to a RE constructor. Example: +

+   RE_Options opt;
+   opt.set_caseless(true);
+   if (RE("HELLO", opt).PartialMatch("hello world")) ...
+
+RE_options has two constructors. The default constructor takes no arguments 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,
+     RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str);
+
+However, new code is better off doing +
+   RE(pattern,
+     RE_Options().set_caseless(true).set_multiline(true))
+       .PartialMatch(str);
+
+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 +appropriate 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 statement, you may write: +

+   RE(" ^ xyz \\s+ .* blah$",
+     RE_Options()
+       .set_caseless(true)
+       .set_extended(true)
+       .set_multiline(true)).PartialMatch(sometext);
+
+
+

+
SCANNING TEXT INCREMENTALLY
+

+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 pcrecpp namespace. +

+  Example: read lines of the form "var = value" from a string.
+     string contents = ...;                 // Fill string somehow
+     pcrecpp::StringPiece input(contents);  // Wrap in a StringPiece
+
+     string var;
+     int value;
+     pcrecpp::RE re("(\\w+) = (\\d+)\n");
+     while (re.Consume(&input, &var, &value)) {
+       ...;
+     }
+
+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 +could extract all words from a string by repeatedly calling +

+  pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word)
+
+

+
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 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 base-10. +

+  Example:
+    int a, b, c, d;
+    pcrecpp::RE re("(.*) (.*) (.*) (.*)");
+    re.FullMatch("100 40 0100 0x40",
+                 pcrecpp::Octal(&a), pcrecpp::Hex(&b),
+                 pcrecpp::CRadix(&c), pcrecpp::CRadix(&d));
+
+will leave 64 in a, b, c, and d. +

+
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 pattern. \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 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 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 +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 +occurred and the extraction happened successfully; if no match occurs, the +string is left unaffected. +

+
AUTHOR
+

+The C++ wrapper was contributed by Google Inc. +
+Copyright © 2007 Google Inc. +
+

+
REVISION
+

+Last updated: 08 January 2012 +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcredemo.html b/tools/pcre/doc/html/pcredemo.html new file mode 100644 index 00000000..894a9308 --- /dev/null +++ b/tools/pcre/doc/html/pcredemo.html @@ -0,0 +1,426 @@ + + +pcredemo specification + + +

pcredemo 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 DEMONSTRATION PROGRAM           *
+*************************************************/
+
+/* This is a demonstration program to illustrate the most straightforward ways
+of calling the PCRE regular expression library from a C program. See the
+pcresample documentation for a short discussion ("man pcresample" if you have
+the PCRE man pages installed).
+
+In Unix-like environments, if PCRE is installed in your standard system
+libraries, you should be able to compile this program using this command:
+
+gcc -Wall pcredemo.c -lpcre -o pcredemo
+
+If PCRE is not installed in a standard place, it is likely to be installed with
+support for the pkg-config mechanism. If you have pkg-config, you can compile
+this program using this command:
+
+gcc -Wall pcredemo.c `pkg-config --cflags --libs libpcre` -o pcredemo
+
+If you do not have pkg-config, you may have to use this:
+
+gcc -Wall pcredemo.c -I/usr/local/include -L/usr/local/lib \
+  -R/usr/local/lib -lpcre -o pcredemo
+
+Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and
+library files for PCRE are installed on your system. Only some operating
+systems (e.g. Solaris) use the -R option.
+
+Building under Windows:
+
+If you want to statically link this program against a non-dll .a file, you must
+define PCRE_STATIC before including pcre.h, otherwise the pcre_malloc() and
+pcre_free() exported functions will be declared __declspec(dllimport), with
+unwanted results. So in this environment, uncomment the following line. */
+
+/* #define PCRE_STATIC */
+
+#include <stdio.h>
+#include <string.h>
+#include <pcre.h>
+
+#define OVECCOUNT 30    /* should be a multiple of 3 */
+
+
+int main(int argc, char **argv)
+{
+pcre *re;
+const char *error;
+char *pattern;
+char *subject;
+unsigned char *name_table;
+unsigned int option_bits;
+int erroffset;
+int find_all;
+int crlf_is_newline;
+int namecount;
+int name_entry_size;
+int ovector[OVECCOUNT];
+int subject_length;
+int rc, i;
+int utf8;
+
+
+/**************************************************************************
+* First, sort out the command line. There is only one possible option at  *
+* the moment, "-g" to request repeated matching to find all occurrences,  *
+* like Perl's /g option. We set the variable find_all to a non-zero value *
+* if the -g option is present. Apart from that, there must be exactly two *
+* arguments.                                                              *
+**************************************************************************/
+
+find_all = 0;
+for (i = 1; i < argc; i++)
+  {
+  if (strcmp(argv[i], "-g") == 0) find_all = 1;
+    else break;
+  }
+
+/* After the options, we require exactly two arguments, which are the pattern,
+and the subject string. */
+
+if (argc - i != 2)
+  {
+  printf("Two arguments required: a regex and a subject string\n");
+  return 1;
+  }
+
+pattern = argv[i];
+subject = argv[i+1];
+subject_length = (int)strlen(subject);
+
+
+/*************************************************************************
+* Now we are going to compile the regular expression pattern, and handle *
+* and errors that are detected.                                          *
+*************************************************************************/
+
+re = pcre_compile(
+  pattern,              /* the pattern */
+  0,                    /* default options */
+  &error,               /* for error message */
+  &erroffset,           /* for error offset */
+  NULL);                /* use default character tables */
+
+/* Compilation failed: print the error message and exit */
+
+if (re == NULL)
+  {
+  printf("PCRE compilation failed at offset %d: %s\n", erroffset, error);
+  return 1;
+  }
+
+
+/*************************************************************************
+* If the compilation succeeded, we call PCRE again, in order to do a     *
+* pattern match against the subject string. This does just ONE match. If *
+* further matching is needed, it will be done below.                     *
+*************************************************************************/
+
+rc = pcre_exec(
+  re,                   /* the compiled pattern */
+  NULL,                 /* no extra data - we didn't study the pattern */
+  subject,              /* the subject string */
+  subject_length,       /* the length of the subject */
+  0,                    /* start at offset 0 in the subject */
+  0,                    /* default options */
+  ovector,              /* output vector for substring information */
+  OVECCOUNT);           /* number of elements in the output vector */
+
+/* Matching failed: handle error cases */
+
+if (rc < 0)
+  {
+  switch(rc)
+    {
+    case PCRE_ERROR_NOMATCH: printf("No match\n"); break;
+    /*
+    Handle other special cases if you like
+    */
+    default: printf("Matching error %d\n", rc); break;
+    }
+  pcre_free(re);     /* Release memory used for the compiled pattern */
+  return 1;
+  }
+
+/* Match succeded */
+
+printf("\nMatch succeeded at offset %d\n", ovector[0]);
+
+
+/*************************************************************************
+* We have found the first match within the subject string. If the output *
+* vector wasn't big enough, say so. Then output any substrings that were *
+* captured.                                                              *
+*************************************************************************/
+
+/* The output vector wasn't big enough */
+
+if (rc == 0)
+  {
+  rc = OVECCOUNT/3;
+  printf("ovector only has room for %d captured substrings\n", rc - 1);
+  }
+
+/* Show substrings stored in the output vector by number. Obviously, in a real
+application you might want to do things other than print them. */
+
+for (i = 0; i < rc; i++)
+  {
+  char *substring_start = subject + ovector[2*i];
+  int substring_length = ovector[2*i+1] - ovector[2*i];
+  printf("%2d: %.*s\n", i, substring_length, substring_start);
+  }
+
+
+/**************************************************************************
+* That concludes the basic part of this demonstration program. We have    *
+* compiled a pattern, and performed a single match. The code that follows *
+* shows first how to access named substrings, and then how to code for    *
+* repeated matches on the same subject.                                   *
+**************************************************************************/
+
+/* See if there are any named substrings, and if so, show them by name. First
+we have to extract the count of named parentheses from the pattern. */
+
+(void)pcre_fullinfo(
+  re,                   /* the compiled pattern */
+  NULL,                 /* no extra data - we didn't study the pattern */
+  PCRE_INFO_NAMECOUNT,  /* number of named substrings */
+  &namecount);          /* where to put the answer */
+
+if (namecount <= 0) printf("No named substrings\n"); else
+  {
+  unsigned char *tabptr;
+  printf("Named substrings\n");
+
+  /* Before we can access the substrings, we must extract the table for
+  translating names to numbers, and the size of each entry in the table. */
+
+  (void)pcre_fullinfo(
+    re,                       /* the compiled pattern */
+    NULL,                     /* no extra data - we didn't study the pattern */
+    PCRE_INFO_NAMETABLE,      /* address of the table */
+    &name_table);             /* where to put the answer */
+
+  (void)pcre_fullinfo(
+    re,                       /* the compiled pattern */
+    NULL,                     /* no extra data - we didn't study the pattern */
+    PCRE_INFO_NAMEENTRYSIZE,  /* size of each entry in the table */
+    &name_entry_size);        /* where to put the answer */
+
+  /* Now we can scan the table and, for each entry, print the number, the name,
+  and the substring itself. */
+
+  tabptr = name_table;
+  for (i = 0; i < namecount; i++)
+    {
+    int n = (tabptr[0] << 8) | tabptr[1];
+    printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2,
+      ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]);
+    tabptr += name_entry_size;
+    }
+  }
+
+
+/*************************************************************************
+* If the "-g" option was given on the command line, we want to continue  *
+* to search for additional matches in the subject string, in a similar   *
+* way to the /g option in Perl. This turns out to be trickier than you   *
+* might think because of the possibility of matching an empty string.    *
+* What happens is as follows:                                            *
+*                                                                        *
+* If the previous match was NOT for an empty string, we can just start   *
+* the next match at the end of the previous one.                         *
+*                                                                        *
+* If the previous match WAS for an empty string, we can't do that, as it *
+* would lead to an infinite loop. Instead, a special call of pcre_exec() *
+* is made with the PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED flags set.    *
+* The first of these tells PCRE that an empty string at the start of the *
+* subject is not a valid match; other possibilities must be tried. The   *
+* second flag restricts PCRE to one match attempt at the initial string  *
+* position. If this match succeeds, an alternative to the empty string   *
+* match has been found, and we can print it and proceed round the loop,  *
+* advancing by the length of whatever was found. If this match does not  *
+* succeed, we still stay in the loop, advancing by just one character.   *
+* In UTF-8 mode, which can be set by (*UTF8) in the pattern, this may be *
+* 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 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.  *
+*************************************************************************/
+
+if (!find_all)     /* Check for -g */
+  {
+  pcre_free(re);   /* Release the memory used for the compiled pattern */
+  return 0;        /* Finish unless -g was given */
+  }
+
+/* Before running the loop, check for UTF-8 and whether CRLF is a valid newline
+sequence. First, find the options with which the regex was compiled; extract
+the UTF-8 state, and mask off all but the newline options. */
+
+(void)pcre_fullinfo(re, NULL, PCRE_INFO_OPTIONS, &option_bits);
+utf8 = option_bits & PCRE_UTF8;
+option_bits &= PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_CRLF|
+               PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF;
+
+/* If no newline options were set, find the default newline convention from the
+build configuration. */
+
+if (option_bits == 0)
+  {
+  int 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. */
+  option_bits = (d == 13)? PCRE_NEWLINE_CR :
+          (d == 10)? PCRE_NEWLINE_LF :
+          (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF :
+          (d == -2)? PCRE_NEWLINE_ANYCRLF :
+          (d == -1)? PCRE_NEWLINE_ANY : 0;
+  }
+
+/* See if CRLF is a valid newline sequence. */
+
+crlf_is_newline =
+     option_bits == PCRE_NEWLINE_ANY ||
+     option_bits == PCRE_NEWLINE_CRLF ||
+     option_bits == PCRE_NEWLINE_ANYCRLF;
+
+/* Loop for second and subsequent matches */
+
+for (;;)
+  {
+  int options = 0;                 /* Normally no options */
+  int start_offset = ovector[1];   /* Start at end of previous match */
+
+  /* If the previous match was for an empty string, we are finished if we are
+  at the end of the subject. Otherwise, arrange to run another match at the
+  same point to see if a non-empty match can be found. */
+
+  if (ovector[0] == ovector[1])
+    {
+    if (ovector[0] == subject_length) break;
+    options = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED;
+    }
+
+  /* Run the next matching operation */
+
+  rc = pcre_exec(
+    re,                   /* the compiled pattern */
+    NULL,                 /* no extra data - we didn't study the pattern */
+    subject,              /* the subject string */
+    subject_length,       /* the length of the subject */
+    start_offset,         /* starting offset in the subject */
+    options,              /* options */
+    ovector,              /* output vector for substring information */
+    OVECCOUNT);           /* number of elements in the output vector */
+
+  /* This time, a result of NOMATCH isn't an error. If the value in "options"
+  is zero, it just means we have found all possible matches, so the loop ends.
+  Otherwise, it means we have failed to find a non-empty-string match at a
+  point where there was a previous empty-string match. In this case, we do what
+  Perl does: advance the matching position by one character, and continue. We
+  do this by setting the "end of previous match" offset, because that is picked
+  up at the top of the loop as the point at which to start again.
+
+  There are two complications: (a) When CRLF is a valid newline sequence, and
+  the current position is just before it, advance by an extra byte. (b)
+  Otherwise we must ensure that we skip an entire UTF-8 character if we are in
+  UTF-8 mode. */
+
+  if (rc == PCRE_ERROR_NOMATCH)
+    {
+    if (options == 0) break;                    /* All matches found */
+    ovector[1] = start_offset + 1;              /* Advance one byte */
+    if (crlf_is_newline &&                      /* If CRLF is newline & */
+        start_offset < subject_length - 1 &&    /* we are at CRLF, */
+        subject[start_offset] == '\r' &&
+        subject[start_offset + 1] == '\n')
+      ovector[1] += 1;                          /* Advance by one more. */
+    else if (utf8)                              /* Otherwise, ensure we */
+      {                                         /* advance a whole UTF-8 */
+      while (ovector[1] < subject_length)       /* character. */
+        {
+        if ((subject[ovector[1]] & 0xc0) != 0x80) break;
+        ovector[1] += 1;
+        }
+      }
+    continue;    /* Go round the loop again */
+    }
+
+  /* Other matching errors are not recoverable. */
+
+  if (rc < 0)
+    {
+    printf("Matching error %d\n", rc);
+    pcre_free(re);    /* Release memory used for the compiled pattern */
+    return 1;
+    }
+
+  /* Match succeded */
+
+  printf("\nMatch succeeded again at offset %d\n", ovector[0]);
+
+  /* The match succeeded, but the output vector wasn't big enough. */
+
+  if (rc == 0)
+    {
+    rc = OVECCOUNT/3;
+    printf("ovector only has room for %d captured substrings\n", rc - 1);
+    }
+
+  /* As before, show substrings stored in the output vector by number, and then
+  also any named substrings. */
+
+  for (i = 0; i < rc; i++)
+    {
+    char *substring_start = subject + ovector[2*i];
+    int substring_length = ovector[2*i+1] - ovector[2*i];
+    printf("%2d: %.*s\n", i, substring_length, substring_start);
+    }
+
+  if (namecount <= 0) printf("No named substrings\n"); else
+    {
+    unsigned char *tabptr = name_table;
+    printf("Named substrings\n");
+    for (i = 0; i < namecount; i++)
+      {
+      int n = (tabptr[0] << 8) | tabptr[1];
+      printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2,
+        ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]);
+      tabptr += name_entry_size;
+      }
+    }
+  }      /* End of loop to find second and subsequent matches */
+
+printf("\n");
+pcre_free(re);       /* Release memory used for the compiled pattern */
+return 0;
+}
+
+/* End of pcredemo.c */
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcregrep.html b/tools/pcre/doc/html/pcregrep.html new file mode 100644 index 00000000..bac8f9a4 --- /dev/null +++ b/tools/pcre/doc/html/pcregrep.html @@ -0,0 +1,757 @@ + + +pcregrep specification + + +

pcregrep 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
+

+pcregrep [options] [long options] [pattern] [path1 path2 ...] +

+
DESCRIPTION
+

+pcregrep searches files for character patterns, in the same way as other +grep commands do, but it uses the PCRE regular expression library to support +patterns that are compatible with the regular expressions of Perl 5. See +pcrepattern(3) +for a full description of syntax and semantics of the regular expressions +that PCRE supports. +

+

+Patterns, whether supplied on the command line or in a separate file, are given +without delimiters. For example: +

+  pcregrep Thursday /etc/motd
+
+If you attempt to use delimiters (for example, by surrounding a pattern with +slashes, as is common in Perl scripts), they are interpreted as part of the +pattern. Quotes can of course be used to delimit patterns on the command line +because they are interpreted by the shell, and indeed quotes are required if a +pattern contains white space or shell metacharacters. +

+

+The first argument that follows any option settings is treated as the single +pattern to be matched when neither -e nor -f is present. +Conversely, when one or both of these options are used to specify patterns, all +arguments are treated as path names. At least one of -e, -f, or an +argument pattern must be provided. +

+

+If no files are specified, pcregrep reads the standard input. The +standard input can also be referenced by a name consisting of a single hyphen. +For example: +

+  pcregrep some-pattern /file1 - /file3
+
+By default, each line that matches a pattern is copied to the standard +output, and if there is more than one file, the file name is output at the +start of each line, followed by a colon. However, there are options that can +change how pcregrep behaves. In particular, the -M option makes it +possible to search for patterns that span line boundaries. What defines a line +boundary is controlled by the -N (--newline) option. +

+

+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 can be no longer than 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 a line, no further patterns are +considered. However, if --colour (or --color) is used to colour the +matching substrings, or if --only-matching, --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 follow the one that matched are not tried on the earlier part +of the line. +

+

+This behaviour means that the order in which multiple patterns are specified +can affect the output when one of the above options is used. This is no longer +the same behaviour as GNU grep, which now manages to display earlier matches +for later patterns (as long as there is no overlap). +

+

+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 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 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 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 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. Similarly, except where noted below, if an option is given twice, the +later setting is used. Numerical values for options may be followed by K or M, +to signify multiplication by 1024 or 1024*1024 respectively. +

+

+-- +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. +

+

+-A number, --after-context=number +Output number lines of context after each matching line. If filenames +and/or line numbers are being output, a hyphen separator 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 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 +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 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. +

+

+-c, --count +Do not output individual lines from the files that are being scanned; instead +output the number of lines that would otherwise have been shown. If no lines +are selected, the number zero is output. If several files are are being +scanned, a count is output for each of them. However, if the +--files-with-matches option is also used, only those files whose counts +are greater than zero are listed. When -c is used, the -A, +-B, and -C options are ignored. +

+

+--colour, --color +If this option is given without any data, it is equivalent to "--colour=auto". +If data is required, it must be given in the same shell item, separated by an +equals sign. +

+

+--colour=value, --color=value +This option specifies under what circumstances the parts of a line that matched +a pattern should be coloured in the output. By default, the output is not +coloured. The value (which is optional, see above) may be "never", "always", or +"auto". In the latter case, colouring happens only if the standard output is +connected to a terminal. More resources are used when colouring is enabled, +because pcregrep has to search for all possible matches in a line, not +just one, in order to colour them all. +
+
+The colour that is used can be specified by setting the environment variable +PCREGREP_COLOUR or PCREGREP_COLOR. The value of this variable should be a +string of two numbers, separated by a semicolon. They are copied directly into +the control string for setting colour on a terminal, so it is your +responsibility to ensure that they make sense. If neither of the environment +variables is set, the default is "1;31", which gives red. +

+

+-D action, --devices=action +If an input path is not a regular file or a directory, "action" specifies how +it is to be processed. Valid values are "read" (the default) or "skip" +(silently skip the path). +

+

+-d action, --directories=action +If an input path is a directory, "action" specifies how it is to be processed. +Valid values are "read" (the default in non-Windows environments, for +compatibility with GNU grep), "recurse" (equivalent to the -r option), or +"skip" (silently skip the path, the default in Windows environments). In the +"read" case, directories are read as if they were ordinary files. In some +operating systems the effect of reading a directory like this is an immediate +end-of-file; in others it may provoke an error. +

+

+-e pattern, --regex=pattern, --regexp=pattern +Specify a pattern to be matched. This option can be used multiple times in +order to specify several patterns. It can also be used as a way of specifying a +single pattern that starts with a hyphen. When -e is used, no argument +pattern is taken from the command line; all arguments are treated as file +names. There is no limit to the number of patterns. They are applied to each +line in the order in which they are defined until one matches. +
+
+If -f is used with -e, the command line patterns are matched first, +followed by the patterns from the file(s), independent of the order in which +these options are specified. Note that multiple use of -e is not the same +as a single pattern with alternatives. For example, X|Y finds the first +character in a line that is X or Y, whereas if the two patterns are given +separately, with X first, pcregrep finds X if it is present, even if it +follows Y in the line. It finds Y only if there is no X in the line. This +matters only if you are using -o or --colo(u)r to show the part(s) +of the line that matched. +

+

+--exclude=pattern +Files (but not directories) whose names match the pattern are skipped without +being processed. This applies to all files, whether listed on the command line, +obtained from --file-list, or by scanning a directory. The pattern is a +PCRE regular expression, and is matched against the final component of the file +name, not the entire path. The -F, -w, and -x options do not +apply to this pattern. The option may be given any number of times in order to +specify multiple patterns. If a file name matches both an --include +and an --exclude pattern, it is excluded. There is no short form for this +option. +

+

+--exclude-from=filename +Treat each non-empty line of the file as the data for an --exclude +option. What constitutes a newline when reading the file is the operating +system's default. The --newline option has no effect on this option. This +option may be given more than once in order to specify a number of files to +read. +

+

+--exclude-dir=pattern +Directories whose names match the pattern are skipped without being processed, +whatever the setting of the --recursive option. This applies to all +directories, whether listed on the command line, obtained from +--file-list, or by scanning a parent directory. The pattern is a PCRE +regular expression, and is matched against the final component of the directory +name, not the entire path. The -F, -w, and -x options do not +apply to this pattern. The option may be given any number of times in order to +specify more than one pattern. If a directory matches both --include-dir +and --exclude-dir, it is excluded. There is no short form for this +option. +

+

+-F, --fixed-strings +Interpret each data-matching pattern as a list of fixed strings, separated by +newlines, instead of as a regular expression. What constitutes a newline for +this purpose is controlled by the --newline option. The -w (match +as a word) and -x (match whole line) options can be used with -F. +They apply to each of the fixed strings. A line is selected if any of the fixed +strings are found in it (subject to -w or -x, if present). This +option applies only to the patterns that are matched against the contents of +files; it does not apply to patterns specified by any of the --include or +--exclude options. +

+

+-f filename, --file=filename +Read patterns from the file, one per line, and match them against +each line of input. What constitutes a newline when reading the file is the +operating system's default. The --newline option has no effect on this +option. 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. +
+
+If this option is given more than once, all the specified files are +read. A data line is output if any of the patterns match it. A 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 the names of paths to be searched. +

+

+--file-list=filename +Read a list of files and/or directories that are to be scanned from the given +file, one per line. Trailing white space is removed from each line, and blank +lines are ignored. These paths are processed before any that are 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. If this option is given more than once, all the specified files are +read. +

+

+--file-offsets +Instead of showing lines or parts of lines that match, show each match as an +offset from the start of the file and a length, 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 separately. This option is mutually exclusive with --line-offsets +and --only-matching. +

+

+-H, --with-filename +Force the inclusion of the filename at the start of output lines when searching +a single file. By default, the filename is not shown in this case. For matching +lines, the filename is followed by a colon; for context lines, a hyphen +separator is used. If a line number is also being output, it follows the file +name. +

+

+-h, --no-filename +Suppress the output filenames when searching multiple files. By default, +filenames are shown when multiple files are searched. For matching lines, the +filename is followed by a colon; for context lines, a hyphen separator is used. +If a line number is also being output, it follows the file name. +

+

+--help +Output a help message, giving brief details of the command options and file +type support, and then exit. Anything else on the command line is +ignored. +

+

+-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. +

+

+--include=pattern +If any --include patterns are specified, the only files that are +processed are those that match one of the patterns (and do not match an +--exclude pattern). This option does not affect directories, but it +applies to all files, whether listed on the command line, obtained from +--file-list, or by scanning a directory. The pattern is a PCRE regular +expression, and is matched against the final component of the file name, not +the entire path. The -F, -w, and -x options do not apply to +this pattern. The option may be given any number of times. If a file name +matches both an --include and an --exclude pattern, it is excluded. +There is no short form for this option. +

+

+--include-from=filename +Treat each non-empty line of the file as the data for an --include +option. What constitutes a newline for this purpose is the operating system's +default. The --newline option has no effect on this option. This option +may be given any number of times; all the files are read. +

+

+--include-dir=pattern +If any --include-dir patterns are specified, the only directories that +are processed are those that match one of the patterns (and do not match an +--exclude-dir pattern). This applies to all directories, whether listed +on the command line, obtained from --file-list, or by scanning a parent +directory. The pattern is a PCRE regular expression, and is matched against the +final component of the directory name, not the entire path. The -F, +-w, and -x options do not apply to this pattern. The option may be +given any number of times. If a directory 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 separate line. +

+

+-l, --files-with-matches +Instead of outputting lines from the files, just output the names of the files +containing lines that would have been output. 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 suppressing the listing of files with no matches. +

+

+--label=name +This option supplies a name to be used for the standard input when file names +are being output. If not supplied, "(standard 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 currently possible only in Unix-like environments). Output to terminal is +normally automatically flushed by the operating system. 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 +performance, and the -M (multiline) option ceases to work. +

+

+--line-offsets +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 separately. This option is +mutually exclusive with --file-offsets and --only-matching. +

+

+--locale=locale-name +This option specifies a locale to be used for pattern matching. It overrides +the value in the LC_ALL or LC_CTYPE environment 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 program 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 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 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. +
+
+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, 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 settings 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 is given, patterns +may usefully contain literal newline characters 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 "multiline" 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 similarly +the previous 8K characters (or all the previous characters, 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 \fP--line-buffered\fP.) +

+

+-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 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 +(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 for the operating system. Unless +otherwise specified 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 to scan 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. Note that this option does not +apply to files specified by the -f, --exclude-from, or +--include-from options, which are expected to use the operating system's +standard newline sequence. +

+

+-n, --line-number +Precede each output line by its line number in the file, followed 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 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 +-C options are ignored. If there is more than one match in a line, each +of them is shown separately. If -o is combined with -v (invert the +sense of the match to find non-matching lines), no output is generated, but the +return code is set appropriately. If the matched portion of the line is empty, +nothing is output unless the file name or line number are being printed, in +which case they are shown on an otherwise empty line. This option is mutually +exclusive with --file-offsets and --line-offsets. +

+

+-onumber, --only-matching=number +Show only the part of the line that matched the capturing parentheses of the +given number. Up to 32 capturing parentheses are supported, and -o0 is +equivalent to -o without a number. Because these options can be given +without an argument (see above), if an argument is present, it must be given in +the same shell item, for example, -o3 or --only-matching=2. The comments given +for the non-argument case above also apply to this case. If the specified +capturing parentheses do not exist in the pattern, or were not set in the +match, nothing is output unless the file name or line number are being printed. +
+
+If this option is given multiple times, multiple substrings are output, in the +order the options are given. For example, -o3 -o1 -o3 causes the substrings +matched by capturing parentheses 3 and 1 and then 3 again to be output. By +default, there is no separator (but see the next option). +

+

+--om-separator=text +Specify a separating string for multiple occurrences of -o. The default +is an empty string. Separating strings are never coloured. +

+

+-q, --quiet +Work quietly, that is, display nothing except error messages. The exit +status indicates whether or not any matches were found. +

+

+-r, --recursive +If any given path is a directory, recursively scan the files it contains, +taking note of any --include and --exclude settings. By default, a +directory is read as a normal file; in some operating systems this gives an +immediate end-of-file. This option is a shorthand for setting the -d +option to "recurse". +

+

+--recursion-limit=number +See --match-limit above. +

+

+-s, --no-messages +Suppress error messages about non-existent or unreadable files. Such files are +quietly skipped. However, the return code is still 2, even if matches were +found in other files. +

+

+-u, --utf-8 +Operate in UTF-8 mode. This option is available only if PCRE has been compiled +with UTF-8 support. All patterns (including those for any --exclude and +--include options) and all subject lines that are scanned must be valid +strings of UTF-8 characters. +

+

+-V, --version +Write the version numbers of pcregrep and the PCRE library to the +standard output and then exit. Anything else on the command line is +ignored. +

+

+-v, --invert-match +Invert the sense of the match, so that lines which do not match any of +the patterns are the ones that are found. +

+

+-w, --word-regex, --word-regexp +Force the patterns to match only whole words. This is equivalent to having \b +at the start and end of the pattern. This option applies only to the patterns +that are matched against the contents of files; it does not apply to patterns +specified by any of the --include or --exclude options. +

+

+-x, --line-regex, --line-regexp +Force the patterns to be anchored (each must start matching at the beginning of +a line) and in addition, require them to match entire lines. This is equivalent +to having ^ and $ characters at the start and end of each alternative branch in +every pattern. This option applies only to the patterns that are matched +against the contents of files; it does not apply to patterns specified by any +of the --include or --exclude options. +

+
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
+

+The -N (--newline) option allows pcregrep to scan files with +different newline conventions from the default. Any parts of the input files +that are written to the standard output are copied identically, with whatever +newline sequences they have in the input. However, the setting of this option +does not affect the interpretation of files specified by the -f, +--exclude-from, or --include-from options, which are assumed to use +the operating system's standard newline sequence, nor does it affect the way in +which pcregrep writes informational messages to the standard error and +output streams. For these it uses the string "\n" to indicate newlines, +relying on the C I/O library to convert this to an appropriate sequence. +

+
OPTIONS COMPATIBILITY
+

+Many of the short and long forms of pcregrep's options are the same +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-list, --file-offsets, +--include-dir, --line-offsets, --locale, --match-limit, +-M, --multiline, -N, --newline, --om-separator, +--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 +pcregrep. For example, the --include option's argument is a glob +for GNU grep, but a regular expression for pcregrep. If both the +-c and -l options are given, GNU grep lists only file names, +without counts, but pcregrep gives the counts. +

+
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 +exception) in the next command line item. For example: +

+  -f/some/file
+  -f /some/file
+
+The exception is the -o option, which may appear with or without data. +Because of this, if data is present, it must follow immediately in the same +item, for example -o3. +

+

+If a long form option is used, the data may appear in the same command line +item, separated by an equals character, or (with two exceptions) it may appear +in the next command line item. For example: +

+  --file=/some/file
+  --file /some/file
+
+Note, however, that if you want to supply a file name beginning with ~ as data +in a shell command, and have the shell expand ~ to a home directory, you must +separate the file name from the option, because the shell does not treat ~ +specially unless it is at the start of an item. +

+

+The exceptions to the above are the --colour (or --color) and +--only-matching options, for which the data is optional. If one of these +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
+

+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 +repeats, for example: (a+)*\d when matched against a line of a's with no final +digit. The PCRE matching function has a resource limit that causes it to abort +in these circumstances. If this happens, pcregrep outputs an error +message and the line that caused the problem to the standard error stream. If +there are more than 20 such errors, pcregrep gives up. +

+

+The --match-limit option of pcregrep can be used to set the overall +resource limit; there is a second option called --recursion-limit that +sets a limit on the amount of memory (usually stack) that is used (see the +discussion of these options above). +

+
DIAGNOSTICS
+

+Exit status is 0 if any matches were found, 1 if no matches were found, 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 inaccessible files does not +affect the return code. +

+
SEE ALSO
+

+pcrepattern(3), pcresyntax(3), pcretest(1). +

+
AUTHOR
+

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

+
REVISION
+

+Last updated: 13 September 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcrejit.html b/tools/pcre/doc/html/pcrejit.html new file mode 100644 index 00000000..6286fccb --- /dev/null +++ b/tools/pcre/doc/html/pcrejit.html @@ -0,0 +1,458 @@ + + +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, 16-BIT AND 32-BIT SUPPORT
+

+JIT support is available for all of the 8-bit, 16-bit and 32-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). If you are using the 32-bit library, +substitute the 32-bit functions and 32-bit structures (for example, +pcre32_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
+  SPARC 32-bit (experimental)
+
+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 normal API is implemented +in a way that falls back to the interpretive code if JIT is not available. For +programs that need the best possible performance, there is also a "fast path" +API that is JIT-specific. +

+

+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_NO_UTF32_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 achieve 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);
+
+
+

+
JIT FAST PATH API
+

+Because the API described above falls back to interpreted execution when JIT is +not available, it is convenient for programs that are written for general use +in many environments. However, calling JIT via pcre_exec() does have a +performance impact. Programs that are written for use where JIT is known to be +available, and which need the best possible performance, can instead use a +"fast path" API to call JIT execution directly instead of calling +pcre_exec() (obviously only for patterns that have been successfully +studied by JIT). +

+

+The fast path function is called pcre_jit_exec(), and it takes exactly +the same arguments as pcre_exec(), plus one additional argument that +must point to a JIT stack. The JIT stack arrangements described above do not +apply. The return values are the same as for pcre_exec(). +

+

+When you call pcre_exec(), as well as testing for invalid options, a +number of other sanity checks are performed on the arguments. For example, if +the subject pointer is NULL, or its length is negative, an immediate error is +given. Also, unless PCRE_NO_UTF[8|16|32] is set, a UTF subject string is tested +for validity. In the interests of speed, these checks do not happen on the JIT +fast path, and if invalid data is passed, the result is undefined. +

+

+Bypassing the sanity checks and the pcre_exec() wrapping can give +speedups of more than 10%. +

+
SEE ALSO
+

+pcreapi(3) +

+
AUTHOR
+

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

+
REVISION
+

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

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcrelimits.html b/tools/pcre/doc/html/pcrelimits.html new file mode 100644 index 00000000..b83a8010 --- /dev/null +++ b/tools/pcre/doc/html/pcrelimits.html @@ -0,0 +1,86 @@ + + +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, 32-bit units for the 32-bit library, and 32-bit units for +the 32-bit library) if PCRE is compiled with the default internal linkage size +of 2 bytes. If you want to process regular expressions that are truly enormous, +you can compile PCRE with an internal linkage size of 3 or 4 (when building the +16-bit or 32-bit library, 3 is rounded up to 4). See the README file in +the source distribution and the +pcrebuild +documentation for details. In these cases the limit is substantially larger. +However, the speed of 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 and 32-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 --git a/tools/pcre/doc/html/pcrematching.html b/tools/pcre/doc/html/pcrematching.html new file mode 100644 index 00000000..f1854314 --- /dev/null +++ b/tools/pcre/doc/html/pcrematching.html @@ -0,0 +1,233 @@ + + +pcrematching specification + + +

pcrematching 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 MATCHING ALGORITHMS
+

+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(), +pcre16_exec() and pcre32_exec() functions. These work in the same +as 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(), +pcre16_dfa_exec() and pcre32_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 arises, however, +when there are multiple possibilities. For example, if the pattern +

+  ^<.*>
+
+is matched against the string +
+  <something> <something else> <something further>
+
+there are three possible answers. The standard algorithm finds only one of +them, whereas the alternative algorithm finds all three. +

+
REGULAR EXPRESSIONS AS TREES
+

+The set of strings that are matched by a regular expression can be represented +as a tree structure. An unlimited repetition in the pattern makes the tree of +infinite size, but it is still a tree. Matching the pattern to a given subject +string (from a given starting point) can be thought of as a search of the tree. +There are two ways to search a tree: depth-first and breadth-first, and these +correspond to the two matching algorithms provided by PCRE. +

+
THE STANDARD MATCHING ALGORITHM
+

+In the terminology of Jeffrey Friedl's book "Mastering Regular +Expressions", the standard algorithm is an "NFA algorithm". It conducts a +depth-first search of the pattern tree. That is, it proceeds along a single +path through the tree, checking that the subject matches what is required. When +there is a mismatch, the algorithm tries any alternatives at the current point, +and if they all fail, it backs up to the previous branch point in the tree, and +tries the next alternative branch at that level. This often involves backing up +(moving to the left) in the subject string as well. The order in which +repetition branches are tried is controlled by the greedy or ungreedy nature of +the quantifier. +

+

+If a leaf node is reached, a matching string has been found, and at that point +the algorithm stops. Thus, if there is more than one possible match, this +algorithm returns the first one that it finds. Whether this is the shortest, +the longest, or some intermediate length depends on the way the greedy and +ungreedy repetition quantifiers are specified in the pattern. +

+

+Because it ends up with a single path through the tree, it is relatively +straightforward for this algorithm to keep track of the substrings that are +matched by portions of the pattern in parentheses. This provides support for +capturing parentheses and back references. +

+
THE ALTERNATIVE MATCHING ALGORITHM
+

+This algorithm conducts a breadth-first search of the tree. Starting from the +first matching point in the subject, it scans the subject string from left to +right, once, character by character, and as it does this, it remembers all the +paths through the tree that represent valid matches. In Friedl's terminology, +this is a kind of "DFA algorithm", though it is not implemented as a +traditional finite state machine (it keeps multiple states active +simultaneously). +

+

+Although the general principle of this matching algorithm is that it scans the +subject string only once, without backtracking, there is one exception: when a +lookaround assertion is encountered, the characters following or preceding the +current point have to be independently inspected. +

+

+The scan continues until either the end of the subject is reached, or there are +no more unterminated paths. At this point, terminated paths represent the +different matching possibilities (if there are none, the match has failed). +Thus, if there is more than one possible match, this algorithm finds all of +them, and in particular, it finds the longest. The matches are returned in +decreasing order of length. There is an option to stop the algorithm after the +first match (which is necessarily the shortest) is found. +

+

+Note that all the matches that are found start at the same point in the +subject. If the pattern +

+  cat(er(pillar)?)?
+
+is matched against the string "the caterpillar catchment", the result will be +the three strings "caterpillar", "cater", and "cat" that start at the fifth +character of the subject. The algorithm does not automatically move on to find +matches that start at later positions. +

+

+There are a number of features of PCRE regular expressions that are not +supported by the alternative matching algorithm. They are as follows: +

+

+1. Because the algorithm finds all possible matches, the greedy or ungreedy +nature of repetition quantifiers is not relevant. Greedy and ungreedy +quantifiers are treated in exactly the same way. However, possessive +quantifiers can make a difference when what follows could also match what is +quantified, for example in a pattern like this: +

+  ^a++\w!
+
+This pattern matches "aaab!" but not "aaa!", which would be matched by a +non-possessive quantifier. Similarly, if an atomic group is present, it is +matched as if it were a standalone pattern at the current point, and the +longest match is then "locked in" for the rest of the overall pattern. +

+

+2. When dealing with multiple paths through the tree simultaneously, it is not +straightforward to keep track of captured substrings for the different matching +possibilities, and PCRE's implementation of this algorithm does not attempt to +do this. This means that no captured substrings are available. +

+

+3. Because no substrings are captured, back references within the pattern are +not supported, and cause errors if encountered. +

+

+4. For the same reason, conditional expressions that use a backreference as the +condition or test for a specific group recursion are not supported. +

+

+5. Because many paths through the tree may be active, the \K escape sequence, +which resets the start of the match when encountered (but may be on some paths +and not on others), is not supported. It causes an error if encountered. +

+

+6. Callouts are supported, but the value of the capture_top field is +always 1, and the value of the capture_last field is always -1. +

+

+7. The \C escape sequence, which (in the standard algorithm) always matches a +single data unit, even in UTF-8, UTF-16 or UTF-32 modes, is not supported in +these modes, because the alternative algorithm moves 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 negative assertion. +

+
ADVANTAGES OF THE ALTERNATIVE ALGORITHM
+

+Using the alternative matching algorithm provides the following advantages: +

+

+1. All possible matches (at a single point in the subject) are automatically +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 (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. +

+
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 because it is +less susceptible to optimization. +

+

+2. Capturing parentheses and back references are not supported. +

+

+3. Although atomic groups are supported, their use does not provide the +performance advantage that it does for the standard algorithm. +

+
AUTHOR
+

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

+
REVISION
+

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

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcrepartial.html b/tools/pcre/doc/html/pcrepartial.html new file mode 100644 index 00000000..298f92e0 --- /dev/null +++ b/tools/pcre/doc/html/pcrepartial.html @@ -0,0 +1,474 @@ + + +pcrepartial specification + + +

pcrepartial 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. +
+

+
PARTIAL MATCHING IN PCRE
+

+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 +for a field with specific formatting requirements. An example might be a date +in the form ddmmmyy, defined by this pattern: +

+  ^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$
+
+If the application sees the user's keystrokes one by one, and can check that +what has been typed so far is potentially valid, it is able to raise an error +as soon as a mistake is made, by beeping and not reflecting the character that +has been typed, for example. This immediate feedback is likely to be a better +user interface than a check that is delayed until the entire string has been +entered. Partial matching can also be useful when the subject string is very +long and is not all 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 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. +

+

+If you want to use partial matching with just-in-time optimized code, you must +call pcre_study(), pcre16_study() or pcre32_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 pcre[16|32]_exec()
+

+A partial match occurs during a call to pcre_exec() or +pcre[16|32]_exec() when the end of the subject string is reached 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 +partially matched string. However, for patterns that contain lookbehind +assertions, or \K, or begin with \b or \B, earlier characters have been +inspected while carrying out the match. For example: +

+  /(?<=abc)123/
+
+This pattern matches "123", but only if it is preceded by "abc". If the subject +string is "xyzabc12", the offsets after a partial match are for the substring +"abc12", because all these characters are needed if another match is tried +with extra characters added to the subject. +

+

+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() OR pcre[16|32]_exec() +
+

+If PCRE_PARTIAL_SOFT is set when pcre_exec() or pcre[16|32]_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. +All the various matching items in a pattern behave as if the subject string is +potentially complete. For example, \z, \Z, and $ match at the end of the +subject, as normal, and for \b and \B the end of the subject is treated as a +non-alphanumeric. +

+

+If there is more than one partial match, the first one that was found provides +the data that is returned. Consider this pattern: +

+  /123\w+X|dogY/
+
+If this is matched against the subject string "abc123dog", both +alternatives fail to match, but the end of the subject is reached during +matching, so PCRE_ERROR_PARTIAL is returned. The offsets are set to 3 and 9, +identifying "123dog" as the first partial match that was found. (In this +example, there are two partial matches, because "dog" on its own partially +matches the second alternative.) +

+
+PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre[16|32]_exec() +
+

+If PCRE_PARTIAL_HARD is set for pcre_exec() or pcre[16|32]_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. +

+
+Comparing hard and soft partial matching +
+

+The difference between the two partial matching options can be illustrated by a +pattern such as: +

+  /dog(sbody)?/
+
+This matches either "dog" or "dogsbody", greedily (that is, it prefers the +longer string if possible). If it is matched against the string "dog" with +PCRE_PARTIAL_SOFT, it yields a complete match for "dog". However, if +PCRE_PARTIAL_HARD is set, the result is PCRE_ERROR_PARTIAL. On the other hand, +if the pattern is made ungreedy the result is different: +
+  /dog(sbody)??/
+
+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", because it will always find the +shorter match first. +

+
PARTIAL MATCHING USING pcre_dfa_exec() OR pcre[16|32]_dfa_exec()
+

+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 +have been no complete matches. Otherwise, the complete matches are returned. +However, if PCRE_PARTIAL_HARD is set, a partial match takes precedence over any +complete matches. The portion of the string that was inspected when the longest +partial match was found is set as the first matching string, provided there are +at least two slots in the offsets vector. +

+

+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 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
+

+If a pattern ends with one of sequences \b or \B, which test for word +boundaries, partial matching with PCRE_PARTIAL_SOFT can give counter-intuitive +results. Consider this pattern: +

+  /\bcat\b/
+
+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, 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 can be requested for any pattern. +

+

+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 +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 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$/
+  data> 25jun04\P
+   0: 25jun04
+   1: jun
+  data> 25dec3\P
+  Partial match: 23dec3
+  data> 3ju\P
+  Partial match: 3ju
+  data> 3juj\P
+  No match
+  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 complete +pattern, but the first two are partial matches. Similar output is obtained +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() OR pcre[16|32]_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
+  Partial match: 23ja
+  data> n05\R\D
+   0: n05
+
+The first call has "23ja" as the subject, and requests partial matching; 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 the DFA matching +functions. +

+
MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre[16|32]_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. 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 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
+

+Certain types of pattern may give problems with multi-segment matching, +whichever matching function is used. +

+

+1. If the pattern contains a test for the beginning of a line, you need to pass +the PCRE_NOTBOL option when the subject string for any call does start at the +beginning of a line. There is also a PCRE_NOTEOL option, but in practice when +doing multi-segment matching you should be using PCRE_PARTIAL_HARD, which +includes the effect of PCRE_NOTEOL. +

+

+2. Lookbehind assertions that have already been obeyed are catered for 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 pcre[16|32]_fullinfo() functions to obtain the length +of the largest lookbehind in the pattern. This length is given in characters, +not bytes. If you always retain at least that many characters before the +partially matched string, all should be well. (Of course, near the 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 possible. Consider again this pcretest example: +

+    re> /dog(sbody)?/
+  data> dogsb\P
+   0: dog
+  data> do\P\D
+  Partial match: do
+  data> gsb\R\P\D
+   0: g
+  data> dogsbody\D
+   0: dogsbody
+   1: dog
+
+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 differently: +

+    re> /dog(sbody)?/
+  data> dogsb\P\P
+  Partial match: dogsb
+  data> do\P\D
+  Partial match: do
+  data> gsb\R\P\P\D
+  Partial match: gsb
+
+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
+
+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 such as: +
+  1234|ABCD
+
+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
+  Partial match: 123
+  data> 1237890
+   0: 3789
+
+Of course, instead of using PCRE_DFA_RESTART, the same technique of re-running +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 +the first buffer. +

+
AUTHOR
+

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

+
REVISION
+

+Last updated: 24 June 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcrepattern.html b/tools/pcre/doc/html/pcrepattern.html new file mode 100644 index 00000000..ee55d06e --- /dev/null +++ b/tools/pcre/doc/html/pcrepattern.html @@ -0,0 +1,2953 @@ + + +pcrepattern specification + + +

pcrepattern 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 REGULAR EXPRESSION DETAILS
+

+The syntax and semantics of the regular expressions that are supported by PCRE +are described in detail below. There is a quick-reference syntax summary in the +pcresyntax +page. PCRE tries to match Perl syntax and semantics as closely as it can. PCRE +also supports some alternative regular expression syntax (which does not +conflict with the Perl syntax) in order to provide some compatibility with +regular expressions in Python, .NET, and Oniguruma. +

+

+Perl's regular expressions are described in its own documentation, and +regular expressions in general are covered in a number of books, some of which +have copious examples. Jeffrey Friedl's "Mastering Regular Expressions", +published by O'Reilly, covers regular expressions in great detail. This +description of PCRE's regular expressions is intended as reference material. +

+

+The original operation of PCRE was on strings of one-byte characters. However, +there is now also support for UTF-8 strings in the original library, an +extra library that supports 16-bit and UTF-16 character strings, and a +third library that supports 32-bit and UTF-32 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, +PCRE_UTF16, or PCRE_UTF32 option, or the pattern must start with one of +these special sequences: +

+  (*UTF8)
+  (*UTF16)
+  (*UTF32)
+  (*UTF)
+
+(*UTF) is a generic sequence that can be used with any of the libraries. +Starting a pattern with such a sequence is equivalent to setting the relevant +option. This feature is not Perl-compatible. How setting a UTF mode affects +pattern matching is mentioned in several places below. There is also a summary +of features in the +pcreunicode +page. +

+

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

+  (*UCP)
+
+This has the same effect as setting the PCRE_UCP option: it causes sequences +such as \d and \w to use Unicode properties to determine character types, +instead of recognizing only characters with codes less than 128 via a lookup +table. +

+

+If a pattern starts with (*NO_START_OPT), it has the same effect as setting the +PCRE_NO_START_OPTIMIZE option either at compile or matching time. There are +also some more of these special sequences that are concerned with the handling +of newlines; they are described below. +

+

+The remainder of this document discusses the patterns that are supported by +PCRE when one its main matching functions, pcre_exec() (8-bit) or +pcre[16|32]_exec() (16- or 32-bit), is used. PCRE also has alternative +matching functions, pcre_dfa_exec() and pcre[16|32_dfa_exec(), +which match using a different algorithm that is not Perl-compatible. Some of +the features discussed below are not available when DFA matching is used. The +advantages and disadvantages of the alternative functions, and how they differ +from the normal functions, are discussed in the +pcrematching +page. +

+
EBCDIC CHARACTER CODES
+

+PCRE can be compiled to run in an environment that uses EBCDIC as its character +code rather than ASCII or Unicode (typically a mainframe system). In the +sections below, character code values are ASCII or Unicode; in an EBCDIC +environment these characters may have different code values, and there are no +code points greater than 255. +

+
NEWLINE CONVENTIONS
+

+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 +pcreapi +page has +further discussion +about newlines, and shows how to set the newline convention in the +options arguments for the compiling and matching functions. +

+

+It is also possible to specify a newline convention by starting a pattern +string with one of the following five sequences: +

+  (*CR)        carriage return
+  (*LF)        linefeed
+  (*CRLF)      carriage return, followed by linefeed
+  (*ANYCRLF)   any of the three above
+  (*ANY)       all Unicode newline sequences
+
+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
+
+changes the convention to CR. That pattern matches "a\nb" because LF is no +longer a newline. Note that these special settings, which are not +Perl-compatible, are recognized only at the very start of a pattern, and that +they must be in upper case. If more than one of them is present, the last one +is used. +

+

+The newline convention affects where the circumflex and dollar assertions are +true. It also affects the interpretation of the dot metacharacter when +PCRE_DOTALL is not set, and the behaviour of \N. However, it does not affect +what the \R escape sequence matches. By default, this is any Unicode newline +sequence, for Perl compatibility. However, this can be changed; see the +description of \R in the section entitled +"Newline sequences" +below. A change of \R setting can be combined with a change of newline +convention. +

+
CHARACTERS AND METACHARACTERS
+

+A regular expression is a pattern that is matched against a subject string from +left to right. Most characters stand for themselves in a pattern, and match the +corresponding characters in the subject. As a trivial example, the pattern +

+  The quick brown fox
+
+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 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 support. +

+

+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 +metacharacters, which do not stand for themselves but instead are +interpreted in some special way. +

+

+There are two different sets of metacharacters: those that are recognized +anywhere in the pattern except within square brackets, and those that are +recognized within square brackets. Outside square brackets, the metacharacters +are as follows: +

+  \      general escape character with several uses
+  ^      assert start of string (or line, in multiline mode)
+  $      assert end of string (or line, in multiline mode)
+  .      match any character except newline (by default)
+  [      start character class definition
+  |      start of alternative branch
+  (      start subpattern
+  )      end subpattern
+  ?      extends the meaning of (
+         also 0 or 1 quantifier
+         also quantifier minimizer
+  *      0 or more quantifier
+  +      1 or more quantifier
+         also "possessive quantifier"
+  {      start min/max quantifier
+
+Part of a pattern that is in square brackets is called a "character class". In +a character class the only metacharacters are: +
+  \      general escape character
+  ^      negate the class, but only if the first character
+  -      indicates character range
+  [      POSIX character class (only if followed by POSIX syntax)
+  ]      terminates the character class
+
+The following sections describe the use of each of the metacharacters. +

+
BACKSLASH
+

+The backslash character has several uses. Firstly, if it is followed by a +character that is not a number or a letter, it takes away any special meaning +that character may have. This use of backslash as an escape character applies +both inside and outside character classes. +

+

+For example, if you want to match a * character, you write \* in the pattern. +This escaping action applies whether or not the following character would +otherwise be interpreted as a metacharacter, so it is always safe to precede a +non-alphanumeric with backslash to specify that it stands for itself. In +particular, if you want to match a backslash, you write \\. +

+

+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, 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 white space or # character as part of the pattern. +

+

+If you want to remove the special meaning from a sequence of characters, you +can do so by putting them between \Q and \E. This is different from Perl in +that $ and @ are handled as literals in \Q...\E sequences in PCRE, whereas in +Perl, $ and @ cause variable interpolation. Note the following examples: +

+  Pattern            PCRE matches   Perl matches
+
+  \Qabc$xyz\E        abc$xyz        abc followed by the contents of $xyz
+  \Qabc\$xyz\E       abc\$xyz       abc\$xyz
+  \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. 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 +
+

+A second use of backslash provides a way of encoding non-printing characters +in patterns in a visible manner. There is no restriction on the appearance of +non-printing characters, apart from the binary zero that terminates a pattern, +but when a pattern is being prepared by text editing, it is often easier to use +one of the following escape sequences than the binary character it represents: +

+  \a        alarm, that is, the BEL character (hex 07)
+  \cx       "control-x", where x is any ASCII character
+  \e        escape (hex 1B)
+  \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.. (non-JavaScript mode)
+  \uhhhh    character with hex code hhhh (JavaScript mode only)
+
+The precise effect of \cx on ASCII characters 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 \cA to \cZ become hex 01 to hex 1A (A is 41, Z is 5A), +but \c{ becomes hex 3B ({ is 7B), and \c; becomes hex 7B (; is 3B). If the +data item (byte or 16-bit value) following \c has a value greater than 127, a +compile-time error occurs. This locks out non-ASCII characters in all modes. +

+

+The \c facility was designed for use with ASCII characters, but with the +extension to Unicode it is even less useful than it once was. It is, however, +recognized when PCRE is compiled in EBCDIC mode, where data items are always +bytes. In this mode, all values are valid after \c. If the next character is a +lower case letter, it is converted to upper case. Then the 0xc0 bits of the +byte are inverted. Thus \cA becomes hex 01, as in ASCII (A is C1), but because +the EBCDIC letters are disjoint, \cZ becomes hex 29 (Z is E9), and other +characters also generate different values. +

+

+By default, after \x, from zero to two hexadecimal digits are read (letters +can be in upper or lower case). Any number of hexadecimal 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
+  32-bit non-UTF mode   less than 0x80000000
+  32-bit UTF-32 mode    less than 0x10ffff and a valid codepoint
+
+Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called +"surrogate" codepoints), and 0xffef. +

+

+If characters other than hexadecimal digits appear between \x{ and }, or if +there is no terminating }, this form of escape is not recognized. Instead, the +initial \x will be interpreted as a basic hexadecimal escape, with no +following digits, giving a character whose value is zero. +

+

+If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \x is +as just described only when it is followed by two hexadecimal 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 (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 +digits, just those that are present are used. Thus the sequence \0\x\07 +specifies two binary zeros followed by a BEL character (code value 7). Make +sure you supply two digits after the initial zero if the pattern character that +follows is itself an octal digit. +

+

+The handling of a backslash followed by a digit other than 0 is complicated. +Outside a character class, PCRE reads it and any following digits as a decimal +number. If the number is less than 10, or if there have been at least that many +previous capturing left parentheses in the expression, the entire sequence is +taken as a back reference. A description of how this works is given +later, +following the discussion of +parenthesized subpatterns. +

+

+Inside a character class, or if the decimal number is greater than 9 and there +have not been that many capturing subpatterns, PCRE re-reads up to three octal +digits following the backslash, and uses them to generate a data character. Any +subsequent digits stand for themselves. The value of the character is +constrained in the same way as characters specified in hexadecimal. +For example: +

+  \040   is another way of writing an ASCII space
+  \40    is the same, provided there are fewer than 40 previous capturing subpatterns
+  \7     is always a back reference
+  \11    might be a back reference, or another way of writing a tab
+  \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 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 +zero, because no more than three octal digits are ever read. +

+

+All the sequences that define a single character value can be used both inside +and outside character classes. In addition, inside a character class, \b is +interpreted as the backspace character (hex 08). +

+

+\N is not allowed in a character class. \B, \R, and \X are not special +inside a character class. Like other unrecognized escape sequences, they are +treated as the literal characters "B", "R", and "X" by default, but cause an +error if the PCRE_EXTRA option is set. Outside a 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 +
+

+The sequence \g followed by an unsigned or a negative number, optionally +enclosed in braces, is an absolute or relative back reference. A named back +reference can be coded as \g{name}. Back references are discussed +later, +following the discussion of +parenthesized subpatterns. +

+
+Absolute and relative subroutine calls +
+

+For compatibility with Oniguruma, the non-Perl syntax \g followed by a name or +a number enclosed either in angle brackets or single quotes, is an alternative +syntax for referencing a subpattern as a "subroutine". Details are discussed +later. +Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not +synonymous. The former is a back reference; the latter is a +subroutine +call. +

+
+Generic character types +
+

+Another use of backslash is for specifying generic character types: +

+  \d     any decimal digit
+  \D     any character that is not a decimal digit
+  \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. 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 +of characters into two disjoint sets. Any given character matches one, and only +one, of each pair. The sequences can appear both inside and outside character +classes. They each match one character of the appropriate type. If the current +matching point is at the end of the subject string, all of them fail, because +there is no character to match. +

+

+For compatibility with Perl, \s does not match the VT character (code 11). +This makes it different from the the POSIX "space" class. The \s characters +are HT (9), LF (10), FF (12), CR (13), and space (32). If "use locale;" is +included in a Perl script, \s may match the VT character. In PCRE, it never +does. +

+

+A "word" character is an underscore or any character that is a letter or digit. +By default, the definition of letters and digits is controlled by PCRE's +low-valued character tables, and may vary if locale-specific matching is taking +place (see +"Locale support" +in the +pcreapi +page). For example, in a French locale such as "fr_FR" in Unix-like systems, +or "french" in Windows, some character codes greater than 128 are used for +accented letters, and these are then matched by \w. The use of locales with +Unicode is discouraged. +

+

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

+  \d  any character that \p{Nd} matches (decimal digit)
+  \s  any character that \p{Z} matches, plus HT, LF, FF, CR
+  \w  any character that \p{L} or \p{N} matches, plus underscore
+
+The upper case escapes match the inverse sets of characters. Note that \d +matches only decimal digits, whereas \w matches any Unicode digit, as well as +any Unicode letter, and underscore. Note also that PCRE_UCP affects \b, and +\B because they are defined in terms of \w and \W. Matching these sequences +is noticeably slower when PCRE_UCP is set. +

+

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

+  U+0009     Horizontal tab (HT)
+  U+0020     Space
+  U+00A0     Non-break space
+  U+1680     Ogham space mark
+  U+180E     Mongolian vowel separator
+  U+2000     En quad
+  U+2001     Em quad
+  U+2002     En space
+  U+2003     Em space
+  U+2004     Three-per-em space
+  U+2005     Four-per-em space
+  U+2006     Six-per-em space
+  U+2007     Figure space
+  U+2008     Punctuation space
+  U+2009     Thin space
+  U+200A     Hair space
+  U+202F     Narrow no-break space
+  U+205F     Medium mathematical space
+  U+3000     Ideographic space
+
+The vertical space characters are: +
+  U+000A     Linefeed (LF)
+  U+000B     Vertical tab (VT)
+  U+000C     Form feed (FF)
+  U+000D     Carriage return (CR)
+  U+0085     Next line (NEL)
+  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 8-bit non-UTF-8 mode \R is equivalent to the +following: +

+  (?>\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 (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 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. +

+

+It is possible to restrict \R to match only CR, LF, or CRLF (instead of the +complete set of Unicode line endings) by setting the option PCRE_BSR_ANYCRLF +either at compile time or when the pattern is matched. (BSR is an abbrevation +for "backslash R".) This can be made the default when PCRE is built; if this is +the case, the other behaviour can be requested via the PCRE_BSR_UNICODE option. +It is also possible to specify these settings by starting a pattern string with +one of the following sequences: +

+  (*BSR_ANYCRLF)   CR, LF, or CRLF only
+  (*BSR_UNICODE)   any Unicode newline sequence
+
+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), (*UTF16), (*UTF32), (*UTF) 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 additional +escape sequences that match characters with specific properties 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
+  \X       a Unicode extended grapheme cluster
+
+The property names represented by xx above are limited to the Unicode +script names, the general category properties, "Any", which matches any +character (including newline), and some special PCRE properties (described +in the +next section). +Other Perl properties such as "InMusicalSymbols" are not currently supported by +PCRE. Note that \P{Any} does not match any characters, so always causes a +match failure. +

+

+Sets of Unicode characters are defined as belonging to certain scripts. A +character from one of these sets can be matched using a script name. For +example: +

+  \p{Greek}
+  \P{Han}
+
+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, +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, +Hiragana, +Imperial_Aramaic, +Inherited, +Inscriptional_Pahlavi, +Inscriptional_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, +Samaritan, +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, specified by +a two-letter abbreviation. For compatibility with Perl, negation can be +specified by including a circumflex between the opening brace and the property +name. For example, \p{^Lu} is the same as \P{Lu}. +

+

+If only one letter is specified with \p or \P, it includes all the general +category properties that start with that letter. In this case, in the absence +of negation, the curly brackets in the escape sequence are optional; these two +examples have the same effect: +

+  \p{L}
+  \pL
+
+The following general category property codes are supported: +
+  C     Other
+  Cc    Control
+  Cf    Format
+  Cn    Unassigned
+  Co    Private use
+  Cs    Surrogate
+
+  L     Letter
+  Ll    Lower case letter
+  Lm    Modifier letter
+  Lo    Other letter
+  Lt    Title case letter
+  Lu    Upper case letter
+
+  M     Mark
+  Mc    Spacing mark
+  Me    Enclosing mark
+  Mn    Non-spacing mark
+
+  N     Number
+  Nd    Decimal number
+  Nl    Letter number
+  No    Other number
+
+  P     Punctuation
+  Pc    Connector punctuation
+  Pd    Dash punctuation
+  Pe    Close punctuation
+  Pf    Final punctuation
+  Pi    Initial punctuation
+  Po    Other punctuation
+  Ps    Open punctuation
+
+  S     Symbol
+  Sc    Currency symbol
+  Sk    Modifier symbol
+  Sm    Mathematical symbol
+  So    Other symbol
+
+  Z     Separator
+  Zl    Line separator
+  Zp    Paragraph separator
+  Zs    Space separator
+
+The special property L& is also supported: it matches a character that has +the Lu, Ll, or Lt property, in other words, a letter that is not 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 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, PCRE_NO_UTF16_CHECK and +PCRE_NO_UTF32_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 any of these +properties with "Is". +

+

+No character that is in the Unicode table has the Cn (unassigned) property. +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. For +example, \p{Lu} always matches only upper case letters. +

+

+Matching characters by Unicode property is not fast, because PCRE has to do a +multistage table lookup in order to find a character's property. That is why +the traditional escape sequences such as \d and \w do not use Unicode +properties in PCRE by default, though you can make them do so by setting the +PCRE_UCP option or by starting the pattern with (*UCP). +

+
+Extended grapheme clusters +
+

+The \X escape matches any number of Unicode characters that form an "extended +grapheme cluster", and treats the sequence as an atomic group +(see below). +Up to and including release 8.31, PCRE matched an earlier, simpler definition +that was equivalent to +

+  (?>\PM\pM*)
+
+That is, it matched a character without the "mark" property, followed by zero +or more characters with the "mark" property. Characters with the "mark" +property are typically non-spacing accents that affect the preceding character. +

+

+This simple definition was extended in Unicode to include more complicated +kinds of composite character by giving each character a grapheme breaking +property, and creating rules that use these properties to define the boundaries +of extended grapheme clusters. In releases of PCRE later than 8.31, \X matches +one of these clusters. +

+

+\X always matches at least one character. Then it decides whether to add +additional characters according to the following rules for ending a cluster: +

+

+1. End at the end of the subject string. +

+

+2. Do not end between CR and LF; otherwise end after any control character. +

+

+3. Do not break Hangul (a Korean script) syllable sequences. Hangul characters +are of five types: L, V, T, LV, and LVT. An L character may be followed by an +L, V, LV, or LVT character; an LV or V character may be followed by a V or T +character; an LVT or T character may be follwed only by a T character. +

+

+4. Do not end before extending characters or spacing marks. Characters with +the "mark" property always have the "extend" grapheme breaking property. +

+

+5. Do not end after prepend characters. +

+

+6. Otherwise, end the cluster. +

+
+PCRE's additional properties +
+

+As well as the standard Unicode properties described above, PCRE supports four +more that make it possible to convert traditional escape sequences such as \w +and \s and POSIX character classes to use Unicode properties. PCRE uses these +non-standard, non-Perl properties internally when PCRE_UCP is set. They are: +

+  Xan   Any alphanumeric character
+  Xps   Any POSIX space character
+  Xsp   Any Perl space character
+  Xwd   Any Perl "word" character
+
+Xan matches characters that have either the L (letter) or the N (number) +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 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, 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 assertions, but is +ignored in negative assertions. +

+
+Simple assertions +
+

+The final use of backslash is for certain simple assertions. An assertion +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
+  \B     matches when not at a word boundary
+  \A     matches at the start of the subject
+  \Z     matches at the end of the subject
+          also matches before a newline at the end of the subject
+  \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 character (for example, \B +matches the letter B). However, if the PCRE_EXTRA option is set, an "invalid +escape sequence" error is generated instead. +

+

+A word boundary is a position in the subject string where the current character +and the previous character do not both match \w or \W (i.e. one matches +\w and the other matches \W), or the start or end of the string if the +first or last character matches \w, respectively. In a UTF mode, the meanings +of \w and \W can be changed by setting the PCRE_UCP option. When this is +done, it also affects \b and \B. Neither PCRE nor Perl has a separate "start +of word" or "end of word" metasequence. 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 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 assertions 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, indicating 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 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 +arguments, you can mimic Perl's /g option, and it is in this kind of +implementation where \G can be useful. +

+

+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 at a time, it cannot +reproduce this behaviour. +

+

+If all the alternatives of a pattern begin with \G, the expression is anchored +to the starting match position, and the "anchored" flag is set in the compiled +regular expression. +

+
CIRCUMFLEX AND DOLLAR
+

+The circumflex and dollar metacharacters are zero-width assertions. That is, +they test for a particular condition being true without consuming any +characters from the subject string. +

+

+Outside a character class, in the default matching mode, the circumflex +character is an assertion that is true only if the current matching point is at +the start of the subject string. If the startoffset argument 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 subject, it is said to be an +"anchored" pattern. (There are also other constructs that can cause a pattern +to be anchored.) +

+

+The dollar character is an assertion that is true only if the current matching +point is at the end of the subject string, or immediately before a newline at +the end of the string (by default). Note, however, that it does not actually +match the newline. Dollar need not be the 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 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 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 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 set. +

+
FULL STOP (PERIOD, DOT) AND \N
+

+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. +

+

+When a line ending is defined as a single character, dot never matches that +character; when the two-character sequence CRLF is used, dot does not match CR +if it is immediately followed by LF, but otherwise it matches all characters +(including isolated CRs and LFs). When any Unicode line endings are being +recognized, dot does not match CR or LF or any of the other line ending +characters. +

+

+The behaviour of dot with regard to newlines can be changed. If the PCRE_DOTALL +option is set, a dot matches any one character, without exception. If the +two-character sequence CRLF is present in the subject string, it takes two dots +to match it. +

+

+The handling of dot is entirely independent of the handling of circumflex and +dollar, the only relationship being that they both involve newlines. Dot has no +special meaning in a character class. +

+

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

+
MATCHING A SINGLE DATA UNIT
+

+Outside a character class, the escape sequence \C matches any one data unit, +whether or not a UTF mode is set. In the 8-bit library, one data unit is one +byte; in the 16-bit library it is a 16-bit unit; in the 32-bit library it is +a 32-bit unit. Unlike a dot, \C always +matches line-ending characters. The feature is provided in Perl in order to +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, PCRE_NO_UTF16_CHECK or +PCRE_NO_UTF32_CHECK option is used). +

+

+PCRE does not allow \C to appear in lookbehind assertions +(described below) +in a UTF mode, because this would make it impossible to 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
+

+An opening square bracket introduces a character class, terminated by a closing +square bracket. A closing square bracket on its own is not special 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 present) or escaped with a backslash. +

+

+A character class matches a single character in the subject. In a UTF mode, the +character may be more than one data unit long. A matched 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. 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 consumes a character from the subject +string, and therefore it fails if the current pointer is at the end of the +string. +

+

+In UTF-8 (UTF-16, UTF-32) mode, characters with values greater than 255 (0xffff) +can be included in a class as a literal string of data units, 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 characters 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 character 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 interpreted 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]. 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 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, \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 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 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 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, 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 supports +this notation. For example, +

+  [01[:alpha:]%]
+
+matches "0", "1", any alphabetic character, or "%". The supported class names +are: +
+  alnum    letters and digits
+  alpha    letters
+  ascii    character codes 0 - 127
+  blank    space or tab only
+  cntrl    control characters
+  digit    decimal digits (same as \d)
+  graph    printing characters, excluding space
+  lower    lower case letters
+  print    printing characters, including space
+  punct    printing characters, excluding letters and digits and space
+  space    white space (not quite the same as \s)
+  upper    upper case letters
+  word     "word" characters (same as \w)
+  xdigit   hexadecimal digits
+
+The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), and +space (32). Notice that this list includes the VT character (code 11). This +makes "space" different to \s, which does not include VT (for Perl +compatibility). +

+

+The 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 POSIX +syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not +supported, and an error is given if they are encountered. +

+

+By default, in UTF modes, characters with values greater than 128 do not match +any of the POSIX character classes. However, if the PCRE_UCP option is passed +to pcre_compile(), some of the classes are changed so that Unicode +character properties are used. This is achieved by replacing the POSIX classes +by other sequences, as follows: +

+  [:alnum:]  becomes  \p{Xan}
+  [:alpha:]  becomes  \p{L}
+  [:blank:]  becomes  \h
+  [:digit:]  becomes  \p{Nd}
+  [:lower:]  becomes  \p{Ll}
+  [:space:]  becomes  \p{Xps}
+  [:upper:]  becomes  \p{Lu}
+  [:word:]   becomes  \p{Xwd}
+
+Negated versions, such as [:^alpha:] use \P instead of \p. The other POSIX +classes are unchanged, and match only characters with code points less than +128. +

+
VERTICAL BAR
+

+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 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 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 between "(?" and ")". +The option letters are +

+  i  for PCRE_CASELESS
+  m  for PCRE_MULTILINE
+  s  for PCRE_DOTALL
+  x  for PCRE_EXTENDED
+
+For example, (?im) sets caseless, multiline matching. It is also possible to +unset these options by preceding the letter with a hyphen, and a combined +setting and unsetting such as (?im-sx), which sets PCRE_CASELESS 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 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 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 therefore 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, 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 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 some very weird +behaviour otherwise. +

+

+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),(*UTF32), 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, PCRE_UTF32 and the PCRE_UCP +options, respectively. The (*UTF) sequence is a generic version that can be +used with any of the libraries. +

+
SUBPATTERNS
+

+Subpatterns are delimited by parentheses (round brackets), which can be nested. +Turning part of a pattern into a subpattern does two things: +
+
+1. It localizes a set of alternatives. For example, the pattern +

+  cat(aract|erpillar|)
+
+matches "cataract", "caterpillar", or "cat". Without the parentheses, it would +match "cataract", "erpillar" or an empty string. +
+
+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 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))
+
+the captured substrings are "red king", "red", and "king", and are numbered 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 capturing, 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))
+
+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 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 "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, consider this +pattern: +

+  (?|(Sat)ur|(Sun))day
+
+Because the two alternatives are inside a (?| group, both sets of capturing +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, parentheses 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 following example is taken from the Perl documentation. The +numbers underneath show in which buffer the captured content will be stored. +
+  # before  ---------------branch-reset----------- after
+  / ( 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 matches "abcabc" +or "defdef": +
+  /(?|(abc)|(def))\1/
+
+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 number have matched. +

+

+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 expressions. Furthermore, +if an expression is modified, the numbers may change. To help with this +difficulty, PCRE supports the naming of subpatterns. 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 syntax. 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: (?<name>...) or +(?'name'...) as in Perl, or (?P<name>...) 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 function calls for +extracting the name-to-number translation table from a compiled pattern. There +is also a convenience function for extracting a captured substring by name. +

+

+By default, a name must be unique within a pattern, but it is possible to relax +this constraint by setting the PCRE_DUPNAMES option at compile time. (Duplicate +names are also always permitted for subpatterns with the same number, set up as +described in the previous section.) Duplicate 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: +

+  (?<DN>Mon|Fri|Sun)(?:day)?|
+  (?<DN>Tue)(?:sday)?|
+  (?<DN>Wed)(?:nesday)?|
+  (?<DN>Thu)(?:rsday)?|
+  (?<DN>Sat)(?:urday)?
+
+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 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 occurrence of the name is +used. In the absence of duplicate numbers (see the previous section) this is +the one with the lowest number. If you use a named reference in a condition +test (see the +section about conditions +below), either to check whether a subpattern has matched, or to check for +recursion, all subpatterns with the same name are tested. If the condition is +true for any one of them, the overall condition is true. This is the same +behaviour as testing by number. For further details of the interfaces for +handling named subpatterns, see the +pcreapi +documentation. +

+

+Warning: You cannot use different names to distinguish between two +subpatterns with the same number because PCRE uses only the numbers when +matching. For this reason, an error is given at compile time if different 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 following +items: +

+  a literal data character
+  the dot metacharacter
+  the \C escape sequence
+  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 (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), +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. Thus +
+  [aeiou]{3,}
+
+matches at least 3 successive vowels, but may match many more, while +
+  \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 example, {,6} is not a +quantifier, but a literal string of four characters. +

+

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

+

+The quantifier {0} is permitted, causing the expression to behave as if the +previous item and the quantifier were not present. This may be useful for +subpatterns that are referenced as +subroutines +from elsewhere in the pattern (but see also the section entitled +"Defining subpatterns for use by reference only" +below). Items other than subpatterns that have a {0} quantifier are omitted +from the compiled pattern. +

+

+For convenience, the three most common quantifiers have single-character +abbreviations: +

+  *    is equivalent to {0,}
+  +    is equivalent to {1,}
+  ?    is equivalent to {0,1}
+
+It is possible to construct infinite loops by following a subpattern that can +match no characters with a quantifier that has no upper limit, for example: +
+  (a?)*
+
+Earlier versions of Perl and PCRE used to give an error at compile time for +such patterns. However, because there are cases where this can be useful, such +patterns are now accepted, but if any repetition of the subpattern does in fact +match no characters, the loop is forcibly broken. +

+

+By default, the quantifiers are "greedy", that is, they match as much as +possible (up to the maximum number of permitted times), without causing the +rest of the pattern to fail. The classic example of where this gives problems +is in trying to match comments in C programs. These appear between /* and */ +and within the comment, individual * and / characters may appear. An attempt to +match C comments by applying the pattern +

+  /\*.*\*/
+
+to the string +
+  /* first comment */  not comment  /* second comment */
+
+fails, because it matches the entire string owing to the greediness of the .* +item. +

+

+However, if a quantifier is followed by a question mark, it ceases to be +greedy, and instead matches the minimum number of times possible, so the +pattern +

+  /\*.*?\*/
+
+does the right thing with the C comments. The meaning of the various +quantifiers is not otherwise changed, just the preferred number of matches. +Do not confuse this use of question mark with its use as a quantifier in its +own right. Because it has two uses, it can sometimes appear doubled, as in +
+  \d??\d
+
+which matches one digit by preference, but can match two if that is the only +way the rest of the pattern matches. +

+

+If the PCRE_UNGREEDY option is set (an option that is not available in Perl), +the quantifiers are not greedy by default, but individual ones can be made +greedy by following them with a question mark. In other words, it inverts the +default behaviour. +

+

+When a parenthesized subpattern is quantified with a minimum repeat count that +is greater than 1 or with a limited maximum, more memory is required for the +compiled pattern, in proportion to the size of the minimum or maximum. +

+

+If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equivalent +to Perl's /s) is set, thus allowing the dot to match newlines, the pattern is +implicitly anchored, because whatever follows will be tried against every +character position in the subject string, so there is no point in retrying the +overall match at any position after the first. PCRE normally treats such a +pattern as though it were preceded by \A. +

+

+In cases where it is known that the subject string contains no newlines, it is +worth setting PCRE_DOTALL in order to obtain this optimization, or +alternatively using ^ to indicate anchoring explicitly. +

+

+However, there are some cases where the optimization cannot be used. When .* +is inside capturing parentheses that are the subject of a back reference +elsewhere in the pattern, a match at the start may fail where a later one +succeeds. Consider, for example: +

+  (.*)abc\1
+
+If the subject is "xyz123abc123" the match point is the fourth character. For +this reason, such a pattern is not implicitly anchored. +

+

+Another case where implicit anchoring is not applied is when the leading .* is +inside an atomic group. Once again, a match at the start may fail where a later +one succeeds. Consider this pattern: +

+  (?>.*?a)b
+
+It matches "ab" in the subject "aab". The use of the backtracking control verbs +(*PRUNE) and (*SKIP) also disable this optimization. +

+

+When a capturing subpattern is repeated, the value captured is the substring +that matched the final iteration. For example, after +

+  (tweedle[dume]{3}\s*)+
+
+has matched "tweedledum tweedledee" the value of the captured substring is +"tweedledee". However, if there are nested capturing subpatterns, the +corresponding captured values may have been set in previous iterations. For +example, after +
+  /(a|(b))+/
+
+matches "aba" the value of the second captured substring is "b". +

+
ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
+

+With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy") +repetition, failure of what follows normally causes the repeated item to be +re-evaluated to see if a different number of repeats allows the rest of the +pattern to match. Sometimes it is useful to prevent this, either to change the +nature of the match, or to cause it fail earlier than it otherwise might, when +the author of the pattern knows there is no point in carrying on. +

+

+Consider, for example, the pattern \d+foo when applied to the subject line +

+  123456bar
+
+After matching all 6 digits and then failing to match "foo", the normal +action of the matcher is to try again with only 5 digits matching the \d+ +item, and then with 4, and so on, before ultimately failing. "Atomic grouping" +(a term taken from Jeffrey Friedl's book) provides the means for specifying +that once a subpattern has matched, it is not to be re-evaluated in this way. +

+

+If we use atomic grouping for the previous example, the matcher gives up +immediately on failing to match "foo" the first time. The notation is a kind of +special parenthesis, starting with (?> as in this example: +

+  (?>\d+)foo
+
+This kind of parenthesis "locks up" the part of the pattern it contains once +it has matched, and a failure further into the pattern is prevented from +backtracking into it. Backtracking past it to previous items, however, works as +normal. +

+

+An alternative description is that a subpattern of this type matches the string +of characters that an identical standalone pattern would match, if anchored at +the current point in the subject string. +

+

+Atomic grouping subpatterns are not capturing subpatterns. Simple cases such as +the above example can be thought of as a maximizing repeat that must swallow +everything it can. So, while both \d+ and \d+? are prepared to adjust the +number of digits they match in order to make the rest of the pattern match, +(?>\d+) can only match an entire sequence of digits. +

+

+Atomic groups in general can of course contain arbitrarily complicated +subpatterns, and can be nested. However, when the subpattern for an atomic +group is just a single repeated item, as in the example above, a simpler +notation, called a "possessive quantifier" can be used. This consists of an +additional + character following a quantifier. Using this notation, the +previous example can be rewritten as +

+  \d++foo
+
+Note that a possessive quantifier can be used with an entire group, for +example: +
+  (abc|xyz){2,3}+
+
+Possessive quantifiers are always greedy; the setting of the PCRE_UNGREEDY +option is ignored. They are a convenient notation for the simpler forms of +atomic group. However, there is no difference in the meaning of a possessive +quantifier and the equivalent atomic group, though there may be a performance +difference; possessive quantifiers should be slightly faster. +

+

+The possessive quantifier syntax is an extension to the Perl 5.8 syntax. +Jeffrey Friedl originated the idea (and the name) in the first edition of his +book. Mike McCloskey liked it, so implemented it when he built Sun's Java +package, and PCRE copied it from there. It ultimately found its way into Perl +at release 5.10. +

+

+PCRE has an optimization that automatically "possessifies" certain simple +pattern constructs. For example, the sequence A+B is treated as A++B because +there is no point in backtracking into a sequence of A's when B must follow. +

+

+When a pattern contains an unlimited repeat inside a subpattern that can itself +be repeated an unlimited number of times, the use of an atomic group is the +only way to avoid some failing matches taking a very long time indeed. The +pattern +

+  (\D+|<\d+>)*[!?]
+
+matches an unlimited number of substrings that either consist of non-digits, or +digits enclosed in <>, followed by either ! or ?. When it matches, it runs +quickly. However, if it is applied to +
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+it takes a long time before reporting failure. This is because the string can +be divided between the internal \D+ repeat and the external * repeat in a +large number of ways, and all have to be tried. (The example uses [!?] rather +than a single character at the end, because both PCRE and Perl have an +optimization that allows for fast failure when a single character is used. They +remember the last single character that is required for a match, and fail early +if it is not present in the string.) If the pattern is changed so that it uses +an atomic group, like this: +
+  ((?>\D+)|<\d+>)*[!?]
+
+sequences of non-digits cannot be broken, and failure happens quickly. +

+
BACK REFERENCES
+

+Outside a character class, a backslash followed by a digit greater than 0 (and +possibly further digits) is a back reference to a capturing subpattern earlier +(that is, to its left) in the pattern, provided there have been that many +previous capturing left parentheses. +

+

+However, if the decimal number following the backslash is less than 10, it is +always taken as a back reference, and causes an error only if there are not +that many capturing left parentheses in the entire pattern. In other words, the +parentheses that are referenced need not be to the left of the reference for +numbers less than 10. A "forward back reference" of this type can make sense +when a repetition is involved and the subpattern to the right has participated +in an earlier iteration. +

+

+It is not possible to have a numerical "forward back reference" to a subpattern +whose number is 10 or more using this syntax because a sequence such as \50 is +interpreted as a character defined in octal. See the subsection entitled +"Non-printing characters" +above +for further details of the handling of digits following a backslash. There is +no such problem when named parentheses are used. A back reference to any +subpattern is possible using named parentheses (see below). +

+

+Another way of avoiding the ambiguity inherent in the use of digits following a +backslash is to use the \g escape sequence. This escape must be followed by an +unsigned number or a negative number, optionally enclosed in braces. These +examples are all identical: +

+  (ring), \1
+  (ring), \g1
+  (ring), \g{1}
+
+An unsigned number specifies an absolute reference without the ambiguity that +is present in the older syntax. It is also useful when literal digits follow +the reference. A negative number is a relative reference. Consider this +example: +
+  (abc(def)ghi)\g{-1}
+
+The sequence \g{-1} is a reference to the most recently started capturing +subpattern before \g, that is, is it equivalent to \2 in this example. +Similarly, \g{-2} would be equivalent to \1. The use of relative references +can be helpful in long patterns, and also in patterns that are created by +joining together fragments that contain references within themselves. +

+

+A back reference matches whatever actually matched the capturing subpattern in +the current subject string, rather than anything matching the subpattern +itself (see +"Subpatterns as subroutines" +below for a way of doing that). So the pattern +

+  (sens|respons)e and \1ibility
+
+matches "sense and sensibility" and "response and responsibility", but not +"sense and responsibility". If caseful matching is in force at the time of the +back reference, the case of letters is relevant. For example, +
+  ((?i)rah)\s+\1
+
+matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original +capturing subpattern is matched caselessly. +

+

+There are several different ways of writing back references to named +subpatterns. The .NET syntax \k{name} and the Perl syntax \k<name> or +\k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's unified +back reference syntax, in which \g can be used for both numeric and named +references, is also supported. We could rewrite the above example in any of +the following ways: +

+  (?<p1>(?i)rah)\s+\k<p1>
+  (?'p1'(?i)rah)\s+\k{p1}
+  (?P<p1>(?i)rah)\s+(?P=p1)
+  (?<p1>(?i)rah)\s+\g{p1}
+
+A subpattern that is referenced by name may appear in the pattern before or +after the reference. +

+

+There may be more than one back reference to the same subpattern. If a +subpattern has not actually been used in a particular match, any back +references to it always fail by default. For example, the pattern +

+  (a|(bc))\2
+
+always fails if it starts to match "a" rather than "bc". However, if the +PCRE_JAVASCRIPT_COMPAT option is set at compile time, a back reference to an +unset value matches an empty string. +

+

+Because there may be many capturing parentheses in a pattern, all digits +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 +white space. Otherwise, the \g{ syntax or an empty comment (see +"Comments" +below) can be used. +

+
+Recursive back references +
+

+A back reference that occurs inside the parentheses to which it refers fails +when the subpattern is first used, so, for example, (a\1) never matches. +However, such references can be useful inside repeated subpatterns. For +example, the pattern +

+  (a|b\1)+
+
+matches any number of "a"s and also "aba", "ababbaa" etc. At each iteration of +the subpattern, the back reference matches the character string corresponding +to the previous iteration. In order for this to work, the pattern must be such +that the first iteration does not need to match the back reference. This can be +done using alternation, as in the example above, or by a quantifier with a +minimum of zero. +

+

+Back references of this type cause the group that they reference to be treated +as an +atomic group. +Once the whole group has been matched, a subsequent matching failure cannot +cause backtracking into the middle of the group. +

+
ASSERTIONS
+

+An assertion is a test on the characters following or preceding the current +matching point that does not actually consume any characters. The simple +assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are described +above. +

+

+More complicated assertions are coded as subpatterns. There are two kinds: +those that look ahead of the current position in the subject string, and those +that look behind it. An assertion subpattern is matched in the normal way, +except that it does not cause the current matching position to be changed. +

+

+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 +
+

+Lookahead assertions start with (?= for positive assertions and (?! for +negative assertions. For example, +

+  \w+(?=;)
+
+matches a word followed by a semicolon, but does not include the semicolon in +the match, and +
+  foo(?!bar)
+
+matches any occurrence of "foo" that is not followed by "bar". Note that the +apparently similar pattern +
+  (?!foo)bar
+
+does not find an occurrence of "bar" that is preceded by something other than +"foo"; it finds any occurrence of "bar" whatsoever, because the assertion +(?!foo) is always true when the next three characters are "bar". A +lookbehind assertion is needed to achieve the other effect. +

+

+If you want to force a matching failure at some point in a pattern, the most +convenient way to do it is with (?!) because an empty string always matches, so +an assertion that requires there not to be an empty string must always fail. +The backtracking control verb (*FAIL) or (*F) is a synonym for (?!). +

+
+Lookbehind assertions +
+

+Lookbehind assertions start with (?<= for positive assertions and (?<! for +negative assertions. For example, +

+  (?<!foo)bar
+
+does find an occurrence of "bar" that is not preceded by "foo". The contents of +a lookbehind assertion are restricted such that all the strings it matches must +have a fixed length. However, if there are several top-level alternatives, they +do not all have to have the same fixed length. Thus +
+  (?<=bullock|donkey)
+
+is permitted, but +
+  (?<!dogs?|cats?)
+
+causes an error at compile time. Branches that match different length strings +are permitted only at the top level of a lookbehind assertion. This is an +extension compared with Perl, which requires all branches to match the same +length of string. An assertion such as +
+  (?<=ab(c|de))
+
+is not permitted, because its single top-level branch can match two different +lengths, but it is acceptable to PCRE if rewritten to use two top-level +branches: +
+  (?<=abc|abde)
+
+In some cases, the escape sequence \K +(see above) +can be used instead of a lookbehind assertion to get round the fixed-length +restriction. +

+

+The implementation of lookbehind assertions is, for each alternative, to +temporarily move the current position back by the fixed length and then try to +match. If there are insufficient characters before the current position, the +assertion fails. +

+

+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" +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 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 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 pattern is specified as +
+  ^.*abcd$
+
+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, 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 processing time. +

+
+Using multiple assertions +
+

+Several assertions (of any sort) may occur in succession. For example, +

+  (?<=\d{3})(?<!999)foo
+
+matches "foo" preceded by three digits that are not "999". Notice that each of +the assertions is applied independently at the same point in the subject +string. First there is a check that the previous three characters are all +digits, and then there is a check that the same three characters are not "999". +This pattern does not match "foo" preceded by six characters, the first +of which are digits and the last three of which are not "999". For example, it +doesn't match "123abcfoo". A pattern to do that is +
+  (?<=\d{3}...)(?<!999)foo
+
+This time the first assertion looks at the preceding six characters, checking +that the first three are digits, and then the second assertion checks that the +preceding three characters are not "999". +

+

+Assertions can be nested in any combination. For example, +

+  (?<=(?<!foo)bar)baz
+
+matches an occurrence of "baz" that is preceded by "bar" which in turn is not +preceded by "foo", while +
+  (?<=\d{3}(?!999)...)foo
+
+is another pattern that matches "foo" preceded by three digits and any three +characters that are not "999". +

+
CONDITIONAL SUBPATTERNS
+

+It is possible to cause the matching process to obey a subpattern +conditionally or to choose between two alternative subpatterns, depending on +the result of an assertion, or whether a specific capturing subpattern has +already been matched. The two possible forms of conditional subpattern are: +

+  (?(condition)yes-pattern)
+  (?(condition)yes-pattern|no-pattern)
+
+If the condition is satisfied, the yes-pattern is used; otherwise the +no-pattern (if present) is used. If there are more than two alternatives in the +subpattern, a compile-time error occurs. Each of the two alternatives may +itself contain nested subpatterns of any form, including conditional +subpatterns; the restriction to two alternatives applies only at the level of +the condition. This pattern fragment is an example where the alternatives are +complex: +
+  (?(1) (A|B|C) | (D | (?(2)E|F) | E) )
+
+
+

+

+There are four kinds of condition: references to subpatterns, references to +recursion, a pseudo-condition called DEFINE, and assertions. +

+
+Checking for a used subpattern by number +
+

+If the text between the parentheses consists of a sequence of digits, the +condition is true if a capturing subpattern of that number has previously +matched. If there is more than one capturing subpattern with the same number +(see the earlier +section about duplicate subpattern numbers), +the condition is true if any of them have matched. An alternative notation is +to precede the digits with a plus or minus sign. In this case, the subpattern +number is relative rather than absolute. The most recently opened parentheses +can be referenced by (?(-1), the next most recent by (?(-2), and so on. Inside +loops it can also make sense to refer to subsequent groups. The next +parentheses to be opened can be referenced as (?(+1), and so on. (The value +zero in any of these forms is not used; it provokes a compile-time error.) +

+

+Consider the following pattern, which contains non-significant white space to +make it more readable (assume the PCRE_EXTENDED option) and to divide it into +three parts for ease of discussion: +

+  ( \( )?    [^()]+    (?(1) \) )
+
+The first part matches an optional opening parenthesis, and if that +character is present, sets it as the first captured substring. The second part +matches one or more characters that are not parentheses. The third part is a +conditional subpattern that tests whether or not the first set of parentheses +matched. If they did, that is, if subject started with an opening parenthesis, +the condition is true, and so the yes-pattern is executed and a closing +parenthesis is required. Otherwise, since no-pattern is not present, the +subpattern matches nothing. In other words, this pattern matches a sequence of +non-parentheses, optionally enclosed in parentheses. +

+

+If you were embedding this pattern in a larger one, you could use a relative +reference: +

+  ...other stuff... ( \( )?    [^()]+    (?(-1) \) ) ...
+
+This makes the fragment independent of the parentheses in the larger pattern. +

+
+Checking for a used subpattern by name +
+

+Perl uses the syntax (?(<name>)...) or (?('name')...) to test for a used +subpattern by name. For compatibility with earlier versions of PCRE, which had +this facility before Perl, the syntax (?(name)...) is also recognized. However, +there is a possible ambiguity with this syntax, 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 number, which must be greater than zero. Using subpattern +names that consist entirely of digits is not recommended. +

+

+Rewriting the above example to use a named subpattern gives this: +

+  (?<OPEN> \( )?    [^()]+    (?(<OPEN>) \) )
+
+If the name used in a condition of this kind is a duplicate, the test is +applied to all subpatterns of the same name, and is true if any one 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 or any +subpattern has been made. If digits or a name preceded by ampersand follow the +letter R, for example: +

+  (?(R3)...) or (?(R&name)...)
+
+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 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 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 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 white space and line +breaks): +

+  (?(DEFINE) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
+  \b (?&byte) (\.(?&byte)){3} \b
+
+The first part of the pattern is a DEFINE group inside which a another group +named "byte" is defined. This matches an individual component of an IPv4 +address (a number less than 256). When matching takes place, this part of the +pattern is skipped because DEFINE acts like a false condition. The rest of the +pattern uses references to the named group to match the four dot-separated +components of an IPv4 address, insisting on a word boundary at each end. +

+
+Assertion conditions +
+

+If the condition is not in any of the above formats, it must be an assertion. +This may be a positive or negative lookahead or lookbehind assertion. Consider +this pattern, again containing non-significant white space, and with the two +alternatives on the second line: +

+  (?(?=[^a-z]*[a-z])
+  \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )
+
+The condition is a positive lookahead assertion that matches an optional +sequence of non-letters followed by a letter. In other words, it tests for the +presence of at least one letter in the subject. If a letter is found, the +subject is matched against the first alternative; otherwise it is matched +against the second. This pattern matches strings in one of the two forms +dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits. +

+
COMMENTS
+

+There are two ways of including comments in patterns that are processed by +PCRE. In both cases, the start of the comment must not be in a character class, +nor in the middle of any other sequence of related characters such as (?: or a +subpattern name or number. The characters that make up a comment play no part +in the pattern matching. +

+

+The sequence (?# marks the start of a comment that continues up to the next +closing parenthesis. Nested parentheses are not permitted. If the PCRE_EXTENDED +option is set, an unescaped # character also introduces a comment, which in +this case continues to immediately after the next newline character or +character sequence in the pattern. Which characters are interpreted as newlines +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 +in the pattern; escape sequences that happen to represent a newline do not +count. For example, consider this pattern when PCRE_EXTENDED is set, and the +default newline convention is in force: +

+  abc #comment \n still comment
+
+On encountering the # character, pcre_compile() skips along, looking for +a newline in the pattern. The sequence \n is still literal at this stage, so +it does not terminate the comment. Only an actual character with the code value +0x0a (the default newline) does so. +

+
RECURSIVE PATTERNS
+

+Consider the problem of matching a string in parentheses, allowing for +unlimited nested parentheses. Without the use of recursion, the best that can +be done is to use a pattern that matches up to some fixed depth of nesting. It +is not possible to handle an arbitrary nesting depth. +

+

+For some time, Perl has provided a facility that allows regular expressions to +recurse (amongst other things). It does this by interpolating Perl code in the +expression at run time, and the code can refer to the expression itself. A Perl +pattern using code interpolation to solve the parentheses problem can be +created like this: +

+  $re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x;
+
+The (?p{...}) item interpolates Perl code at run time, and in this case refers +recursively to the pattern in which it appears. +

+

+Obviously, PCRE cannot support the interpolation of Perl code. Instead, it +supports special syntax for recursion of the entire pattern, and also for +individual subpattern recursion. After its introduction in PCRE and Python, +this kind of recursion was subsequently introduced into Perl at release 5.10. +

+

+A special item that consists of (? followed by a number greater than zero and a +closing parenthesis is a recursive subroutine call of the subpattern of the +given number, provided that it occurs inside that subpattern. (If not, it is a +non-recursive subroutine +call, which is described in the next section.) The special item (?R) or (?0) is +a 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): +

+  \( ( [^()]++ | (?R) )* \)
+
+First it matches an opening parenthesis. Then it matches any number of +substrings which can either be a sequence of non-parentheses, or a recursive +match of the pattern itself (that is, a correctly parenthesized substring). +Finally there is a closing parenthesis. Note the use of a possessive quantifier +to avoid backtracking into sequences of non-parentheses. +

+

+If this were part of a larger pattern, you would not want to recurse the entire +pattern, so instead you could use this: +

+  ( \( ( [^()]++ | (?1) )* \) )
+
+We have put the pattern into parentheses, and caused the recursion to refer to +them instead of the whole pattern. +

+

+In a larger pattern, keeping track of parenthesis numbers can be tricky. This +is made easier by the use of relative references. Instead of (?1) in the +pattern above you can write (?-2) to refer to the second most recently opened +parentheses preceding the recursion. In other words, a negative number counts +capturing parentheses leftwards from the point at which it is encountered. +

+

+It is also possible to refer to subsequently opened parentheses, by writing +references such as (?+2). However, these cannot be recursive because the +reference is not inside the parentheses that are referenced. 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 supported. We +could rewrite the above example as follows: +

+  (?<pn> \( ( [^()]++ | (?&pn) )* \) )
+
+If there is more than one subpattern with the same name, the earliest one is +used. +

+

+This particular example pattern that we have been looking at contains nested +unlimited repeats, and so the use of a possessive quantifier for matching +strings of non-parentheses is important when applying the pattern to strings +that do not match. For example, when this pattern is applied to +

+  (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
+
+it yields "no match" quickly. However, if a possessive quantifier is not used, +the match runs for a very long time indeed because there are so many different +ways the + and * repeats can carve up the subject, and all have to be tested +before failure can be reported. +

+

+At the end of a match, the values of capturing parentheses are those from +the outermost level. If you want to obtain intermediate values, a callout +function can be used (see below and the +pcrecallout +documentation). If the pattern above is matched against +

+  (ab(cd)ef)
+
+the value for the inner capturing parentheses (numbered 2) is "ef", which is +the last value taken on at the top level. If a capturing subpattern 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 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 brackets, allowing for +arbitrary nesting. Only digits are allowed in nested brackets (that is, when +recursing), whereas any characters are permitted 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. The (?R) item +is the actual recursive call. +

+
+Differences in recursion processing between PCRE and Perl +
+

+Recursion processing in PCRE differs from Perl in two important ways. In PCRE +(like Python, but unlike Perl), a recursive subpattern call is 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)$
+
+The idea is that it either matches a single character, or two identical +characters surrounding a sub-palindrome. In Perl, this pattern works; in PCRE +it does not if the pattern is longer than three characters. Consider the +subject string "abcba": +

+

+At the top level, the first character is matched, but as it is not at the end +of the string, the first alternative fails; the second alternative is taken +and the recursion kicks in. The recursive call to subpattern 1 successfully +matches the next character ("b"). (Note that the beginning and end of line +tests are not part of the recursion). +

+

+Back at the top level, the next character ("c") is compared with what +subpattern 2 matched, which was "a". This fails. Because the recursion is +treated as an atomic group, there are now no backtracking points, and so the +entire match fails. (Perl is able, at this point, to re-enter the recursion and +try the second alternative.) However, if the pattern is written with the +alternatives in the other order, things are different: +

+  ^((.)(?1)\2|.)$
+
+This time, the recursing alternative is tried first, and continues to recurse +until it runs out of characters, at which point the recursion fails. But this +time we do have another alternative to try at the higher level. That is the big +difference: in the previous case the remaining alternative is at a deeper +recursion level, which PCRE cannot use. +

+

+To change the pattern so that it matches all palindromic strings, not just +those with an odd number of characters, it is tempting to change the pattern to +this: +

+  ^((.)(?1)\2|.?)$
+
+Again, this works in Perl, but not in PCRE, and for the same reason. When a +deeper recursion has matched a single character, it cannot be entered again in +order to match an empty string. The solution is to separate the two cases, and +write out the odd and even cases as alternatives at the higher level: +
+  ^(?:((.)(?1)\2|)|((.)(?3)\4|.))
+
+If you want to match typical palindromic phrases, the pattern has to ignore all +non-word characters, which can be done like this: +
+  ^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$
+
+If run with the PCRE_CASELESS option, this pattern matches phrases such as "A +man, a plan, a canal: Panama!" and it works well in both PCRE and Perl. Note +the use of the possessive quantifier *+ to avoid backtracking into sequences of +non-word characters. Without this, PCRE takes a great deal longer (ten times or +more) to match typical phrases, and Perl takes so long that you think it has +gone into a loop. +

+

+WARNING: The palindrome-matching patterns above work only if the subject +string does not start with a palindrome that is shorter than the entire string. +For example, although "abcba" is correctly matched, if the subject is "ababa", +PCRE finds the palindrome "aba" at the start, then fails at top level because +the end of the string does not follow. Once again, it cannot jump back into the +recursion to try other 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 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)...
+  (...(?+1)...(relative)...
+
+An earlier example pointed out that the pattern +
+  (sens|respons)e and \1ibility
+
+matches "sense and sensibility" and "response and responsibility", but not +"sense and responsibility". If instead the pattern +
+  (sens|respons)e and (?1)ibility
+
+is used, it does match "sense and responsibility" as well as the other two +strings. Another example is given in the discussion of DEFINE above. +

+

+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. +

+

+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))
+
+It matches "abcabc". It does not match "abcABC" because the change of +processing option does not affect the called subpattern. +

+
ONIGURUMA SUBROUTINE SYNTAX
+

+For compatibility with Oniguruma, the non-Perl syntax \g followed by a name or +a number enclosed either in angle brackets or single quotes, is an alternative +syntax for referencing a subpattern as a subroutine, possibly recursively. Here +are two of the examples used above, rewritten using this syntax: +

+  (?<pn> \( ( (?>[^()]+) | \g<pn> )* \) )
+  (sens|respons)e and \g'1'ibility
+
+PCRE supports an extension to Oniguruma: if a number is preceded by a +plus or a minus sign it is taken as a relative reference. For example: +
+  (abc)(?i:\g<-1>)
+
+Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not +synonymous. The former is a back reference; the latter is a subroutine call. +

+
CALLOUTS
+

+Perl has a feature whereby using the sequence (?{...}) causes arbitrary Perl +code to be obeyed in the middle of matching a regular expression. This makes it +possible, amongst other things, to extract different substrings that match the +same pair of parentheses when there is a repetition. +

+

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

+

+Within a regular expression, (?C) indicates the points at which the external +function is to be called. If you want to identify different callout points, you +can put a number less than 256 after the letter C. The default value is zero. +For example, this pattern has two callout points: +

+  (?C1)abc(?C2)def
+
+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, 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. +

+
BACKTRACKING CONTROL
+

+Perl 5.10 introduced a number of "Special Backtracking Control Verbs", which +are described in the Perl documentation as "experimental and subject to change +or removal in a future version of Perl". It goes on to say: "Their usage in +production code should be noted to avoid problems during upgrades." The same +remarks apply to the PCRE features described in this section. +

+

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

+

+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. A name is any sequence of +characters that does not include a closing parenthesis. The maximum length of +name is 255 in the 8-bit library and 65535 in the 16-bit and 32-bit library. +If the name is empty, that is, if the 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 +minimum length of matching subject, or that a particular character must be +present. When one of these optimizations suppresses the running of a match, any +included backtracking verbs will not, of 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). 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 be +followed by a name. +

+   (*ACCEPT)
+
+This verb causes the match to end successfully, skipping the remainder of the +pattern. However, when it is inside a subpattern that is called as a +subroutine, only that subpattern is ended successfully. Matching then continues +at the outer level. If (*ACCEPT) is inside capturing parentheses, the data so +far is captured. For example: +
+  A((?:A|B(*ACCEPT)|C)D)
+
+This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is captured by +the outer parentheses. +
+  (*FAIL) or (*F)
+
+This verb causes a matching failure, forcing backtracking to occur. It is +equivalent to (?!) but easier to read. The Perl documentation notes that it is +probably useful only when combined with (?{}) or (??{}). Those are, of course, +Perl features that are not present in PCRE. The nearest equivalent is the +callout feature, as for example in this pattern: +
+  a+(?C)(*FAIL)
+
+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 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 have to be unique. +

+

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

+    re> /X(*MARK:A)Y|X(*MARK:B)Z/K
+  data> XY
+   0: XY
+  MK: A
+  XZ
+   0: XZ
+  MK: B
+
+The (*MARK) name is tagged with "MK:" in this output, and in this example it +indicates which of the two alternatives matched. This is a more efficient way +of obtaining this information than putting each alternative in its own +capturing parentheses. +

+

+If (*MARK) is encountered in a positive assertion, its name is recorded and +passed back if it is the last-encountered. This does not happen for negative +assertions. +

+

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

+    re> /X(*MARK:A)Y|X(*MARK:B)Z/K
+  data> XP
+  No match, mark = B
+
+Note that in this unanchored example the mark is retained from the 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 continues +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 backtracking 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 backtracking +reaches them. +

+  (*COMMIT)
+
+This verb, which may not be followed by a name, causes the whole match to fail +outright if the rest of the pattern does not match. Even if the pattern is +unanchored, no further attempts to find a match by advancing the starting point +take place. Once (*COMMIT) has been passed, pcre_exec() is committed to +finding a match at the current starting point, or not at all. For example: +
+  a+(*COMMIT)b
+
+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) 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 shown in this +pcretest example: +

+    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 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 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). In an +anchored pattern (*PRUNE) has the same effect as (*COMMIT). +
+  (*SKIP)
+
+This verb, when given without a name, is like (*PRUNE), except that if the +pattern is unanchored, the "bumpalong" advance is not to the next character, +but to the position in the subject where (*SKIP) was encountered. (*SKIP) +signifies that whatever text was matched leading up to it cannot be part of a +successful match. Consider: +
+  a+(*SKIP)b
+
+If the subject is "aaaac...", after the first match attempt fails (starting at +the first character in the string), the starting point skips on to start the +next attempt at "c". Note that a possessive quantifer does not have the same +effect as this example; although it would suppress backtracking during the +first match attempt, the second attempt would start at the second character +instead of skipping on to "c". +
+  (*SKIP:NAME)
+
+When (*SKIP) has an associated name, its behaviour is modified. If the +following pattern fails to match, the previous path through the pattern is +searched for the most recent (*MARK) that has the same name. If one is found, +the "bumpalong" advance is to the subject position that corresponds to that +(*MARK) instead of to where (*SKIP) was encountered. 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 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 +second alternative and tries COND2, without backtracking into COND1. The +behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN). +If (*THEN) is not inside an alternation, it acts like (*PRUNE). +

+

+Note that a subpattern that does not contain a | character is just a part of +the enclosing alternative; it is not a nested alternation with only one +alternative. The effect of (*THEN) extends beyond such a 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 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 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 alternative (that is, D) does not happen because (*COMMIT) +overrides. +

+
SEE ALSO
+

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

+
AUTHOR
+

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

+
REVISION
+

+Last updated: 11 November 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcreperform.html b/tools/pcre/doc/html/pcreperform.html new file mode 100644 index 00000000..dda207f9 --- /dev/null +++ b/tools/pcre/doc/html/pcreperform.html @@ -0,0 +1,195 @@ + + +pcreperform specification + + +

pcreperform 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 PERFORMANCE +
+

+Two aspects of performance are discussed below: memory usage and processing +time. The way you express your pattern as a regular expression can affect both +of them. +

+
+COMPILED PATTERN MEMORY USAGE +
+

+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}
+
+is compiled as if it were +
+  (abc|def)(abc|def)((abc|def)(abc|def)?)?
+
+(Technical aside: It is done this way so that backtrack points within each of +the repetitions can be independently maintained.) +

+

+For regular expressions whose quantifiers use only small numbers, this is not +usually a problem. However, if the numbers are large, and particularly if such +repetitions are nested, the memory usage can become an embarrassment. For +example, the very simple pattern +

+  ((ab){1,1000}c){1,3}
+
+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 +"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 otherwise handle. +

+
+STACK USAGE AT RUN TIME +
+

+When pcre_exec() or pcre[16|32]_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 efficiently +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 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 observations about PCRE. +

+

+Using Unicode character properties (the \p, \P, and \X escapes) is slow, +because PCRE has to use a multi-stage table lookup 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, 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 +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 is set, the +pattern is implicitly anchored by PCRE, since it can match only at the start of +a subject string. However, if PCRE_DOTALL is not set, PCRE cannot make this +optimization, because the . metacharacter does not then match a newline, and if +the subject string contains newlines, the pattern may match from the character +immediately following one of them instead of from the very start. For example, +the pattern +

+  .*second
+
+matches the subject "first\nand second" (where \n stands for a newline +character), with the match starting at the seventh character. In order to do +this, PCRE has to retry the match starting after every newline in the subject. +

+

+If you are using such a pattern with subject strings that do not contain +newlines, the best performance is obtained by setting PCRE_DOTALL, or starting +the pattern with ^.* or ^.*? to indicate explicit anchoring. That saves PCRE +from having to scan along the subject looking for a newline to restart at. +

+

+Beware of patterns that contain nested indefinite repeats. These can take a +long time to run when applied to a string that does not match. Consider the +pattern fragment +

+  ^(a+)*
+
+This can match "aaaa" in 16 different ways, and this number increases very +rapidly as the string gets longer. (The * repeat can match 0, 1, 2, 3, or 4 +times, and for each of those cases other than 0 or 4, the + repeats can match +different numbers of times.) When the remainder of the pattern is such that the +entire match is going to fail, PCRE has in principle to try every possible +variation, and this can take an extremely long time, even for relatively short +strings. +

+

+An optimization catches some of the more simple cases such as +

+  (a+)*b
+
+where a literal character follows. Before embarking on the standard matching +procedure, PCRE checks that there is a "b" later in the subject string, and if +there is not, it fails the match immediately. However, when there is no +following literal this optimization cannot be used. You can see the difference +by comparing the behaviour of +
+  (a+)*\d
+
+with the pattern above. The former gives a failure almost instantly when +applied to a whole line of "a" characters, whereas the latter takes an +appreciable time with strings longer than about 20 characters. +

+

+In many cases, the solution to this kind of performance issue is to use an +atomic group or a possessive quantifier. +

+
+AUTHOR +
+

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

+
+REVISION +
+

+Last updated: 25 August 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcreposix.html b/tools/pcre/doc/html/pcreposix.html new file mode 100644 index 00000000..0e5b296a --- /dev/null +++ b/tools/pcre/doc/html/pcreposix.html @@ -0,0 +1,292 @@ + + +pcreposix specification + + +

pcreposix 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 OF POSIX API
+

+#include <pcreposix.h> +

+

+int regcomp(regex_t *preg, const char *pattern, +int cflags); +

+

+int regexec(regex_t *preg, const char *string, +size_t nmatch, regmatch_t pmatch[], int eflags); +

+

+size_t regerror(int errcode, const regex_t *preg, +char *errbuf, size_t errbuf_size); +

+

+void regfree(regex_t *preg); +

+
DESCRIPTION
+

+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. There is no POSIX-style wrapper for PCRE's 16-bit +and 32-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 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 are not even defined. +

+

+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 expressions 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 renamed or +aliased as regex.h, which is the "correct" name. It provides two +structure types, regex_t for compiled internal forms, and +regmatch_t for returning captured substrings. It also defines some +constants 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 compiled regular expression. +

+

+The argument cflags is either zero, or contains one or more of the bits +defined by the following macros: +

+  REG_DOTALL
+
+The PCRE_DOTALL option is set when the regular expression is passed for +compilation to the native function. Note that REG_DOTALL is not part of the +POSIX standard. +
+  REG_ICASE
+
+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 section). +
+  REG_NOSUB
+
+The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is passed +for compilation to the native function. In addition, when a pattern that is +compiled with this flag is passed to regexec() for matching, 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 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 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. 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 by a negative class such as [^a] +(they are). +

+

+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 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 +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. +

+
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 PCRE: +

+                          Default   Change with
+
+  . matches newline          no     PCRE_DOTALL
+  newline matches [^a]       yes    not changeable
+  $ matches \n at end        yes    PCRE_DOLLARENDONLY
+  $ matches \n in middle     no     PCRE_MULTILINE
+  ^ matches \n in middle     no     PCRE_MULTILINE
+
+This is the equivalent table for POSIX: +
+                          Default   Change with
+
+  . matches newline          yes    REG_NEWLINE
+  newline matches [^a]       yes    REG_NEWLINE
+  $ matches \n at end        no     REG_NEWLINE
+  $ matches \n in middle     no     REG_NEWLINE
+  ^ matches \n in middle     no     REG_NEWLINE
+
+PCRE's behaviour is the same as Perl's, except that there is no equivalent 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 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 can +be: +

+  REG_NOTBOL
+
+The PCRE_NOTBOL option is set when calling the underlying PCRE matching +function. +
+  REG_NOTEMPTY
+
+The PCRE_NOTEMPTY option is set when calling the underlying PCRE matching +function. Note that REG_NOTEMPTY is not part of the POSIX standard. However, +setting this option can give more POSIX-like behaviour in some situations. +
+  REG_NOTEOL
+
+The PCRE_NOTEOL option is set when calling the underlying PCRE matching +function. +
+  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 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 +regexec() are ignored. +

+

+If the value of nmatch is zero, or if the value pmatch is NULL, +no data about any matched strings is returned. +

+

+Otherwise,the portion of the string that was matched, and also any captured +substrings, are returned via the pmatch argument, which points to an +array of nmatch structures of type regmatch_t, containing the +members 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" 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 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 +function is the size of buffer needed to hold the whole message. +

+
MEMORY USAGE
+

+Compiling a regular expression causes memory to be allocated and associated +with the preg structure. The function regfree() frees all such +memory, after which preg may no longer be used as a compiled expression. +

+
AUTHOR
+

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

+
REVISION
+

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

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcreprecompile.html b/tools/pcre/doc/html/pcreprecompile.html new file mode 100644 index 00000000..beb9e242 --- /dev/null +++ b/tools/pcre/doc/html/pcreprecompile.html @@ -0,0 +1,158 @@ + + +pcreprecompile specification + + +

pcreprecompile 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. +
+

+
SAVING AND RE-USING PRECOMPILED PCRE PATTERNS
+

+If you are running an application that uses a large number of regular +expression patterns, it may be useful to store them in a precompiled 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. 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. If the two hosts have different endianness (byte order), +you should run the pcre[16|32]_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[16|32]_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|32]_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;
+  pcre *re;
+
+  re = pcre_compile("my pattern", 0, &error, &erroroffset, NULL);
+  if (re == NULL) { ... handle errors ... }
+  rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size);
+  if (rc < 0) { ... handle errors ... }
+  rc = fwrite(re, 1, size, fd);
+  if (rc != size) { ... handle errors ... }
+
+In this example, the bytes that comprise the compiled pattern are copied +exactly. Note that this is binary data that may contain any of the 256 possible +byte values. On systems that make a distinction between binary and non-binary +data, be sure that the file is opened for binary output. +

+

+If you want to write more than one pattern to a file, you will have to devise a +way of separating them. For binary data, preceding each pattern with its length +is probably the most straightforward approach. Another possibility is to write +out the data in hexadecimal instead of binary, one pattern to a line. +

+

+Saving compiled patterns in a file is only one possible way of storing them for +later use. They could equally well be saved in a database, or 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 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|32]_study() returns a pointer to a +pcre[16|32]_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|32]_extra block itself). The +length of the study data can be obtained by calling pcre[16|32]_fullinfo() +with an argument of PCRE_INFO_STUDYSIZE. Remember to check that +pcre[16|32]_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, called pcre[16|32]_pattern_to_host_byte_order() if necessary, +you pass its pointer to pcre[16|32]_exec() or pcre[16|32]_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[16|32]_compile()), you +must now pass a similar pointer to pcre[16|32]_exec() or +pcre[16|32]_dfa_exec(), because the value saved with the compiled pattern +will obviously be nonsense. A field in a pcre[16|32]_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 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[16|32]_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|32]_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
+

+In general, it is safest to recompile all saved patterns when you update to a +new PCRE release, though not all updates actually require this. +

+
AUTHOR
+

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

+
REVISION
+

+Last updated: 24 June 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcresample.html b/tools/pcre/doc/html/pcresample.html new file mode 100644 index 00000000..aca9184e --- /dev/null +++ b/tools/pcre/doc/html/pcresample.html @@ -0,0 +1,110 @@ + + +pcresample specification + + +

pcresample 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 SAMPLE PROGRAM +
+

+A simple, complete demonstration program, to get you started with using PCRE, +is supplied in the file pcredemo.c in the PCRE distribution. A listing of +this program is given in the +pcredemo +documentation. If you do not have a copy of the PCRE distribution, you can save +this listing to re-create pcredemo.c. +

+

+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 possibility 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 for your +operating system, you should be able to compile the demonstration 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 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 against a +non-dll pcre.a file, you must uncomment the line that defines PCRE_STATIC +before including pcre.h, because otherwise the pcre_malloc() and +pcre_free() exported functions will be declared +__declspec(dllimport), with unwanted results. +

+

+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 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 systems (e.g. Solaris): +

+  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 systems. You +need to add +
+  -R/usr/local/lib
+
+(for example) to the compile command to get round this problem. +

+
+AUTHOR +
+

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

+
+REVISION +
+

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

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcrestack.html b/tools/pcre/doc/html/pcrestack.html new file mode 100644 index 00000000..af6406d0 --- /dev/null +++ b/tools/pcre/doc/html/pcrestack.html @@ -0,0 +1,225 @@ + + +pcrestack specification + + +

pcrestack 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 DISCUSSION OF STACK USAGE +
+

+When you call pcre[16|32]_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 +different numbers of a's. Furthermore, in a number of cases where the result of +the recursive call would immediately be passed back as the result of the +current call (a "tail recursion"), the function is just restarted instead. +

+

+The above comments apply when pcre[16|32]_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|32]_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|32]_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|32]_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|32]_dfa_exec() to run out of stack. At +present, there is no protection against this. +

+

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

+
+Reducing pcre[16|32]_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 large +amounts of stack may be needed, despite the recognition of "tail recursion". +You can often reduce the amount of recursion, and therefore the amount of stack +used, by modifying the pattern that is being matched. Consider, for example, +this pattern: +

+  ([^<]|<(?!inet))+
+
+It matches from wherever it starts until it encounters "<inet" or the end of +the data, and is the kind of pattern that might be used when processing an XML +file. Each iteration of the outer parentheses matches either one character that +is not "<" or a "<" that is not followed by "inet". However, each time a +parenthesis is processed, a recursion occurs, so this formulation uses a stack +frame for each matched character. For a long string, a lot of stack is +required. Consider now this rewritten pattern, which matches exactly the same +strings: +
+  ([^<]++|<(?!inet))+
+
+This uses very much less stack, because runs of characters that do not contain +"<" are "swallowed" in one item inside the parentheses. Recursion happens only +when a "<" character that is not followed by "inet" is encountered (and we +assume this is relatively rare). A possessive quantifier is used to stop any +backtracking into the runs of non-"<" characters, but that is not related to +stack usage. +

+

+This example shows that one way of avoiding stack problems when matching 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[16|32]_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[16|32]_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[16|32]_stack_malloc and pcre[16|32]_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[16|32]_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[16|32]_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|32]_exec() is called. For details of these interfaces, see the +pcrebuild +documentation and the +section on extra data for pcre[16|32]_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. +

+

+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[16|32]_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 +
+

+In Unix-like environments, there is not often a problem with the stack unless +very long strings are involved, though the default limit on stack size varies +from system to system. Values from 8Mb to 64Mb are common. You can find your +default limit by running the command: +

+  ulimit -s
+
+Unfortunately, the effect of running out of stack is often SIGSEGV, though +sometimes a more explicit error message is given. You can normally increase the +limit on stack size by code such as this: +
+  struct rlimit rlim;
+  getrlimit(RLIMIT_STACK, &rlim);
+  rlim.rlim_cur = 100*1024*1024;
+  setrlimit(RLIMIT_STACK, &rlim);
+
+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[16|32]_exec(). +

+
+Changing stack size in Mac OS X +
+

+Using setrlimit(), as described above, should also work on Mac OS X. It +is also possible to set a stack size when linking a program. There is a +discussion about stack sizes in Mac OS X at this web site: +http://developer.apple.com/qa/qa2005/qa1419.html. +

+
+AUTHOR +
+

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

+
+REVISION +
+

+Last updated: 24 June 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcresyntax.html b/tools/pcre/doc/html/pcresyntax.html new file mode 100644 index 00000000..22a253e2 --- /dev/null +++ b/tools/pcre/doc/html/pcresyntax.html @@ -0,0 +1,521 @@ + + +pcresyntax specification + + +

pcresyntax 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 REGULAR EXPRESSION SYNTAX SUMMARY
+

+The full syntax and semantics of the regular expressions that are supported by +PCRE are described in the +pcrepattern +documentation. This document contains a quick-reference summary of the syntax. +

+
QUOTING
+

+

+  \x         where x is non-alphanumeric is a literal x
+  \Q...\E    treat enclosed characters as literal
+
+

+
CHARACTERS
+

+

+  \a         alarm, that is, the BEL character (hex 07)
+  \cx        "control-x", where x is any ASCII character
+  \e         escape (hex 1B)
+  \f         form feed (hex 0C)
+  \n         newline (hex 0A)
+  \r         carriage return (hex 0D)
+  \t         tab (hex 09)
+  \ddd       character with octal code ddd, or backreference
+  \xhh       character with hex code hh
+  \x{hhh..}  character with hex code hhh..
+
+

+
CHARACTER TYPES
+

+

+  .          any character except newline;
+               in dotall mode, any character whatsoever
+  \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 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 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         a Unicode extended grapheme cluster
+
+In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII +characters, even in a UTF mode. However, this can be changed by setting the +PCRE_UCP option. +

+
GENERAL CATEGORY PROPERTIES FOR \p and \P
+

+

+  C          Other
+  Cc         Control
+  Cf         Format
+  Cn         Unassigned
+  Co         Private use
+  Cs         Surrogate
+
+  L          Letter
+  Ll         Lower case letter
+  Lm         Modifier letter
+  Lo         Other letter
+  Lt         Title case letter
+  Lu         Upper case letter
+  L&         Ll, Lu, or Lt
+
+  M          Mark
+  Mc         Spacing mark
+  Me         Enclosing mark
+  Mn         Non-spacing mark
+
+  N          Number
+  Nd         Decimal number
+  Nl         Letter number
+  No         Other number
+
+  P          Punctuation
+  Pc         Connector punctuation
+  Pd         Dash punctuation
+  Pe         Close punctuation
+  Pf         Final punctuation
+  Pi         Initial punctuation
+  Po         Other punctuation
+  Ps         Open punctuation
+
+  S          Symbol
+  Sc         Currency symbol
+  Sk         Modifier symbol
+  Sm         Mathematical symbol
+  So         Other symbol
+
+  Z          Separator
+  Zl         Line separator
+  Zp         Paragraph separator
+  Zs         Space separator
+
+

+
PCRE SPECIAL CATEGORY PROPERTIES FOR \p and \P
+

+

+  Xan        Alphanumeric: union of properties L and N
+  Xps        POSIX space: property Z or tab, NL, VT, FF, CR
+  Xsp        Perl space: property Z or tab, NL, FF, CR
+  Xwd        Perl word: property Xan or underscore
+
+

+
SCRIPT NAMES FOR \p AND \P
+

+Arabic, +Armenian, +Avestan, +Balinese, +Bamum, +Batak, +Bengali, +Bopomofo, +Brahmi, +Braille, +Buginese, +Buhid, +Canadian_Aboriginal, +Carian, +Chakma, +Cham, +Cherokee, +Common, +Coptic, +Cuneiform, +Cypriot, +Cyrillic, +Deseret, +Devanagari, +Egyptian_Hieroglyphs, +Ethiopic, +Georgian, +Glagolitic, +Gothic, +Greek, +Gujarati, +Gurmukhi, +Han, +Hangul, +Hanunoo, +Hebrew, +Hiragana, +Imperial_Aramaic, +Inherited, +Inscriptional_Pahlavi, +Inscriptional_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, +Samaritan, +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
+

+

+  [...]       positive character class
+  [^...]      negative character class
+  [x-y]       range (can be used for hex characters)
+  [[:xxx:]]   positive POSIX named set
+  [[:^xxx:]]  negative POSIX named set
+
+  alnum       alphanumeric
+  alpha       alphabetic
+  ascii       0-127
+  blank       space or tab
+  cntrl       control character
+  digit       decimal digit
+  graph       printing, excluding space
+  lower       lower case letter
+  print       printing, including space
+  punct       printing, excluding alphanumeric
+  space       white space
+  upper       upper case letter
+  word        same as \w
+  xdigit      hexadecimal digit
+
+In PCRE, POSIX character set names recognize only ASCII characters by default, +but some of them use Unicode properties if PCRE_UCP is set. You can use +\Q...\E inside a character class. +

+
QUANTIFIERS
+

+

+  ?           0 or 1, greedy
+  ?+          0 or 1, possessive
+  ??          0 or 1, lazy
+  *           0 or more, greedy
+  *+          0 or more, possessive
+  *?          0 or more, lazy
+  +           1 or more, greedy
+  ++          1 or more, possessive
+  +?          1 or more, lazy
+  {n}         exactly n
+  {n,m}       at least n, no more than m, greedy
+  {n,m}+      at least n, no more than m, possessive
+  {n,m}?      at least n, no more than m, lazy
+  {n,}        n or more, greedy
+  {n,}+       n or more, possessive
+  {n,}?       n or more, lazy
+
+

+
ANCHORS AND SIMPLE ASSERTIONS
+

+

+  \b          word boundary
+  \B          not a word boundary
+  ^           start of subject
+               also after internal newline in multiline mode
+  \A          start of subject
+  $           end of subject
+               also before newline at end of subject
+               also before internal newline in multiline mode
+  \Z          end of subject
+               also before newline at end of subject
+  \z          end of subject
+  \G          first matching position in subject
+
+

+
MATCH POINT RESET
+

+

+  \K          reset start of match
+
+

+
ALTERNATION
+

+

+  expr|expr|expr...
+
+

+
CAPTURING
+

+

+  (...)           capturing group
+  (?<name>...)    named capturing group (Perl)
+  (?'name'...)    named capturing group (Perl)
+  (?P<name>...)   named capturing group (Python)
+  (?:...)         non-capturing group
+  (?|...)         non-capturing group; reset group numbers for
+                   capturing groups in each alternative
+
+

+
ATOMIC GROUPS
+

+

+  (?>...)         atomic, non-capturing group
+
+

+
COMMENT
+

+

+  (?#....)        comment (not nestable)
+
+

+
OPTION SETTING
+

+

+  (?i)            caseless
+  (?J)            allow duplicate names
+  (?m)            multiline
+  (?s)            single line (dotall)
+  (?U)            default ungreedy (lazy)
+  (?x)            extended (ignore white space)
+  (?-...)         unset option(s)
+
+The following are recognized only at the start of a pattern or after 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: 8-bit library (PCRE_UTF8)
+  (*UTF16)        set UTF-16 mode: 16-bit library (PCRE_UTF16)
+  (*UTF32)        set UTF-32 mode: 32-bit library (PCRE_UTF32)
+  (*UTF)          set appropriate UTF mode for the library in use
+  (*UCP)          set PCRE_UCP (use Unicode properties for \d etc)
+
+

+
LOOKAHEAD AND LOOKBEHIND ASSERTIONS
+

+

+  (?=...)         positive look ahead
+  (?!...)         negative look ahead
+  (?<=...)        positive look behind
+  (?<!...)        negative look behind
+
+Each top-level branch of a look behind must be of a fixed length. +

+
BACKREFERENCES
+

+

+  \n              reference by number (can be ambiguous)
+  \gn             reference by number
+  \g{n}           reference by number
+  \g{-n}          relative reference by number
+  \k<name>        reference by name (Perl)
+  \k'name'        reference by name (Perl)
+  \g{name}        reference by name (Perl)
+  \k{name}        reference by name (.NET)
+  (?P=name)       reference by name (Python)
+
+

+
SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)
+

+

+  (?R)            recurse whole pattern
+  (?n)            call subpattern by absolute number
+  (?+n)           call subpattern by relative number
+  (?-n)           call subpattern by relative number
+  (?&name)        call subpattern by name (Perl)
+  (?P>name)       call subpattern by name (Python)
+  \g<name>        call subpattern by name (Oniguruma)
+  \g'name'        call subpattern by name (Oniguruma)
+  \g<n>           call subpattern by absolute number (Oniguruma)
+  \g'n'           call subpattern by absolute number (Oniguruma)
+  \g<+n>          call subpattern by relative number (PCRE extension)
+  \g'+n'          call subpattern by relative number (PCRE extension)
+  \g<-n>          call subpattern by relative number (PCRE extension)
+  \g'-n'          call subpattern by relative number (PCRE extension)
+
+

+
CONDITIONAL PATTERNS
+

+

+  (?(condition)yes-pattern)
+  (?(condition)yes-pattern|no-pattern)
+
+  (?(n)...        absolute reference condition
+  (?(+n)...       relative reference condition
+  (?(-n)...       relative reference condition
+  (?(<name>)...   named reference condition (Perl)
+  (?('name')...   named reference condition (Perl)
+  (?(name)...     named reference condition (PCRE)
+  (?(R)...        overall recursion condition
+  (?(Rn)...       specific group recursion condition
+  (?(R&name)...   specific recursion condition
+  (?(DEFINE)...   define subpattern for reference
+  (?(assert)...   assertion condition
+
+

+
BACKTRACKING CONTROL
+

+The following act immediately they are reached: +

+  (*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 +afterwards. Those that advance the start-of-match point do so only if the +pattern is not anchored. +
+  (*COMMIT)       overall failure, no advance of starting point
+  (*PRUNE)        advance to next starting character
+  (*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_...), (*UTF8), (*UTF16), (*UTF32) or (*UCP) option. +

+  (*CR)           carriage return only
+  (*LF)           linefeed only
+  (*CRLF)         carriage return followed by linefeed
+  (*ANYCRLF)      all three of the above
+  (*ANY)          any Unicode newline sequence
+
+

+
WHAT \R MATCHES
+

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

+  (*BSR_ANYCRLF)  CR, LF, or CRLF
+  (*BSR_UNICODE)  any Unicode newline sequence
+
+

+
CALLOUTS
+

+

+  (?C)      callout
+  (?Cn)     callout with data n
+
+

+
SEE ALSO
+

+pcrepattern(3), pcreapi(3), pcrecallout(3), +pcrematching(3), pcre(3). +

+
AUTHOR
+

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

+
REVISION
+

+Last updated: 11 November 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcretest.html b/tools/pcre/doc/html/pcretest.html new file mode 100644 index 00000000..8423ba5a --- /dev/null +++ b/tools/pcre/doc/html/pcretest.html @@ -0,0 +1,1082 @@ + + +pcretest specification + + +

pcretest 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
+

+pcretest [options] [input file [output file]] +
+
+pcretest was written as a test program for the PCRE regular expression +library itself, but it can also be used for experimenting with regular +expressions. This document describes the features of the test program; for +details of the regular expressions themselves, see the +pcrepattern +documentation. For details of the PCRE library function calls and their +options, see the +pcreapi +, +pcre16 +and +pcre32 +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. +

+

+As PCRE has evolved, it has acquired many different features, and as a result, +pcretest now has rather a lot of obscure options for testing every +possible feature. Some of these options are specifically designed for use in +conjunction with the test script and data files that are distributed as part of +PCRE, and are unlikely to be of use otherwise. They are all documented here, +but without much justification. +

+
PCRE's 8-BIT, 16-BIT AND 32-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. From release 8.32, a third +library can be built, supporting character strings encoded in 32-bit units. +The pcretest program can be +used to test all three libraries. However, it is itself still an 8-bit program, +reading 8-bit input and writing 8-bit output. When testing the 16-bit or 32-bit +library, the patterns and data strings are converted to 16- or 32-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|32]_xx below +mean "pcre_xx when using the 8-bit library or pcre16_xx when using +the 16-bit library". +

+
COMMAND LINE OPTIONS
+

+-8 +If both the 8-bit library has been built, this option causes the 8-bit library +to be used (which is the default); if the 8-bit library has not been built, +this option causes an error. +

+

+-16 +If both the 8-bit or the 32-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 or the 32-bit +library has been built, this option causes an error. +

+

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

+

+-b +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. 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: +

+  ebcdic-nl  the code for LF (= NL) in an EBCDIC environment:
+               0x15 or 0x25
+               0 if used in an ASCII environment
+  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: +
+  ebcdic     compiled for an EBCDIC environment
+  jit        just-in-time support is available
+  pcre16     the 16-bit library was built
+  pcre32     the 32-bit library was built
+  pcre8      the 8-bit library was built
+  ucp        Unicode property support is available
+  utf        UTF-8 and/or UTF-16 and/or UTF-32 support is available
+
+

+

+-d +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[16|32]_dfa_exec(), to be used instead +of the standard pcre[16|32]_exec() function (more detail is given below). +

+

+-help +Output a brief summary these options and then exit. +

+

+-i +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[16|32]_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. 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[16|32]_exec() or pcre[16|32]_dfa_exec() to be osize. The +default value is 45, which is enough for 14 capturing subexpressions for +pcre[16|32]_exec() or 22 different matches for +pcre[16|32]_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 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. This option can be used only with the 8-bit library. +

+

+-q +Do not output the version number of pcretest at the start of execution. +

+

+-S 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|32]_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. +
+
+Note that there are pattern options that can override -s, either +specifying no studying at all, or suppressing JIT compilation. +
+
+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 +-t, because you will then get the size output a zillion times, and the +timing will be distorted. You can control the number of iterations that are +used for timing by following -t with a number (as a separate item on the +command line). For example, "-t 1000" would iterate 1000 times. The default is +to iterate 500000 times. +

+

+-tm +This is like -t except that it times only the matching phase, not the +compile or study phases. +

+
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 +that file and writes to stdout. Otherwise, it reads from stdin and writes to +stdout, and prompts for each line of input, using "re>" to prompt for regular +expressions, and "data>" to prompt for data lines. +

+

+When pcretest is built, a configuration option can specify that it should +be linked with the libreadline library. When this is done, if the input +is from a terminal, it is read using the readline() function. This +provides line-editing and history facilities. The output from the -help +option states whether or not readline() will be used. +

+

+The program handles any number of sets of input on a single input file. Each +set starts with a regular expression, and continues with any number of data +lines to be matched against the pattern. +

+

+Each data line is matched separately and independently. If you want to do +multi-line matches, you have to use the \n escape sequence (or \r or \r\n, +etc., depending on the newline setting) in a single line of input to encode the +newline sequences. There is no limit on the length of data lines; the input +buffer is automatically extended if it is too small. +

+

+An empty line signals the end of the data lines, at which point a new regular +expression is read. The regular expressions are given enclosed in any +non-alphanumeric delimiters other than backslash, for example: +

+  /(a|bc)x+yz/
+
+White space before the initial delimiter is ignored. A regular expression may +be continued over several input lines, in which case the newline characters are +included within it. It is possible to include the delimiter within the pattern +by escaping it, for example +
+  /abc\/def/
+
+If you do so, the escape and the delimiter form part of the pattern, but since +delimiters are always non-alphanumeric, this does not affect its interpretation. +If the terminating delimiter is immediately followed by a backslash, for +example, +
+  /abc/\
+
+then a backslash is added to the end of the pattern. This is done to provide a +way of testing the error condition that arises if a pattern finishes with a +backslash, because +
+  /abc\/
+
+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
+

+A pattern may be followed by any number of modifiers, which are mostly single +characters, though some of these can be qualified by further 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. White space may appear +between the final pattern delimiter and the first modifier, and between the +modifiers themselves. For reference, here is a complete list of modifiers. They +fall into several groups that are described in detail in the following +sections. +

+  /8              set UTF mode
+  /?              disable UTF validity check
+  /+              show remainder of subject after match
+  /=              show all captures (not just those that are set)
+
+  /A              set PCRE_ANCHORED
+  /B              show compiled code
+  /C              set PCRE_AUTO_CALLOUT
+  /D              same as /B plus /I
+  /E              set PCRE_DOLLAR_ENDONLY
+  /F              flip byte order in compiled pattern
+  /f              set PCRE_FIRSTLINE
+  /G              find all matches (shorten string)
+  /g              find all matches (use startoffset)
+  /I              show information about pattern
+  /i              set PCRE_CASELESS
+  /J              set PCRE_DUPNAMES
+  /K              show backtracking control names
+  /L              set locale
+  /M              show compiled memory size
+  /m              set PCRE_MULTILINE
+  /N              set PCRE_NO_AUTO_CAPTURE
+  /P              use the POSIX wrapper
+  /S              study the pattern after compilation
+  /s              set PCRE_DOTALL
+  /T              select character tables
+  /U              set PCRE_UNGREEDY
+  /W              set PCRE_UCP
+  /X              set PCRE_EXTRA
+  /x              set PCRE_EXTENDED
+  /Y              set PCRE_NO_START_OPTIMIZE
+  /Z              don't show lengths in /B output
+
+  /<any>          set PCRE_NEWLINE_ANY
+  /<anycrlf>      set PCRE_NEWLINE_ANYCRLF
+  /<cr>           set PCRE_NEWLINE_CR
+  /<crlf>         set PCRE_NEWLINE_CRLF
+  /<lf>           set PCRE_NEWLINE_LF
+  /<bsr_anycrlf>  set PCRE_BSR_ANYCRLF
+  /<bsr_unicode>  set PCRE_BSR_UNICODE
+  /<JS>           set PCRE_JAVASCRIPT_COMPAT
+
+
+

+
+Perl-compatible modifiers +
+

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

+  /caseless/i
+
+
+

+
+Modifiers for other PCRE options +
+

+The following table shows additional modifiers for setting PCRE compile-time +options that do not correspond to anything in Perl: +

+  /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
+
+  /8              PCRE_UTF32          ) when using the 32-bit
+  /?              PCRE_NO_UTF32_CHECK )   library
+
+  /A              PCRE_ANCHORED
+  /C              PCRE_AUTO_CALLOUT
+  /E              PCRE_DOLLAR_ENDONLY
+  /f              PCRE_FIRSTLINE
+  /J              PCRE_DUPNAMES
+  /N              PCRE_NO_AUTO_CAPTURE
+  /U              PCRE_UNGREEDY
+  /W              PCRE_UCP
+  /X              PCRE_EXTRA
+  /Y              PCRE_NO_START_OPTIMIZE
+  /<any>          PCRE_NEWLINE_ANY
+  /<anycrlf>      PCRE_NEWLINE_ANYCRLF
+  /<cr>           PCRE_NEWLINE_CR
+  /<crlf>         PCRE_NEWLINE_CRLF
+  /<lf>           PCRE_NEWLINE_LF
+  /<bsr_anycrlf>  PCRE_BSR_ANYCRLF
+  /<bsr_unicode>  PCRE_BSR_UNICODE
+  /<JS>           PCRE_JAVASCRIPT_COMPAT
+
+The modifiers that are enclosed in angle brackets are literal strings 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<CRLF>
+
+As well as turning on the PCRE_UTF8/16/32 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. +

+
+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 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[16|32]_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[16|32]_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() function. 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. 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|32]_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 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 +/BI, that is, both the /B and the /I modifiers. +

+

+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 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[16|32]_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[16|32]_exec(). It causes +pcretest to create a pcre[16|32]_extra block if one has not already +been created by a call to pcre[16|32]_study(), and to set the +PCRE_EXTRA_MARK flag and the mark field within it, every time that +pcre[16|32]_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, +

+  /pattern/Lfr_FR
+
+For this reason, it must be the last modifier. The given locale is set, +pcre[16|32]_maketables() is called to build a set of character tables for +the locale, and this is then passed to pcre[16|32]_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|32] 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. +

+

+The /S modifier causes pcre[16|32]_study() to be called after the +expression has been compiled, and the results used when the expression is +matched. There are a number of qualifying characters that may follow /S. +They may appear in any order. +

+

+If S is followed by an exclamation mark, pcre[16|32]_study() is called +with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a +pcre_extra block, even when studying discovers no useful information. +

+

+If /S is followed by a second S character, 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 followed by a + character, the call to +pcre[16|32]_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|32]_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. +

+

+Finally, if /S is followed by a minus character, JIT compilation is +suppressed, even if it was requested externally by the -s command line +option. This makes it possible to specify that JIT is never to be used for +certain patterns. +

+

+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[16|32]_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
+        pcre_chartables.c.dist
+  1   a set of tables defining ISO 8859 characters
+
+In table 1, some characters whose codes are greater than 128 are identified as +letters, digits, spaces, etc. +

+
+Using the POSIX wrapper API +
+

+The /P modifier causes pcretest to call PCRE via the POSIX wrapper +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
+  /N    REG_NOSUB
+  /s    REG_DOTALL     )
+  /U    REG_UNGREEDY   ) These options are not part of
+  /W    REG_UCP        )   the POSIX standard
+  /8    REG_UTF8       )
+
+The /+ modifier works as described above. All other modifiers are +ignored. +

+
DATA LINES
+

+Before each data line is passed to pcre[16|32]_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: +

+  \a         alarm (BEL, \x07)
+  \b         backspace (\x08)
+  \e         escape (\x27)
+  \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 or 16-bit or 32-bit mode
+  \xhh       hexadecimal byte (up to 2 hex digits)
+  \x{hh...}  hexadecimal character (any number of hex digits)
+  \A         pass the PCRE_ANCHORED option to pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
+  \B         pass the PCRE_NOTBOL option to pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
+  \Cdd       call pcre[16|32]_copy_substring() for substring dd after a successful match (number less than 32)
+  \Cname     call pcre[16|32]_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[16|32]_dfa_exec() match function
+  \F         only shortest match for pcre[16|32]_dfa_exec()
+  \Gdd       call pcre[16|32]_get_substring() for substring dd after a successful match (number less than 32)
+  \Gname     call pcre[16|32]_get_named_substring() for substring "name" after a successful match (name termin-
+               ated by next non-alphanumeric character)
+  \Jdd       set up a JIT stack of dd kilobytes maximum (any number of digits)
+  \L         call pcre[16|32]_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[16|32]_exec() or pcre[16|32]_dfa_exec(); if used twice, pass the
+               PCRE_NOTEMPTY_ATSTART option
+  \Odd       set the size of the output vector passed to pcre[16|32]_exec() to dd (any number of digits)
+  \P         pass the PCRE_PARTIAL_SOFT option to pcre[16|32]_exec() or pcre[16|32]_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[16|32]_dfa_exec()
+  \S         output details of memory get/free calls during matching
+  \Y         pass the PCRE_NO_START_OPTIMIZE option to pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
+  \Z         pass the PCRE_NOTEOL option to pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
+  \?         pass the PCRE_NO_UTF[8|16|32]_CHECK option to pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
+  \>dd       start the match at offset dd (optional "-"; then any number of digits); this sets the startoffset
+               argument for pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
+  \<cr>      pass the PCRE_NEWLINE_CR option to pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
+  \<lf>      pass the PCRE_NEWLINE_LF option to pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
+  \<crlf>    pass the PCRE_NEWLINE_CRLF option to pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
+  \<anycrlf> pass the PCRE_NEWLINE_ANYCRLF option to pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
+  \<any>     pass the PCRE_NEWLINE_ANY option to pcre[16|32]_exec() or pcre[16|32]_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. +

+

+In UTF-32 mode, all 4- to 8-digit \x{...} values are accepted. This makes it +possible to construct invalid UTF-32 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 any data line. +

+

+A backslash followed by anything else just escapes the anything else. If +the very last character is a backslash, it is ignored. This gives a way of +passing an empty line as data, since a real empty line terminates the data +input. +

+

+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|32]_exec() several times, +with different values in the match_limit and match_limit_recursion +fields of the pcre[16|32]_extra data structure, until it finds the minimum +numbers for each parameter that allow pcre[16|32]_exec() to complete without +error. Because this is testing a specific feature of the normal interpretive +pcre[16|32]_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[16|32]_exec() for the line in which it appears. +

+

+If the /P modifier was present on the pattern, causing the POSIX wrapper +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 ALTERNATIVE MATCHING FUNCTION
+

+By default, pcretest uses the standard PCRE matching function, +pcre[16|32]_exec() to match each data line. PCRE also supports an +alternative matching function, pcre[16|32]_dfa_test(), which operates in a +different 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 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
+

+This section describes the output when the normal matching function, +pcre[16|32]_exec(), is being used. +

+

+When a match succeeds, pcretest outputs the list of captured substrings +that pcre[16|32]_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|32]_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 8.13 2011-04-30
+
+    re> /^abc(\d+)/
+  data> abc123
+   0: abc123
+   1: 123
+  data> xyz
+  No match
+
+Unset capturing substrings that are not followed by one that is set are not +returned by pcre[16|32]_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
+   0: a
+   1: a
+  data> b
+   0: b
+   1: <unset>
+   2: b
+
+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
+   0: cat
+   0+ aract
+
+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
+  data> Mississippi
+   0: iss
+   1: ss
+   0: iss
+   1: ss
+   0: ipp
+   1: pp
+
+"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 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 +parentheses 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 newlines 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[16|32]_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: +

+    re> /(tang|tangerine|tan)/
+  data> yellow tangerine\D
+   0: tangerine
+   1: tang
+   2: tan
+
+(Using the normal matching function on this data finds only "tang".) The +longest matching string is always given first (and numbered zero). After a +PCRE_ERROR_PARTIAL return, the output is "Partial match:", followed by the +partially matching substring. (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.) +

+

+If /g is present on the pattern, the search for further matches resumes +at the end of the longest match. For example: +

+    re> /(tang|tangerine|tan)/g
+  data> yellow tangerine and tangy sultana\D
+   0: tangerine
+   1: tang
+   2: tan
+   0: tang
+   1: tan
+   0: tan
+
+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
+

+When the alternative matching function has given the PCRE_ERROR_PARTIAL return, +indicating that the subject partially matched the pattern, you can restart the +match with additional subject data by means of the \R escape sequence. For +example: +

+    re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
+  data> 23ja\P\D
+  Partial match: 23ja
+  data> n05\R\D
+   0: n05
+
+For further information about partial matching, see the +pcrepartial +documentation. +

+
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: +

+  --->pqrabcdef
+    0    ^  ^     \d
+
+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 the +callout number, the offset in the pattern, preceded by a plus, is output. For +example: +

+    re> /\d?[A-E]\*/C
+  data> E*
+  --->E*
+   +0 ^      \d?
+   +3 ^      [A-E]
+   +8 ^^     \*
+  +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 and other parameters of the callout. +

+

+Inserting callouts can be helpful when using pcretest to check +complicated 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 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 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 +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 file name. +For example: +

+  /pattern/im >/some/file
+
+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 optional study data, each +written as four bytes in big-endian order (most significant byte first). If +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 +(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> </some/file
+  Compiled pattern loaded from /some/file
+  No study data
+
+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. 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 +the shell facility of expanding a file name that starts with a tilde (~) is not +available. +

+

+The ability to save and reload files in pcretest is intended for testing +and experimentation. It is not intended for production use because only a +single pattern can be written to a file. Furthermore, there is no facility for +supplying custom character tables for use with a reloaded pattern. If the +original pattern was compiled with custom tables, an attempt to match a subject +string using a reloaded pattern is likely to cause pcretest to crash. +Finally, if you attempt to load a file that is not in the correct format, the +result is undefined. +

+
SEE ALSO
+

+pcre(3), pcre16(3), pcre32(3), pcreapi(3), +pcrecallout(3), +pcrejit, pcrematching(3), pcrepartial(d), +pcrepattern(3), pcreprecompile(3). +

+
AUTHOR
+

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

+
REVISION
+

+Last updated: 10 September 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/html/pcreunicode.html b/tools/pcre/doc/html/pcreunicode.html new file mode 100644 index 00000000..c3c51eac --- /dev/null +++ b/tools/pcre/doc/html/pcreunicode.html @@ -0,0 +1,270 @@ + + +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, UTF-32, AND UNICODE PROPERTY SUPPORT +
+

+As well as UTF-8 support, PCRE also supports UTF-16 (from release 8.30) and +UTF-32 (from release 8.32), by means of two additional libraries. They 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) or (*UTF). 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 individual 1-byte characters. +

+
+UTF-16 AND UTF-32 SUPPORT +
+

+In order process UTF-16 or UTF-32 strings, you must build PCRE's 16-bit or +32-bit library with UTF support, and, in addition, you must call +pcre16_compile() +or +pcre32_compile() +with the PCRE_UTF16 or PCRE_UTF32 option flag, as appropriate. Alternatively, +the pattern must start with the sequence (*UTF16), (*UTF32), as appropriate, or +(*UTF), which can be used with either library. When UTF mode is set, both the +pattern and any subject strings that are matched against it are treated as +UTF-16 or UTF-32 strings instead of strings of individual 16-bit or 32-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_UTF[8|16|32] 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&. Full lists is given in the +pcrepattern +and +pcresyntax +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 the surrogate area and the non-characters. +

+

+Characters in the "Surrogate Area" of Unicode are reserved for use by UTF-16, +where they are used in pairs to encode codepoints with values greater than +0xFFFF. The code points that are encoded by UTF-16 pairs are available +independently in the UTF-8 and UTF-32 encodings. (In other words, the whole +surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8 and +UTF-32.) +

+

+Also excluded are the "Non-Character" code points, which are U+FDD0 to U+FDEF +and the last two code points in each plane, U+??FFFE and U+??FFFF. +

+

+If an invalid UTF-8 string is passed to PCRE, an error return is given. At +compile time, the only additional information is the offset to the first byte +of the failing character. The run-time functions pcre_exec() 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. +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. +

+

+Note that passing PCRE_NO_UTF8_CHECK to pcre_compile() just disables the +check for the pattern; it does not also apply to subject strings. If you want +to disable the check for a subject string you must pass this option to +pcre_exec() or pcre_dfa_exec(). +

+

+If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, the result +is undefined and your program may crash. +

+
+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. +

+

+Excluded are the "Non-Character" code points, which are U+FDD0 to U+FDEF +and the last two code points in each plane, U+??FFFE and U+??FFFF. +

+

+If an invalid UTF-16 string is passed to PCRE, an error return is given. At +compile time, the only additional information is the offset to the first data +unit of the failing character. The run-time functions 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. +However, if an invalid string is passed, the result is undefined. +

+
+Validity of UTF-32 strings +
+

+When you set the PCRE_UTF32 flag, the strings of 32-bit data units that are +passed as patterns and subjects are (by default) checked for validity on entry +to the relevant functions. This check allows only values in the range U+0 +to U+10FFFF, excluding the surrogate area U+D800 to U+DFFF, and the +"Non-Character" code points, which are U+FDD0 to U+FDEF and the last two +characters in each plane, U+??FFFE and U+??FFFF. +

+

+If an invalid UTF-32 string is passed to PCRE, an error return is given. At +compile time, the only additional information is the offset to the first data +unit of the failing character. The run-time functions pcre32_exec() and +pcre32_dfa_exec() also pass back this information, as well as a more +detailed reason code if the caller has provided memory 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_UTF32_CHECK flag at compile time or at run time, PCRE assumes that +the pattern or subject it is given (respectively) contains only valid UTF-32 +sequences. In this case, it does not diagnose an invalid UTF-32 string. +However, if an invalid string is passed, the result is undefined. +

+
+General comments about UTF modes +
+

+1. Codepoints less than 256 can be specified in patterns by either 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, or a single 32-bit data unit in +UTF-32 mode, but its use can lead to some strange effects because it breaks up +multi-unit characters (see the description of \C in the +pcrepattern +documentation). The use of \C is not supported in the alternative matching +function pcre[16|32]_dfa_exec(), nor is it supported in UTF mode by the +JIT optimization of pcre[16|32]_exec(). If JIT optimization is requested +for a UTF pattern that contains \C, it 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. A few Unicode +characters such as Greek sigma have more than two codepoints that are +case-equivalent. Up to and including PCRE release 8.31, only one-to-one case +mappings were supported, but later releases (with Unicode property support) do +treat as case-equivalent all versions of characters such as Greek sigma. +

+
+AUTHOR +
+

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

+
+REVISION +
+

+Last updated: 11 November 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff --git a/tools/pcre/doc/index.html.src b/tools/pcre/doc/index.html.src new file mode 100644 index 00000000..c7bc196b --- /dev/null +++ b/tools/pcre/doc/index.html.src @@ -0,0 +1,180 @@ + + + +PCRE specification + + +

Perl-compatible Regular Expressions (PCRE)

+

+The HTML documentation for PCRE comprises the following pages: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
pcre  Introductory page
pcre16  Discussion of the 16-bit PCRE library
pcre32  Discussion of the 32-bit PCRE library
pcre-config  Information about the installation configuration
pcreapi  PCRE's native API
pcrebuild  Options for building PCRE
pcrecallout  The callout facility
pcrecompat  Compability with Perl
pcrecpp  The C++ wrapper for the PCRE library
pcredemo  A demonstration C program that uses the PCRE library
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
pcrepartial  Using PCRE for partial matching
pcrepattern  Specification of the regular expressions supported by PCRE
pcreperform  Some comments on performance
pcreposix  The POSIX API to the PCRE library
pcreprecompile  How to save and re-use compiled patterns
pcresample  Discussion of the pcredemo program
pcrestack  Discussion of PCRE's stack usage
pcresyntax  Syntax quick-reference summary
pcretest  The pcretest command for testing PCRE
pcreunicode  Discussion of Unicode and UTF-8/UTF-16/UTF-32 support
+ +

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

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
pcre_assign_jit_stack  Assign stack for JIT matching
pcre_compile  Compile a regular expression
pcre_compile2  Compile a regular expression (alternate interface)
pcre_config  Show build-time configuration options
pcre_copy_named_substring  Extract named substring into given buffer
pcre_copy_substring  Extract numbered substring into given buffer
pcre_dfa_exec  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_free_substring  Free extracted substring
pcre_free_substring_list  Free list of extracted substrings
pcre_fullinfo  Extract information about a pattern
pcre_get_named_substring  Extract named substring into new memory
pcre_get_stringnumber  Convert captured string name to number
pcre_get_substring  Extract numbered substring into new memory
pcre_get_substring_list  Extract all substrings into new memory
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_utf32_to_host_byte_order  Convert UTF-32 string to host byte order if necessary
pcre_version  Return PCRE version and release date
+ + diff --git a/tools/pcre/doc/pcre-config.1 b/tools/pcre/doc/pcre-config.1 new file mode 100644 index 00000000..92a4b58b --- /dev/null +++ b/tools/pcre/doc/pcre-config.1 @@ -0,0 +1,92 @@ +.TH PCRE-CONFIG 1 "01 January 2012" "PCRE 8.30" +.SH NAME +pcre-config - program to return PCRE configuration +.SH SYNOPSIS +.rs +.sp +.B pcre-config [--prefix] [--exec-prefix] [--version] [--libs] +.ti +5n +.B [--libs16] [--libs32] [--libs-cpp] [--libs-posix] +.ti +5n +.B [--cflags] [--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. Some of +the options apply only to the 8-bit, or 16-bit, or 32-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 +.rs +.TP 10 +\fB--prefix\fP +Writes the directory prefix used in the PCRE installation for architecture +independent files (\fI/usr\fP on many systems, \fI/usr/local\fP on some +systems) to the standard output. +.TP 10 +\fB--exec-prefix\fP +Writes the directory prefix used in the PCRE installation for architecture +dependent files (normally the same as \fB--prefix\fP) to the standard output. +.TP 10 +\fB--version\fP +Writes the version number of the installed PCRE libraries to the standard +output. +.TP 10 +\fB--libs\fP +Writes to the standard output the command line options required to link +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--libs32\fP +Writes to the standard output the command line options required to link +with the 32-bit PCRE library (\fB-lpcre32\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 +PCRE's POSIX API wrapper library (\fB-lpcreposix\fP \fB-lpcre\fP on many +systems). +.TP 10 +\fB--cflags\fP +Writes to the standard output the command line options required to compile +files that use PCRE (this may include some \fB-I\fP options, but is blank on +many systems). +.TP 10 +\fB--cflags-posix\fP +Writes to the standard output the command line options required to compile +files that use PCRE's POSIX API wrapper library (this may include some \fB-I\fP +options, but is blank on many systems). +. +. +.SH "SEE ALSO" +.rs +.sp +\fBpcre(3)\fP +. +. +.SH AUTHOR +.rs +.sp +This manual page was originally written by Mark Baker for the Debian GNU/Linux +system. It has been subsequently revised as a generic PCRE man page. +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 24 June 2012 +.fi diff --git a/tools/pcre/doc/pcre-config.txt b/tools/pcre/doc/pcre-config.txt new file mode 100644 index 00000000..3ee9777b --- /dev/null +++ b/tools/pcre/doc/pcre-config.txt @@ -0,0 +1,86 @@ +PCRE-CONFIG(1) PCRE-CONFIG(1) + + + +NAME + pcre-config - program to return PCRE configuration + +SYNOPSIS + + pcre-config [--prefix] [--exec-prefix] [--version] [--libs] + [--libs16] [--libs32] [--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. Some of the + options apply only to the 8-bit, or 16-bit, or 32-bit libraries, + respectively, and are not available if only one of those libraries has + been built. If an unavailable option is encountered, the "usage" infor- + mation is output. + + +OPTIONS + + --prefix Writes the directory prefix used in the PCRE installation for + 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) + to the standard output. + + --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 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). + + --libs32 Writes to the standard output the command line options + required to link with the 32-bit PCRE library (-lpcre32 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 PCRE's POSIX API wrapper library + (-lpcreposix -lpcre on many systems). + + --cflags Writes to the standard output the command line options + required to compile files that use PCRE (this may include + some -I options, but is blank on many systems). + + --cflags-posix + Writes to the standard output the command line options + required to compile files that use PCRE's POSIX API wrapper + library (this may include some -I options, but is blank on + many systems). + + +SEE ALSO + + pcre(3) + + +AUTHOR + + This manual page was originally written by Mark Baker for the Debian + GNU/Linux system. It has been subsequently revised as a generic PCRE + man page. + + +REVISION + + Last updated: 24 June 2012 diff --git a/tools/pcre/doc/pcre.3 b/tools/pcre/doc/pcre.3 new file mode 100644 index 00000000..84928f49 --- /dev/null +++ b/tools/pcre/doc/pcre.3 @@ -0,0 +1,202 @@ +.TH PCRE 3 "11 November 2012" "PCRE 8.32" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH INTRODUCTION +.rs +.sp +The PCRE library is a set of functions that implement regular expression +pattern matching using the same syntax and semantics as Perl, with just a few +differences. Some features that appeared in Python and PCRE before they +appeared in Perl are also available using the Python syntax, there is some +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 +Starting with release 8.32 it is possible to compile a third separate PCRE +library, which supports 32-bit character strings (including +UTF-32 strings). The build process allows any set of the 8-, 16- and 32-bit +libraries. The work to make this possible was done by Christian Persch. +.P +The three libraries contain identical sets of functions, except that the names +in the 16-bit library start with \fBpcre16_\fP instead of \fBpcre_\fP, and the +names in the 32-bit library start with \fBpcre32_\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 and 32-bit libraries described separately in the +.\" HREF +\fBpcre16\fP +and +.\" HREF +\fBpcre32\fP +.\" +pages. References to functions or structures of the form \fIpcre[16|32]_xxx\fP +should be read as meaning "\fIpcre_xxx\fP when using the 8-bit library, +\fIpcre16_xxx\fP when using the 16-bit library, or \fIpcre32_xxx\fP when using +the 32-bit library". +.P +The current implementation of PCRE corresponds approximately with Perl 5.12, +including support for UTF-8/16/32 encoded strings and Unicode general category +properties. However, UTF-8/16/32 and Unicode support has to be explicitly +enabled; it is not the default. The Unicode tables correspond to Unicode +release 6.2.0. +.P +In addition to the Perl-compatible matching function, PCRE contains an +alternative function that matches the same compiled patterns in a different +way. In certain circumstances, the alternative function has some advantages. +For a discussion of the two matching algorithms, see the +.\" HREF +\fBpcrematching\fP +.\" +page. +.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 for the 8-bit library. This is now +included as part of the PCRE distribution. The +.\" HREF +\fBpcrecpp\fP +.\" +page has details of this interface. Other people's contributions can be found +in the \fIContrib\fP directory at the primary FTP site, which is: +.sp +.\" HTML +.\" +ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre +.P +Details of exactly which Perl regular expression features are and are not +supported by PCRE are given in separate documents. See the +.\" HREF +\fBpcrepattern\fP +.\" +and +.\" HREF +\fBpcrecompat\fP +.\" +pages. There is a syntax summary in the +.\" HREF +\fBpcresyntax\fP +.\" +page. +.P +Some features of PCRE can be included, excluded, or changed when the library is +built. The +.\" HREF +\fBpcre_config()\fP +.\" +function makes it possible for a client to discover which features are +available. The features themselves are described in the +.\" HREF +\fBpcrebuild\fP +.\" +page. Documentation about building PCRE for various operating systems can be +found in the \fBREADME\fP and \fBNON-AUTOTOOLS_BUILD\fP files in the source +distribution. +.P +The libraries contains a number of undocumented internal functions and data +tables that are used by more than one of the exported external functions, but +which are not intended for use by external callers. Their names all begin with +"_pcre_" or "_pcre16_" or "_pcre32_", which hopefully will not provoke any name +clashes. In some environments, it is possible to control which external symbols +are exported when a shared library is built, and in these cases the +undocumented symbols are not exported. +. +. +.SH "SECURITY CONSIDERATIONS" +.rs +.sp +If you are using PCRE in a non-UTF application that permits users to supply +arbitrary patterns for compilation, you should be aware of a feature that +allows users to turn on UTF support from within a pattern, provided that PCRE +was built with UTF support. For example, an 8-bit pattern that begins with +"(*UTF8)" or "(*UTF)" turns on UTF-8 mode, which interprets patterns and +subjects as strings of UTF-8 characters instead of individual 8-bit characters. +This causes both the pattern and any data against which it is matched to be +checked for UTF-8 validity. If the data string is very long, such a check might +use sufficiently many resources as to cause your application to lose +performance. +.P +The best way of guarding against this possibility is to use the +\fBpcre_fullinfo()\fP function to check the compiled pattern's options for UTF. +.P +If your application is one that supports UTF, be aware that validity checking +can take time. If the same data string is to be matched many times, you can use +the PCRE_NO_UTF[8|16|32]_CHECK option for the second and subsequent matches to +save redundant checks. +.P +Another way that performance can be hit is by running a pattern that has a very +large search tree against a string that will never match. Nested unlimited +repeats in a pattern are a common example. PCRE provides some protection +against this: see the PCRE_EXTRA_MATCH_LIMIT feature in the +.\" HREF +\fBpcreapi\fP +.\" +page. +. +. +.SH "USER DOCUMENTATION" +.rs +.sp +The user documentation for PCRE comprises a number of different sections. 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 \fBpcredemo\fP section, are concatenated, for ease +of searching. The sections are as follows: +.sp + pcre this document + pcre16 details of the 16-bit library + pcre32 details of the 32-bit library + pcre-config show PCRE installation configuration information + pcreapi details of PCRE's native C API + pcrebuild options for building PCRE + pcrecallout details of the callout feature + pcrecompat discussion of Perl compatibility + 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 (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 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/32 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 AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +.P +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. +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 11 November 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcre.txt b/tools/pcre/doc/pcre.txt new file mode 100644 index 00000000..2a2a82c7 --- /dev/null +++ b/tools/pcre/doc/pcre.txt @@ -0,0 +1,9909 @@ +----------------------------------------------------------------------------- +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 +the pcredemo program. There are separate text files for the pcregrep and +pcretest commands. +----------------------------------------------------------------------------- + + +PCRE(3) PCRE(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +INTRODUCTION + + The PCRE library is a set of functions that implement regular expres- + sion pattern matching using the same syntax and semantics as Perl, with + just a few differences. Some features that appeared in Python and PCRE + before they appeared in Perl are also available using the Python syn- + tax, there is some 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. + + 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. + + Starting with release 8.32 it is possible to compile a third separate + PCRE library, which supports 32-bit character strings (including UTF-32 + strings). The build process allows any set of the 8-, 16- and 32-bit + libraries. The work to make this possible was done by Christian Persch. + + The three libraries contain identical sets of functions, except that + the names in the 16-bit library start with pcre16_ instead of pcre_, + and the names in the 32-bit library start with pcre32_ instead of + pcre_. To avoid over-complication and reduce the documentation mainte- + nance load, most of the documentation describes the 8-bit library, with + the differences for the 16-bit and 32-bit libraries described sepa- + rately in the pcre16 and pcre32 pages. References to functions or + structures of the form pcre[16|32]_xxx should be read as meaning + "pcre_xxx when using the 8-bit library, pcre16_xxx when using the + 16-bit library, or pcre32_xxx when using the 32-bit library". + + The current implementation of PCRE corresponds approximately with Perl + 5.12, including support for UTF-8/16/32 encoded strings and Unicode + general category properties. However, UTF-8/16/32 and Unicode support + has to be explicitly enabled; it is not the default. The Unicode tables + correspond to Unicode release 6.2.0. + + In addition to the Perl-compatible matching function, PCRE contains an + alternative function that matches the same compiled patterns in a dif- + ferent way. In certain circumstances, the alternative function has some + advantages. For a discussion of the two matching algorithms, see the + pcrematching page. + + PCRE is written in C and released as a C library. A number of people + have written wrappers and interfaces of various kinds. In particular, + Google Inc. have provided a comprehensive C++ wrapper for the 8-bit + library. This is now included as part of the PCRE distribution. The + pcrecpp page has details of this interface. Other people's contribu- + tions can be found in the Contrib directory at the primary FTP site, + which is: + + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre + + 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 + 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 + NON-AUTOTOOLS_BUILD files in the source distribution. + + The libraries contains a number of undocumented internal functions and + data tables that are used by more than one of the exported external + functions, but which are not intended for use by external callers. + Their names all begin with "_pcre_" or "_pcre16_" or "_pcre32_", which + hopefully will not provoke any name clashes. In some environments, it + is possible to control which external symbols are exported when a + shared library is built, and in these cases the undocumented symbols + are not exported. + + +SECURITY CONSIDERATIONS + + If you are using PCRE in a non-UTF application that permits users to + supply arbitrary patterns for compilation, you should be aware of a + feature that allows users to turn on UTF support from within a pattern, + provided that PCRE was built with UTF support. For example, an 8-bit + pattern that begins with "(*UTF8)" or "(*UTF)" turns on UTF-8 mode, + which interprets patterns and subjects as strings of UTF-8 characters + instead of individual 8-bit characters. This causes both the pattern + and any data against which it is matched to be checked for UTF-8 valid- + ity. If the data string is very long, such a check might use suffi- + ciently many resources as to cause your application to lose perfor- + mance. + + The best way of guarding against this possibility is to use the + pcre_fullinfo() function to check the compiled pattern's options for + UTF. + + If your application is one that supports UTF, be aware that validity + checking can take time. If the same data string is to be matched many + times, you can use the PCRE_NO_UTF[8|16|32]_CHECK option for the second + and subsequent matches to save redundant checks. + + Another way that performance can be hit is by running a pattern that + has a very large search tree against a string that will never match. + Nested unlimited repeats in a pattern are a common example. PCRE pro- + vides some protection against this: see the PCRE_EXTRA_MATCH_LIMIT fea- + ture in the pcreapi page. + + +USER DOCUMENTATION + + The user documentation for PCRE comprises a number of different sec- + tions. In the "man" format, each of these is a separate "man page". In + the HTML format, each is a separate page, linked from the index page. + In the plain text format, all the sections, except the pcredemo sec- + tion, are concatenated, for ease of searching. The sections are as fol- + lows: + + pcre this document + pcre16 details of the 16-bit library + pcre32 details of the 32-bit library + pcre-config show PCRE installation configuration information + pcreapi details of PCRE's native C API + pcrebuild options for building PCRE + pcrecallout details of the callout feature + pcrecompat discussion of Perl compatibility + 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 (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 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/32 support + + In addition, in the "man" and HTML formats, there is a short page for + each C library function, listing its arguments and results. + + +AUTHOR + + Philip Hazel + 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: 11 November 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCRE(3) PCRE(3) + + +NAME + PCRE - Perl-compatible regular expressions + + #include + + +PCRE 16-BIT API BASIC FUNCTIONS + + pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options, + const char **errptr, int *erroffset, + const unsigned char *tableptr); + + pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options, + int *errorcodeptr, + const char **errptr, int *erroffset, + const unsigned char *tableptr); + + pcre16_extra *pcre16_study(const pcre16 *code, int options, + const char **errptr); + + void pcre16_free_study(pcre16_extra *extra); + + int pcre16_exec(const pcre16 *code, const pcre16_extra *extra, + PCRE_SPTR16 subject, int length, int startoffset, + int options, int *ovector, int ovecsize); + + int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra, + PCRE_SPTR16 subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + int *workspace, int wscount); + + +PCRE 16-BIT API STRING EXTRACTION FUNCTIONS + + int pcre16_copy_named_substring(const pcre16 *code, + PCRE_SPTR16 subject, int *ovector, + int stringcount, PCRE_SPTR16 stringname, + PCRE_UCHAR16 *buffer, int buffersize); + + int pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, + int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, + int buffersize); + + int pcre16_get_named_substring(const pcre16 *code, + PCRE_SPTR16 subject, int *ovector, + int stringcount, PCRE_SPTR16 stringname, + PCRE_SPTR16 *stringptr); + + int pcre16_get_stringnumber(const pcre16 *code, + PCRE_SPTR16 name); + + int pcre16_get_stringtable_entries(const pcre16 *code, + PCRE_SPTR16 name, PCRE_UCHAR16 **first, PCRE_UCHAR16 **last); + + int pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, + int stringcount, int stringnumber, + PCRE_SPTR16 *stringptr); + + int pcre16_get_substring_list(PCRE_SPTR16 subject, + int *ovector, int stringcount, PCRE_SPTR16 **listptr); + + void pcre16_free_substring(PCRE_SPTR16 stringptr); + + void pcre16_free_substring_list(PCRE_SPTR16 *stringptr); + + +PCRE 16-BIT API AUXILIARY FUNCTIONS + + pcre16_jit_stack *pcre16_jit_stack_alloc(int startsize, int maxsize); + + void pcre16_jit_stack_free(pcre16_jit_stack *stack); + + void pcre16_assign_jit_stack(pcre16_extra *extra, + pcre16_jit_callback callback, void *data); + + const unsigned char *pcre16_maketables(void); + + int pcre16_fullinfo(const pcre16 *code, const pcre16_extra *extra, + int what, void *where); + + int pcre16_refcount(pcre16 *code, int adjust); + + int pcre16_config(int what, void *where); + + const char *pcre16_version(void); + + int pcre16_pattern_to_host_byte_order(pcre16 *code, + pcre16_extra *extra, const unsigned char *tables); + + +PCRE 16-BIT API INDIRECTED FUNCTIONS + + void *(*pcre16_malloc)(size_t); + + void (*pcre16_free)(void *); + + void *(*pcre16_stack_malloc)(size_t); + + void (*pcre16_stack_free)(void *); + + int (*pcre16_callout)(pcre16_callout_block *); + + +PCRE 16-BIT API 16-BIT-ONLY FUNCTION + + int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, + PCRE_SPTR16 input, int length, int *byte_order, + int keep_boms); + + +THE PCRE 16-BIT LIBRARY + + Starting with release 8.30, it is possible to compile a PCRE library + that supports 16-bit character strings, including UTF-16 strings, as + well as or instead of the original 8-bit library. The majority of the + work to make this possible was done by Zoltan Herczeg. The two + libraries contain identical sets of functions, used in exactly the same + way. Only the names of the functions and the data types of their argu- + ments and results are different. To avoid over-complication and reduce + the documentation maintenance load, most of the PCRE documentation + describes the 8-bit library, with only occasional references to the + 16-bit library. This page describes what is different when you use the + 16-bit library. + + WARNING: A single application can be linked with both libraries, but + you must take care when processing any particular pattern to use func- + tions from just one library. For example, if you want to study a pat- + tern that was compiled with pcre16_compile(), you must do so with + pcre16_study(), not pcre_study(), and you must free the study data with + pcre16_free_study(). + + +THE HEADER FILE + + There is only one header file, pcre.h. It contains prototypes for all + the functions in all libraries, as well as definitions of flags, struc- + tures, 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 "unsigned 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 pcre32_config(), or if the + PCRE_CONFIG_UTF8 or PCRE_CONFIG_UTF32 option is given to pcre16_con- + fig(), 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 Non-character + + +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 both the 8-bit and the + 32-bit libraries were 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, + 16-bit and 32-bit libraries has been built, and runs the tests appro- + priately. + + +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: 08 November 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCRE(3) PCRE(3) + + +NAME + PCRE - Perl-compatible regular expressions + + #include + + +PCRE 32-BIT API BASIC FUNCTIONS + + pcre32 *pcre32_compile(PCRE_SPTR32 pattern, int options, + const char **errptr, int *erroffset, + const unsigned char *tableptr); + + pcre32 *pcre32_compile2(PCRE_SPTR32 pattern, int options, + int *errorcodeptr, + const char **errptr, int *erroffset, + const unsigned char *tableptr); + + pcre32_extra *pcre32_study(const pcre32 *code, int options, + const char **errptr); + + void pcre32_free_study(pcre32_extra *extra); + + int pcre32_exec(const pcre32 *code, const pcre32_extra *extra, + PCRE_SPTR32 subject, int length, int startoffset, + int options, int *ovector, int ovecsize); + + int pcre32_dfa_exec(const pcre32 *code, const pcre32_extra *extra, + PCRE_SPTR32 subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + int *workspace, int wscount); + + +PCRE 32-BIT API STRING EXTRACTION FUNCTIONS + + int pcre32_copy_named_substring(const pcre32 *code, + PCRE_SPTR32 subject, int *ovector, + int stringcount, PCRE_SPTR32 stringname, + PCRE_UCHAR32 *buffer, int buffersize); + + int pcre32_copy_substring(PCRE_SPTR32 subject, int *ovector, + int stringcount, int stringnumber, PCRE_UCHAR32 *buffer, + int buffersize); + + int pcre32_get_named_substring(const pcre32 *code, + PCRE_SPTR32 subject, int *ovector, + int stringcount, PCRE_SPTR32 stringname, + PCRE_SPTR32 *stringptr); + + int pcre32_get_stringnumber(const pcre32 *code, + PCRE_SPTR32 name); + + int pcre32_get_stringtable_entries(const pcre32 *code, + PCRE_SPTR32 name, PCRE_UCHAR32 **first, PCRE_UCHAR32 **last); + + int pcre32_get_substring(PCRE_SPTR32 subject, int *ovector, + int stringcount, int stringnumber, + PCRE_SPTR32 *stringptr); + + int pcre32_get_substring_list(PCRE_SPTR32 subject, + int *ovector, int stringcount, PCRE_SPTR32 **listptr); + + void pcre32_free_substring(PCRE_SPTR32 stringptr); + + void pcre32_free_substring_list(PCRE_SPTR32 *stringptr); + + +PCRE 32-BIT API AUXILIARY FUNCTIONS + + pcre32_jit_stack *pcre32_jit_stack_alloc(int startsize, int maxsize); + + void pcre32_jit_stack_free(pcre32_jit_stack *stack); + + void pcre32_assign_jit_stack(pcre32_extra *extra, + pcre32_jit_callback callback, void *data); + + const unsigned char *pcre32_maketables(void); + + int pcre32_fullinfo(const pcre32 *code, const pcre32_extra *extra, + int what, void *where); + + int pcre32_refcount(pcre32 *code, int adjust); + + int pcre32_config(int what, void *where); + + const char *pcre32_version(void); + + int pcre32_pattern_to_host_byte_order(pcre32 *code, + pcre32_extra *extra, const unsigned char *tables); + + +PCRE 32-BIT API INDIRECTED FUNCTIONS + + void *(*pcre32_malloc)(size_t); + + void (*pcre32_free)(void *); + + void *(*pcre32_stack_malloc)(size_t); + + void (*pcre32_stack_free)(void *); + + int (*pcre32_callout)(pcre32_callout_block *); + + +PCRE 32-BIT API 32-BIT-ONLY FUNCTION + + int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *output, + PCRE_SPTR32 input, int length, int *byte_order, + int keep_boms); + + +THE PCRE 32-BIT LIBRARY + + Starting with release 8.32, it is possible to compile a PCRE library + that supports 32-bit character strings, including UTF-32 strings, as + well as or instead of the original 8-bit library. This work was done by + Christian Persch, based on the work done by Zoltan Herczeg for the + 16-bit library. All three libraries contain identical sets of func- + tions, 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 and 32-bit libraries. This page + describes what is different when you use the 32-bit library. + + WARNING: A single application can be linked with all or any of the + three 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 pcre32_compile(), you + must do so with pcre32_study(), not pcre_study(), and you must free the + study data with pcre32_free_study(). + + +THE HEADER FILE + + There is only one header file, pcre.h. It contains prototypes for all + the functions in all libraries, as well as definitions of flags, struc- + tures, error codes, etc. + + +THE LIBRARY NAME + + In Unix-like systems, the 32-bit library is called libpcre32, and can + normally be accesss by adding -lpcre32 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 32-bit library, + strings are passed as vectors of unsigned 32-bit quantities. The macro + PCRE_UCHAR32 specifies an appropriate data type, and PCRE_SPTR32 is + defined as "const PCRE_UCHAR32 *". In very many environments, "unsigned + int" is a 32-bit data type. When PCRE is built, it defines PCRE_UCHAR32 + as "unsigned int", but checks that it really is a 32-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 32-bit + patterns and JIT stacks are pcre32 and pcre32_jit_stack respectively. + The type of the user-accessible structure that is returned by + pcre32_study() is pcre32_extra, and the type of the structure that is + used for passing data to a callout function is pcre32_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 32-bit instead of 8-bit types. + + +32-BIT FUNCTIONS + + For every function in the 8-bit library there is a corresponding func- + tion in the 32-bit library with a name that starts with pcre32_ instead + of pcre_. The prototypes are listed above. In addition, there is one + extra function, pcre32_utf32_to_host_byte_order(). This is a utility + function that converts a UTF-32 character string to host byte order if + necessary. The other 32-bit functions expect the strings they are + passed to be in host byte order. + + The input and output arguments of pcre32_utf32_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 32-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 32-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 32-bit units rather than bytes. + + +NAMED SUBPATTERNS + + The name-to-number translation table that is maintained for named sub- + patterns uses 32-bit characters. The pcre32_get_stringtable_entries() + function returns the length of each entry in the table as the number of + 32-bit data units. + + +OPTION NAMES + + There are two new general option names, PCRE_UTF32 and + PCRE_NO_UTF32_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-32 strings in the pcreunicode page. + + For the pcre32_config() function there is an option PCRE_CONFIG_UTF32 + that returns 1 if UTF-32 support is configured, otherwise 0. If this + option is given to pcre_config() or pcre16_config(), or if the + PCRE_CONFIG_UTF8 or PCRE_CONFIG_UTF16 option is given to pcre32_con- + fig(), the result is the PCRE_ERROR_BADOPTION error. + + +CHARACTER CODES + + In 32-bit mode, when PCRE_UTF32 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 0x7fffffff instead of 0 to 0xff. Charac- + ter 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-32 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 ill-formed in UTF-32. + + A UTF-32 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 + pcre32_utf32_to_host_byte_order() is provided to help with this (see + above). + + +ERROR NAMES + + The error PCRE_ERROR_BADUTF32 corresponds to its 8-bit counterpart. + 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 pcre32_exec(). + + There are new error codes whose names begin with PCRE_UTF32_ERR for + invalid UTF-32 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-32 errors + are: + + PCRE_UTF32_ERR1 Surrogate character (range from 0xd800 to 0xdfff) + PCRE_UTF32_ERR2 Non-character + PCRE_UTF32_ERR3 Character > 0x10ffff + + +ERROR TEXTS + + If there is an error while compiling a pattern, the error text that is + passed back by pcre32_compile() or pcre32_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 32-bit vectors. + + +TESTING + + The pcretest program continues to operate with 8-bit input and output + files, but it can be used for testing the 32-bit library. If it is run + with the command line option -32, patterns and subject strings are con- + verted from 8-bit to 32-bit before being passed to PCRE, and the 32-bit + library functions are used instead of the 8-bit ones. Returned 32-bit + strings are converted to 8-bit for output. If both the 8-bit and the + 16-bit libraries were not compiled, pcretest defaults to 32-bit and the + -32 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, + 16-bit and 32-bit libraries has been built, and runs the tests appro- + priately. + + +NOT SUPPORTED IN 32-BIT MODE + + Not all the features of the 8-bit library are available with the 32-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: 08 November 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREBUILD(3) PCREBUILD(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +PCRE BUILD-TIME OPTIONS + + This document describes the optional features of PCRE that can be + selected when the library is compiled. It assumes use of the configure + script, where the optional features are selected or deselected by pro- + viding options to configure before running the make command. However, + the same options can be selected in both Unix-like and non-Unix-like + environments using the GUI facility of cmake-gui if you are using CMake + instead of configure to build PCRE. + + There is a lot more information about building PCRE without using con- + figure (including information about using CMake or building "by hand") + in the file called NON-AUTOTOOLS-BUILD, which is part of the PCRE dis- + tribution. You should consult this file as well as the README file if + you are building in a non-Unix-like environment. + + The complete list of options for configure (which includes the standard + ones such as the selection of the installation directory) can be + obtained by running + + ./configure --help + + The following sections include descriptions of options whose names + begin with --enable or --disable. These settings specify changes to the + defaults for the configure command. Because of the way that configure + works, --enable and --disable always come in pairs, so the complemen- + tary option always exists as well, but as it specifies the default, it + is not described. + + +BUILDING 8-BIT, 16-BIT AND 32-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. You can also build a separate library, called + libpcre32, in which strings are contained in vectors of 32-bit data + units and interpreted either as single-unit characters or UTF-32 + strings, by adding + + --enable-pcre32 + + to the configure command. If you do not want the 8-bit library, add + + --disable-pcre8 + + as well. At least one of the three 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 or 32-bit libraries. + + +BUILDING SHARED AND STATIC LIBRARIES + + The PCRE building process uses libtool to build both shared and static + Unix libraries by default. You can suppress one of these by adding one + of + + --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, UTF-16 AND UTF-32 SUPPORT + + To build PCRE with support for UTF Unicode character strings, add + + --enable-utf + + to the configure command. This setting applies to all three libraries, + adding support for UTF-8 to the 8-bit library, support for UTF-16 to + the 16-bit library, and support for UTF-32 to the to the 32-bit + library. There are no separate options for enabling UTF-8, UTF-16 and + UTF-32 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 another with- + out 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, + UTF-16 or UTF-32. As well as compiling PCRE with this option, you also + have have to set the PCRE_UTF8, PCRE_UTF16 or PCRE_UTF32 option (as + appropriate) when you call one of the pattern 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 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 support, even if you have + not explicitly requested it. + + Including Unicode property support adds around 30K of tables to the + PCRE library. Only the general category properties such as Lu and Nd + 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 + the end of a line. This is the normal newline character on Unix-like + systems. You can compile PCRE to use carriage return (CR) instead, by + adding + + --enable-newline-is-cr + + to the configure command. There is also a --enable-newline-is-lf + option, which explicitly specifies linefeed as the newline character. + + Alternatively, you can specify that line endings are to be indicated by + the two character sequence CRLF. If you want this, add + + --enable-newline-is-crlf + + to the configure command. There is a fourth option, specified by + + --enable-newline-is-anycrlf + + which causes PCRE to recognize any of the three sequences CR, LF, or + CRLF as indicating a line ending. Finally, a fifth option, specified by + + --enable-newline-is-any + + causes PCRE to recognize any Unicode newline sequence. + + Whatever line ending convention is selected when PCRE is built can be + overridden when the library functions are called. At build time it is + conventional to use the standard for your operating system. + + +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 + + --enable-bsr-anycrlf + + the default is changed so that \R matches only CR, LF, or CRLF. What- + ever is selected when PCRE is built can be overridden when the library + functions are called. + + +POSIX MALLOC USAGE + + 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 + + to the configure command. + + +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 alter- + nation metacharacter). By default, in the 8-bit and 16-bit libraries, + 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 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. For the + 16-bit library, a value of 3 is rounded up to 4. In these libraries, + using longer offsets slows down the operation of PCRE because it has to + load additional data when handling them. For the 32-bit library the + value is always 4 and cannot be overridden; the value of --with-link- + size is ignored. + + +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 + 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. + 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 + 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 + 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 + setting such as + + --with-match-limit=500000 + + 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 + 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- + 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 + by adding, for example, + + --with-match-limit-recursion=10000 + + 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 + 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 + the 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 + + 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-utf. + + The EBCDIC character that corresponds to an ASCII LF is assumed to have + the value 0x15 by default. However, in some EBCDIC environments, 0x25 + is used. In such an environment you should use + + --enable-ebcdic-nl25 + + as well as, or instead of, --enable-ebcdic. The EBCDIC character for CR + has the same value as in ASCII, namely, 0x0d. Whichever of 0x15 and + 0x25 is not chosen as LF is made to correspond to the Unicode NEL char- + acter (which, in Unicode, is 0x85). + + The options that select newline behaviour, such as --enable-newline-is- + cr, and equivalent run-time options, refer to these character values in + an EBCDIC environment. + + +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 them + with libz or libbz2, respectively, by adding one or both of + + --enable-pcregrep-libz + --enable-pcregrep-libbz2 + + to the configure command. These options naturally require that the rel- + 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 + + --enable-pcretest-libreadline + + to the configure command, pcretest is linked with the libreadline + library, and when its input is from a terminal, it reads it using the + readline() function. This provides line-editing and history facilities. + Note that libreadline is GPL-licensed, so if you distribute a binary of + pcretest linked in this way, there may be licensing issues. + + Setting this option causes the -lreadline option to be added to the + pcretest build. In many operating environments with a sytem-installed + libreadline this is sufficient. However, in some environments (e.g. if + an unmodified distribution version of readline is in use), some extra + configuration may be necessary. The INSTALL file for libreadline says + this: + + "Readline uses the termcap functions, but does not link with the + termcap or curses library itself, allowing applications which link + with readline the to choose an appropriate library." + + If your environment has not been set up so that an appropriate library + is automatically included, you may need to add something like + + LIBS="-ncurses" + + immediately before the configure command. + + +DEBUGGING WITH VALGRIND SUPPORT + + By adding the + + --enable-valgrind + + option to to the configure command, PCRE will use valgrind annotations + to mark certain memory regions as unaddressable. This allows it to + detect invalid memory accesses, and is mostly useful for debugging PCRE + itself. + + +CODE COVERAGE REPORTING + + If your C compiler is gcc, you can build a version of PCRE that can + generate a code coverage report for its test suite. To enable this, you + must install lcov version 1.6 or above. Then specify + + --enable-coverage + + to the configure command and build PCRE in the usual way. + + Note that using ccache (a caching C compiler) is incompatible with code + coverage reporting. If you have configured ccache to run automatically + on your system, you must set the environment variable + + CCACHE_DISABLE=1 + + before running make to build PCRE, so that ccache is not used. + + When --enable-coverage is used, the following addition targets are + added to the Makefile: + + make coverage + + This creates a fresh coverage report for the PCRE test suite. It is + equivalent to running "make coverage-reset", "make coverage-baseline", + "make check", and then "make coverage-report". + + make coverage-reset + + This zeroes the coverage counters, but does nothing else. + + make coverage-baseline + + This captures baseline coverage information. + + make coverage-report + + This creates the coverage report. + + make coverage-clean-report + + This removes the generated coverage report without cleaning the cover- + age data itself. + + make coverage-clean-data + + This removes the captured coverage data without removing the coverage + files created at compile time (*.gcno). + + make coverage-clean + + This cleans all coverage data including the generated coverage report. + For more information about code coverage, see the gcov and lcov docu- + mentation. + + +SEE ALSO + + pcreapi(3), pcre16, pcre32, pcre_config(3). + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 30 October 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREMATCHING(3) PCREMATCHING(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +PCRE MATCHING ALGORITHMS + + This document describes the two different algorithms that are available + in PCRE for matching a compiled regular expression against a given sub- + ject string. The "standard" algorithm is the one provided by the + pcre_exec(), pcre16_exec() and pcre32_exec() functions. These work in + the same as 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 func- + tions. + + An alternative algorithm is provided by the pcre_dfa_exec(), + pcre16_dfa_exec() and pcre32_dfa_exec() functions; they operate in a + different way, and are not Perl-compatible. This alternative has advan- + tages 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 + arises, however, when there are multiple possibilities. For example, if + the pattern + + ^<.*> + + is matched against the string + + + + there are three possible answers. The standard algorithm finds only one + of them, whereas the alternative algorithm finds all three. + + +REGULAR EXPRESSIONS AS TREES + + The set of strings that are matched by a regular expression can be rep- + resented as a tree structure. An unlimited repetition in the pattern + makes the tree of infinite size, but it is still a tree. Matching the + pattern to a given subject string (from a given starting point) can be + thought of as a search of the tree. There are two ways to search a + tree: depth-first and breadth-first, and these correspond to the two + matching algorithms provided by PCRE. + + +THE STANDARD MATCHING ALGORITHM + + In the terminology of Jeffrey Friedl's book "Mastering Regular Expres- + sions", the standard algorithm is an "NFA algorithm". It conducts a + depth-first search of the pattern tree. That is, it proceeds along a + single path through the tree, checking that the subject matches what is + required. When there is a mismatch, the algorithm tries any alterna- + tives at the current point, and if they all fail, it backs up to the + previous branch point in the tree, and tries the next alternative + branch at that level. This often involves backing up (moving to the + left) in the subject string as well. The order in which repetition + branches are tried is controlled by the greedy or ungreedy nature of + the quantifier. + + If a leaf node is reached, a matching string has been found, and at + that point the algorithm stops. Thus, if there is more than one possi- + ble match, this algorithm returns the first one that it finds. Whether + this is the shortest, the longest, or some intermediate length depends + on the way the greedy and ungreedy repetition quantifiers are specified + in the pattern. + + Because it ends up with a single path through the tree, it is rela- + tively straightforward for this algorithm to keep track of the sub- + strings that are matched by portions of the pattern in parentheses. + This provides support for capturing parentheses and back references. + + +THE ALTERNATIVE MATCHING ALGORITHM + + This algorithm conducts a breadth-first search of the tree. Starting + from the first matching point in the subject, it scans the subject + string from left to right, once, character by character, and as it does + this, it remembers all the paths through the tree that represent valid + matches. In Friedl's terminology, this is a kind of "DFA algorithm", + though it is not implemented as a traditional finite state machine (it + keeps multiple states active simultaneously). + + Although the general principle of this matching algorithm is that it + scans the subject string only once, without backtracking, there is one + exception: when a lookaround assertion is encountered, the characters + following or preceding the current point have to be independently + inspected. + + The scan continues until either the end of the subject is reached, or + there are no more unterminated paths. At this point, terminated paths + represent the different matching possibilities (if there are none, the + match has failed). Thus, if there is more than one possible match, + this algorithm finds all of them, and in particular, it finds the long- + est. The matches are returned in decreasing order of length. There is + an option to stop the algorithm after the first match (which is neces- + sarily the shortest) is found. + + Note that all the matches that are found start at the same point in the + subject. If the pattern + + cat(er(pillar)?)? + + is matched against the string "the caterpillar catchment", the result + will be the three strings "caterpillar", "cater", and "cat" that start + at the fifth character of the subject. The algorithm does not automati- + cally move on to find matches that start at later positions. + + There are a number of features of PCRE regular expressions that are not + supported by the alternative matching algorithm. They are as follows: + + 1. Because the algorithm finds all possible matches, the greedy or + ungreedy nature of repetition quantifiers is not relevant. Greedy and + ungreedy quantifiers are treated in exactly the same way. However, pos- + sessive quantifiers can make a difference when what follows could also + match what is quantified, for example in a pattern like this: + + ^a++\w! + + This pattern matches "aaab!" but not "aaa!", which would be matched by + a non-possessive quantifier. Similarly, if an atomic group is present, + it is matched as if it were a standalone pattern at the current point, + and the longest match is then "locked in" for the rest of the overall + pattern. + + 2. When dealing with multiple paths through the tree simultaneously, it + is not straightforward to keep track of captured substrings for the + different matching possibilities, and PCRE's implementation of this + algorithm does not attempt to do this. This means that no captured sub- + strings are available. + + 3. Because no substrings are captured, back references within the pat- + tern are not supported, and cause errors if encountered. + + 4. For the same reason, conditional expressions that use a backrefer- + ence as the condition or test for a specific group recursion are not + supported. + + 5. Because many paths through the tree may be active, the \K escape + sequence, which resets the start of the match when encountered (but may + be on some paths and not on others), is not supported. It causes an + error if encountered. + + 6. Callouts are supported, but the value of the capture_top field is + always 1, and the value of the capture_last field is always -1. + + 7. The \C escape sequence, which (in the standard algorithm) always + matches a single data unit, even in UTF-8, UTF-16 or UTF-32 modes, is + not supported in these modes, because the alternative algorithm moves + 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 + negative assertion. + + +ADVANTAGES OF THE ALTERNATIVE ALGORITHM + + 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 + 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 (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 + because it is less susceptible to optimization. + + 2. Capturing parentheses and back references are not supported. + + 3. Although atomic groups are supported, their use does not provide the + performance advantage that it does for the standard algorithm. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 08 January 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREAPI(3) PCREAPI(3) + + +NAME + PCRE - Perl-compatible regular expressions + + #include + + +PCRE NATIVE API BASIC FUNCTIONS + + pcre *pcre_compile(const char *pattern, int options, + const char **errptr, int *erroffset, + const unsigned char *tableptr); + + pcre *pcre_compile2(const char *pattern, int options, + int *errorcodeptr, + const char **errptr, int *erroffset, + const unsigned char *tableptr); + + 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); + + int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, + const char *subject, int length, int startoffset, + 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, + char *buffer, int buffersize); + + int pcre_copy_substring(const char *subject, int *ovector, + int stringcount, int stringnumber, char *buffer, + int buffersize); + + int pcre_get_named_substring(const pcre *code, + const char *subject, int *ovector, + int stringcount, const char *stringname, + const char **stringptr); + + int pcre_get_stringnumber(const pcre *code, + const char *name); + + int pcre_get_stringtable_entries(const pcre *code, + const char *name, char **first, char **last); + + int pcre_get_substring(const char *subject, int *ovector, + int stringcount, int stringnumber, + const char **stringptr); + + int pcre_get_substring_list(const char *subject, + int *ovector, int stringcount, const char ***listptr); + + void pcre_free_substring(const char *stringptr); + + void pcre_free_substring_list(const char **stringptr); + + +PCRE NATIVE API AUXILIARY FUNCTIONS + + int pcre_jit_exec(const pcre *code, const pcre_extra *extra, + const char *subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + pcre_jit_stack *jstack); + + 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_refcount(pcre *code, int adjust); + + int pcre_config(int what, void *where); + + 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); + + void (*pcre_free)(void *); + + void *(*pcre_stack_malloc)(size_t); + + void (*pcre_stack_free)(void *); + + int (*pcre_callout)(pcre_callout_block *); + + +PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES + + As well as support for 8-bit character strings, PCRE also supports + 16-bit strings (from release 8.30) and 32-bit strings (from release + 8.32), by means of two additional libraries. They can be built as well + as, or instead of, the 8-bit library. To avoid too much complication, + this document describes the 8-bit versions of the functions, with only + occasional references to the 16-bit and 32-bit libraries. + + The 16-bit and 32-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_ or pcre32_ instead of + pcre_. For every option that has UTF8 in its name (for example, + PCRE_UTF8), there are corresponding 16-bit and 32-bit names with UTF8 + replaced by UTF16 or UTF32, respectively. This facility is in fact just + cosmetic; the 16-bit and 32-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, or 32-bit data quantities and UTF-32 when using the 32-bit + library, unless specified otherwise. More details of the specific dif- + ferences for the 16-bit and 32-bit libraries are given in the pcre16 + and pcre32 pages. + + +PCRE API OVERVIEW + + PCRE has its own native API, which is described in this document. There + are also some wrapper functions (for the 8-bit library only) that cor- + respond to the POSIX regular expression API, but they do not give + access to all the functionality. They are described in the pcreposix + documentation. Both of these APIs define a set of C function calls. A + 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- + 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 PCRE source distribution. A listing of this program is given in the + 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. + + From release 8.32 there is also a direct interface for JIT execution, + which gives improved performance. The JIT-specific functions are dis- + cussed in the pcrejit documentation. + + A second matching function, pcre_dfa_exec(), which is not Perl-compati- + ble, is also provided. This uses a different algorithm for the match- + ing. The alternative algorithm finds all possible matches (at a given + point in the subject), and scans the subject just once (unless there + are lookbehind assertions). However, this algorithm does not return + captured substrings. A description of the two matching algorithms and + their advantages and disadvantages is given in the pcrematching docu- + mentation. + + 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: + + pcre_copy_substring() + pcre_copy_named_substring() + pcre_get_substring() + pcre_get_named_substring() + pcre_get_substring_list() + pcre_get_stringnumber() + pcre_get_stringtable_entries() + + 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 + built are used. + + The function pcre_fullinfo() is used to find out information about a + compiled pattern. The function pcre_version() returns a pointer to a + 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 + 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- + tively. PCRE calls the memory management functions via these variables, + 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 + 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- + 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 + pcrecallout documentation. + + +NEWLINES + + 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 (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 + 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 + 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 + dollar metacharacters, the handling of #-comments in /x mode, and, when + 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, + which is controlled in a similar way, but by separate options. + + +MULTITHREADING + + 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- + 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, 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 + + int pcre_config(int what, void *where); + + The function pcre_config() makes it possible for a PCRE client to dis- + cover which optional features have been compiled into the PCRE library. + The pcrebuild documentation has more details about these optional fea- + tures. + + The first argument for pcre_config() is an integer, specifying which + information is required; the second argument is a pointer to a variable + into which the information is placed. The returned value is zero on + success, or the negative error code PCRE_ERROR_BADOPTION if the value + in the first argument is not recognized. The following information is + available: + + PCRE_CONFIG_UTF8 + + The output is an integer that is set to one if UTF-8 support is avail- + able; otherwise it is set to zero. This value should normally be given + to the 8-bit version of this function, pcre_config(). If it is given to + the 16-bit or 32-bit version of this function, the result is + 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 or 32-bit version of this function, the result is + PCRE_ERROR_BADOPTION. + + PCRE_CONFIG_UTF32 + + The output is an integer that is set to one if UTF-32 support is avail- + able; otherwise it is set to zero. This value should normally be given + to the 32-bit version of this function, pcre32_config(). If it is given + to the 8-bit or 16-bit version of this function, the result is + 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 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 values that are + supported in ASCII/Unicode environments are: 10 for LF, 13 for CR, 3338 + for CRLF, -2 for ANYCRLF, and -1 for ANY. In EBCDIC environments, CR, + ANYCRLF, and ANY yield the same values. However, the value for LF is + normally 21, though some EBCDIC environments use 37. The corresponding + values for CRLF are 3349 and 3365. The default should normally corre- + 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 + 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. For the 8-bit + library, the value can be 2, 3, or 4. For the 16-bit library, the value + is either 2 or 4 and is still a number of bytes. For the 32-bit + 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 + 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. + 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() + below. + + PCRE_CONFIG_STACKRECURSE + + 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 + 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 + blocks on the heap, thus avoiding the use of the stack. + + +COMPILING A PATTERN + + pcre *pcre_compile(const char *pattern, int options, + const char **errptr, int *erroffset, + const unsigned char *tableptr); + + pcre *pcre_compile2(const char *pattern, int options, + int *errorcodeptr, + const char **errptr, int *erroffset, + const unsigned char *tableptr); + + 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 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 + 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 + 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- + 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 + 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_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 + sets the variable pointed to by errptr to point to a textual error mes- + sage. This is a static string that is part of the library. You must not + try to free it. Normally, the offset from the start of the pattern to + the byte that was being processed when the error was discovered is + 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 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 + 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 + 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- + pile(): + + pcre *re; + const char *error; + int erroffset; + re = pcre_compile( + "^A.*Z", /* the pattern */ + 0, /* default options */ + &error, /* for error message */ + &erroffset, /* for error offset */ + NULL); /* use default character tables */ + + 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 + 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 + 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, + 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 + 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 + 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- + 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 + 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 + 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 + 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 + the pcrepattern documentation. + + PCRE_EXTENDED + + If this bit is set, white space data characters in the pattern are + totally ignored except when escaped or inside a character class. White + space does not include the VT character (code 11). In addition, charac- + ters between an unescaped # outside a character class and the next new- + line, inclusive, are also ignored. This is equivalent to Perl's /x + option, and it can be changed within a pattern by a (?x) option set- + ting. + + 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 + 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. + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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, + setting PCRE_MULTILINE has no effect. + + PCRE_NEWLINE_CR + PCRE_NEWLINE_LF + PCRE_NEWLINE_CRLF + 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 + that any of the three preceding sequences should be recognized. Setting + PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be + recognized. + + In an ASCII/Unicode environment, 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 sep- + arator, U+2028), and PS (paragraph separator, U+2029). For the 8-bit + library, the last two are recognized only in UTF-8 mode. + + When PCRE is compiled to run in an EBCDIC (mainframe) environment, the + code for CR is 0x0d, the same as ASCII. However, the character code for + LF is normally 0x15, though in some EBCDIC environments 0x25 is used. + Whichever of these is not LF is made to correspond to Unicode's NEL + character. EBCDIC codes are all less than 256. For more details, see + the pcrebuild documentation. + + 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- + ble. For example, PCRE_NEWLINE_CR with PCRE_NEWLINE_LF is equivalent to + 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 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 + is used for pcre_exec() and pcre_dfa_exec(), but it can be overridden. + + 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). + 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 + 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- + 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 + 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 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 pcreunicode page. If an invalid UTF-8 sequence is + found, pcre_compile() returns an error. If you already know that your + pattern is valid, and you want to skip this check for performance rea- + sons, you can set the PCRE_NO_UTF8_CHECK option. When it is set, the + effect of passing an invalid UTF-8 string as a pattern is undefined. It + may cause your program to crash. Note that this option can also be + passed to pcre_exec() and pcre_dfa_exec(), to suppress the validity + checking of subject strings only. If the same string is being matched + many times, the option can be safely set for the second and subsequent + matchings to improve performance. + + +COMPILATION ERROR CODES + + The following table lists the error codes than may be returned by + pcre_compile2(), along with the error messages that may be returned by + both compiling functions. Note that error messages are always 8-bit + ASCII strings, even in 16-bit or 32-bit mode. As PCRE has developed, + some error codes have fallen out of use. To avoid confusion, they have + not been re-used. + + 0 no error + 1 \ at end of pattern + 2 \c at end of pattern + 3 unrecognized character follows \ + 4 numbers out of order in {} quantifier + 5 number too big in {} quantifier + 6 missing terminating ] for character class + 7 invalid escape sequence in character class + 8 range out of order in character class + 9 nothing to repeat + 10 [this code is not in use] + 11 internal error: unexpected repeat + 12 unrecognized character after (? or (?- + 13 POSIX named classes are supported only within a class + 14 missing ) + 15 reference to non-existent subpattern + 16 erroffset passed as NULL + 17 unknown option bit(s) set + 18 missing ) after comment + 19 [this code is not in use] + 20 regular expression is too large + 21 failed to get memory + 22 unmatched parentheses + 23 internal error: code overflow + 24 unrecognized character after (?< + 25 lookbehind assertion is not fixed length + 26 malformed number or name after (?( + 27 conditional group contains more than two branches + 28 assertion expected after (?( + 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 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{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 (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 in 8-bit non-UTF-8 mode + 52 internal error: overran compiling workspace + 53 internal error: previously-checked referenced subpattern + not found + 54 DEFINE group contains more than one branch + 55 repeating a DEFINE group is not allowed + 56 inconsistent NEWLINE options + 57 \g is not followed by a braced, angle-bracketed, or quoted + name/number or by a plain number + 58 a numbered reference must not be zero + 59 an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) + 60 (*VERB) not recognized + 61 number is too big + 62 subpattern name expected + 63 digit expected after (?+ + 64 ] is an invalid data character in JavaScript compatibility mode + 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 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 + 77 invalid UTF-32 string (specifically UTF-32) + + The numbers 32 and 10000 in errors 48 and 49 are defaults; different + values may be used if the limits were changed when PCRE was built. + + +STUDYING A PATTERN + + pcre_extra *pcre_study(const pcre *code, int options + const char **errptr); + + If a compiled pattern is going to be used several times, it is worth + spending more time analyzing it in order to speed up the time taken for + matching. The function pcre_study() takes a pointer to a compiled pat- + tern as its first argument. If studying the pattern produces additional + information that will help speed up matching, pcre_study() returns a + pointer to a pcre_extra block, in which the study_data field points to + the results of the study. + + The returned value from pcre_study() can be passed directly to + pcre_exec() or pcre_dfa_exec(). However, a pcre_extra block also con- + tains other fields that can be set by the caller before the block is + passed; these are described below in the section on matching a pattern. + + If studying the pattern does not produce any useful information, + pcre_study() returns NULL by default. In that circumstance, if the + calling program wants to pass any of the other fields to pcre_exec() or + pcre_dfa_exec(), it must set up its own pcre_extra block. However, if + pcre_study() is called with the PCRE_STUDY_EXTRA_NEEDED option, it + returns a pcre_extra block even if studying did not find any additional + information. It may still return NULL, however, if an error occurs in + pcre_study(). + + The second argument of pcre_study() contains option bits. There are + three further options in addition to PCRE_STUDY_EXTRA_NEEDED: + + PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + + If any of these are set, and the just-in-time compiler is available, + the pattern is further compiled into machine code that executes much + faster than the pcre_exec() interpretive matching function. If the + just-in-time compiler is not available, these options are ignored. All + undefined bits in the options argument must be zero. + + JIT compilation is a heavyweight optimization. It can take some time + for patterns to be analyzed, and for one-off matches and simple pat- + terns the benefit of faster execution might be offset by a much slower + 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 + points to is set to NULL. Otherwise it is set to point to a textual + error message. This is a static string that is part of the library. You + must not try to free it. You should test the error pointer for NULL + after calling pcre_study(), to be sure that it has run successfully. + + When you are finished with a pattern, you can free the memory used for + 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): + + 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 */ + &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 mean that there are any strings of that length that match, but + it does guarantee that no shorter strings match. The value is used to + avoid wasting time by trying to match strings that are shorter than the + lower bound. You can find out the value in a calling program via the + pcre_fullinfo() function. + + Studying a pattern is also useful for non-anchored patterns that do not + have a single fixed starting character. A bitmap of possible starting + bytes is created. This speeds up finding a position in the subject at + which to start matching. (In 16-bit mode, the bitmap is used for 16-bit + values less than 256. In 32-bit mode, the bitmap is used for 32-bit + values less than 256.) + + 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 + never match escapes such as \w or \d, but they can be tested with \p if + PCRE is built with Unicode character property support. Alternatively, + the PCRE_UCP option can be set at compile time; this causes \w and + friends to use Unicode property support instead of built-in tables. The + use of locales with Unicode is discouraged. If you are handling charac- + ters with codes greater than 128, you should either use UTF-8 and Uni- + code, or use locales, but not try to mix the two. + + PCRE 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 + application that calls PCRE. These may be created in a different locale + 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 + 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; + 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 + 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() + 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 + 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 + + 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 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_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() */ + sd, /* result of pcre_study(), or NULL */ + PCRE_INFO_SIZE, /* what is required */ + &length); /* where to put the data */ + + The possible values for the third argument are defined in pcre.h, and + are as follows: + + PCRE_INFO_BACKREFMAX + + Return the number of the highest back reference in the pattern. The + fourth argument should point to an int variable. Zero is returned if + there are no back references. + + PCRE_INFO_CAPTURECOUNT + + Return the number of capturing subpatterns in the pattern. The fourth + argument should point to an int variable. + + PCRE_INFO_DEFAULT_TABLES + + Return a pointer to the internal default character tables within PCRE. + The fourth argument should point to an unsigned char * variable. This + information call is provided for internal use by the pcre_study() func- + tion. External callers can cause PCRE to use its internal tables by + passing a NULL table pointer. + + PCRE_INFO_FIRSTBYTE + + 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. In the 32-bit library the value can be up to + 0x10ffff. + + If there is no fixed first value, and if either + + (a) the pattern was compiled with the PCRE_MULTILINE option, and every + branch starts with "^", or + + (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not + set (if it were set, the pattern would be anchored), + + -1 is returned, indicating that the pattern matches only at the start + of a subject string or after any newline within the string. Otherwise + -2 is returned. For anchored patterns, -2 is returned. + + Since for the 32-bit library using the non-UTF-32 mode, this function + is unable to return the full 32-bit range of the character, this value + is deprecated; instead the PCRE_INFO_FIRSTCHARACTERFLAGS and + PCRE_INFO_FIRSTCHARACTER values should be used. + + PCRE_INFO_FIRSTTABLE + + If the pattern was studied, and this resulted in the construction of a + 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 + + Return 1 if the pattern contains any explicit matches for CR or LF + characters, otherwise 0. The fourth argument should point to an int + variable. An explicit match is either a literal CR or LF character, or + \r or \n. + + PCRE_INFO_JCHANGED + + Return 1 if the (?J) or (?-J) option setting is used in the pattern, + otherwise 0. The fourth argument should point to an int variable. (?J) + and (?-J) set and unset the local PCRE_DUPNAMES option, respectively. + + PCRE_INFO_JIT + + Return 1 if the pattern was studied with one of the JIT options, and + just-in-time compiling was successful. The fourth argument should point + to an int variable. A return value of 0 means that JIT support is not + available in this version of PCRE, or that the pattern was not studied + with a JIT option, or that the JIT compiler could not handle this par- + ticular pattern. See the pcrejit documentation for details of what can + and cannot be handled. + + PCRE_INFO_JITSIZE + + If the pattern was successfully studied with a JIT option, return the + size of the JIT compiled code, otherwise return zero. The fourth argu- + ment should point to a size_t variable. + + PCRE_INFO_LASTLITERAL + + Return the value of the rightmost literal 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. + + Since for the 32-bit library using the non-UTF-32 mode, this function + is unable to return the full 32-bit range of the character, this value + is deprecated; instead the PCRE_INFO_REQUIREDCHARFLAGS and + PCRE_INFO_REQUIREDCHAR values should be used. + + 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, 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 + PCRE_INFO_NAMETABLE + + PCRE supports the use of named as well as numbered capturing parenthe- + ses. The names are just an additional way of identifying the parenthe- + ses, which still acquire numbers. Several convenience functions such as + pcre_get_named_substring() are provided for extracting captured sub- + strings by name. It is also possible to extract the data directly, by + first converting the name to a number in order to access the correct + pointers in the output vector (described with pcre_exec() below). To do + the conversion, you need to use the name-to-number map, which is + described by these three values. + + The map consists of a number of fixed-size entries. PCRE_INFO_NAMECOUNT + 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. 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. In the 32-bit library, the + pointer points to 32-bit data units, the first of which contains the + parenthesis number. The rest of the entry is the corresponding name, + zero terminated. + + The names are in alphabetical order. Duplicate names may appear if (?| + is used to create multiple groups with the same number, as described in + the section on duplicate subpattern numbers in the pcrepattern page. + Duplicate names for subpatterns with different numbers are permitted + only if PCRE_DUPNAMES is set. In all cases of duplicate names, they + appear in the table in the order in which they were found in the pat- + tern. In the absence of (?| this is the order of increasing number; + when (?| is used this is not necessarily the case because later subpat- + terns may have lower numbers. + + As a simple example of the name/number table, consider the following + 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) ) + + There are four named subpatterns, so the table has four entries, and + each entry in the table is eight bytes long. The table is as follows, + with non-printing bytes shows in hexadecimal, and undefined bytes shown + as ??: + + 00 01 d a t e 00 ?? + 00 05 d a y 00 ?? ?? + 00 04 m o n t h 00 + 00 02 y e a r 00 ?? + + When writing code to extract data from named subpatterns using the + name-to-number map, remember that the length of the entries is likely + to be different for each compiled pattern. + + PCRE_INFO_OKPARTIAL + + Return 1 if the pattern can be used for partial matching with + pcre_exec(), otherwise 0. The fourth argument should point to an int + variable. From release 8.00, this always returns 1, because the + restrictions that previously applied to partial matching have been + lifted. The pcrepartial documentation gives details of partial match- + ing. + + PCRE_INFO_OPTIONS + + Return a copy of the options with which the pattern was compiled. The + fourth argument should point to an unsigned long int variable. These + option bits are those specified in the call to pcre_compile(), modified + by any top-level option settings at the start of the pattern itself. In + other words, they are the options that will be in force when matching + starts. For example, if the pattern /(?im)abc(?-i)d/ is compiled with + the PCRE_EXTENDED option, the result is PCRE_CASELESS, PCRE_MULTILINE, + and PCRE_EXTENDED. + + A pattern is automatically anchored by PCRE if all of its top-level + alternatives begin with one of the following: + + ^ unless PCRE_MULTILINE is set + \A always + \G always + .* if PCRE_DOTALL is set and there are no back + references to the subpattern in which .* appears + + For such patterns, the PCRE_ANCHORED bit is set in the options returned + by pcre_fullinfo(). + + PCRE_INFO_SIZE + + Return the size of the compiled pattern in bytes (for both libraries). + The fourth argument should point to a size_t variable. This value does + not include the size of the pcre structure that is returned by + pcre_compile(). The value that is passed as the argument to pcre_mal- + loc() when pcre_compile() is getting memory in which to place the com- + piled data is the value returned by this option plus the size of the + pcre structure. Studying a compiled pattern, with or without JIT, does + not alter the value returned by this option. + + PCRE_INFO_STUDYSIZE + + Return the size in bytes of the data block pointed to by the study_data + field in a pcre_extra block. If pcre_extra is NULL, or there is no + study data, zero is returned. The fourth argument should point to a + size_t variable. The study_data field is set by pcre_study() to record + information that will speed up matching (see the section entitled + "Studying a pattern" above). The format of the study_data block is pri- + vate, but its length is made available via this option so that it can + be saved and restored (see the pcreprecompile documentation for + details). + + PCRE_INFO_FIRSTCHARACTERFLAGS + + Return information about the first data unit of any matched string, for + a non-anchored pattern. The fourth argument should point to an int + variable. + + If there is a fixed first value, for example, the letter "c" from a + pattern such as (cat|cow|coyote), 1 is returned, and the character + value can be retrieved using PCRE_INFO_FIRSTCHARACTER. + + If there is no fixed first value, and if either + + (a) the pattern was compiled with the PCRE_MULTILINE option, and every + branch starts with "^", or + + (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not + set (if it were set, the pattern would be anchored), + + 2 is returned, indicating that the pattern matches only at the start of + a subject string or after any newline within the string. Otherwise 0 is + returned. For anchored patterns, 0 is returned. + + PCRE_INFO_FIRSTCHARACTER + + Return the fixed first character value, if PCRE_INFO_FIRSTCHARACTER- + FLAGS returned 1; otherwise returns 0. The fourth argument should point + to an uint_t variable. + + In the 8-bit library, the value is always less than 256. In the 16-bit + library the value can be up to 0xffff. In the 32-bit library in UTF-32 + mode the value can be up to 0x10ffff, and up to 0xffffffff when not + using UTF-32 mode. + + If there is no fixed first value, and if either + + (a) the pattern was compiled with the PCRE_MULTILINE option, and every + branch starts with "^", or + + (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not + set (if it were set, the pattern would be anchored), + + -1 is returned, indicating that the pattern matches only at the start + of a subject string or after any newline within the string. Otherwise + -2 is returned. For anchored patterns, -2 is returned. + + PCRE_INFO_REQUIREDCHARFLAGS + + Returns 1 if there is a rightmost literal data unit that must exist in + any matched string, other than at its start. The fourth argument should + point to an int variable. If there is no such value, 0 is returned. If + returning 1, the character value itself can be retrieved using + PCRE_INFO_REQUIREDCHAR. + + For anchored patterns, a last literal value is recorded only if it fol- + lows something of variable length. For example, for the pattern + /^a\d+z\d+/ the returned value 1 (with "z" returned from + PCRE_INFO_REQUIREDCHAR), but for /^a\dz\d/ the returned value is 0. + + PCRE_INFO_REQUIREDCHAR + + Return the value of the rightmost literal data unit that must exist in + any matched string, other than at its start, if such a value has been + recorded. The fourth argument should point to an uint32_t variable. If + there is no such value, 0 is returned. + + +REFERENCE COUNTS + + int pcre_refcount(pcre *code, int adjust); + + 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, + 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 + 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 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 + whose byte-order is different. (This seems a highly unlikely scenario.) + + +MATCHING A PATTERN: THE TRADITIONAL FUNCTION + + int pcre_exec(const pcre *code, const pcre_extra *extra, + const char *subject, int length, int startoffset, + int options, int *ovector, int ovecsize); + + The function pcre_exec() is called to match a subject string against a + compiled pattern, which is passed in the code argument. If the pattern + was studied, the result of the study should be passed in the extra + argument. You can call pcre_exec() with the same code and extra argu- + ments as many times as you like, in order to match different subject + 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 + is possible to save compiled patterns and study data, and then use them + 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(): + + int rc; + int ovector[30]; + rc = pcre_exec( + re, /* result of pcre_compile() */ + NULL, /* we didn't study the pattern */ + "some string", /* the subject string */ + 11, /* the length of the subject string */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + ovector, /* vector of integers for substring information */ + 30); /* number of elements (NOT size in bytes) */ + + 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 + 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; + + In the 16-bit version of this structure, the mark field has type + "PCRE_UCHAR16 **". + + In the 32-bit version of this structure, the mark field has type + "PCRE_UCHAR32 **". + + 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_STUDY_DATA + PCRE_EXTRA_TABLES + + Other flag bits should be set to zero. The study_data field and some- + times the executable_jit field are set in the pcre_extra block that is + returned by pcre_study(), together with the appropriate flag bits. You + should not set these yourself, but you may add to the block by setting + other fields and their corresponding flag bits. + + The match_limit field provides a means of preventing PCRE from using up + a vast amount of resources when running patterns that are not going to + match, but which have a very large number of possibilities in their + search trees. The classic example is a pattern that uses nested unlim- + ited repeats. + + Internally, pcre_exec() uses a function called match(), which it calls + repeatedly (sometimes recursively). The limit set by match_limit is + imposed on the number of times this function is called during a match, + which has the effect of limiting the amount of backtracking that can + 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 + 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- + sive. This limit is of use only if it is set smaller than match_limit. + + 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- + ture, and is described in the pcrecallout documentation. + + The tables field is used to pass a character tables pointer to + pcre_exec(); this overrides the value that is stored with the compiled + pattern. A non-NULL value is stored with the compiled pattern only if + custom tables were supplied to pcre_compile() via its tableptr argu- + ment. If NULL is passed to pcre_exec() using this mechanism, it forces + PCRE's internal tables to be used. This facility is helpful when re- + using patterns that have been saved after compiling with an external + set of tables, because the external tables might be at a different + address when pcre_exec() is called. See the pcreprecompile documenta- + tion for a discussion of saving compiled patterns for later use. + + If PCRE_EXTRA_MARK is set in the flags field, the mark field must be + set to point to a suitable variable. If the pattern contains any back- + tracking control verbs such as (*MARK:NAME), and the execution ends up + with a name to pass back, a pointer to the name string (zero termi- + nated) is placed in the variable pointed to by the mark field. The + names are within the compiled pattern; if you wish to retain such a + name you must copy it before freeing the memory of a compiled pattern. + If there is no name to pass back, the variable pointed to by the mark + field is set to NULL. For details of the backtracking control verbs, + see the section entitled "Backtracking control" in the pcrepattern doc- + umentation. + + Option bits for pcre_exec() + + The unused bits of the options argument for pcre_exec() must be zero. + The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx, + PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, + PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and + 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 + + The PCRE_ANCHORED option limits pcre_exec() to matching at the first + matching position. If a pattern was compiled with PCRE_ANCHORED, or + turned out to be anchored by virtue of its contents, it cannot be made + unachored at matching time. + + PCRE_BSR_ANYCRLF + PCRE_BSR_UNICODE + + These options (which are mutually exclusive) control what the \R escape + sequence matches. The choice is either to match only CR, LF, or CRLF, + or to match any Unicode newline sequence. These options override the + choice that was made or defaulted when the pattern was compiled. + + PCRE_NEWLINE_CR + PCRE_NEWLINE_LF + PCRE_NEWLINE_CRLF + PCRE_NEWLINE_ANYCRLF + PCRE_NEWLINE_ANY + + These options override the newline definition that was chosen or + defaulted when the pattern was compiled. For details, see the descrip- + tion of pcre_compile() above. During matching, the newline choice + affects the behaviour of the dot, circumflex, and dollar metacharac- + ters. It may also alter the way the match position is advanced after a + match failure for an unanchored pattern. + + When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is + set, and a match attempt for an unanchored pattern fails when the cur- + rent position is at a CRLF sequence, and the pattern contains no + explicit matches for CR or LF characters, the match position is + advanced by two characters instead of one, in other words, to after the + CRLF. + + The above rule is a compromise that makes the most common cases work as + expected. For example, if the pattern is .+A (and the PCRE_DOTALL + option is not set), it does not match the string "\r\nA" because, after + failing at the start, it skips both the CR and the LF before retrying. + However, the pattern [\r\n]A does match that string, because it con- + tains an explicit CR or LF reference, and so advances only by one char- + acter after the first failure. + + An explicit match for CR of LF is either a literal appearance of one of + those characters, or one of the \r or \n escape sequences. Implicit + matches such as [^X] do not count, nor does \s (which includes CR and + LF in the characters that it matches). + + Notwithstanding the above, anomalous effects may still occur when CRLF + is a valid newline sequence and explicit \r or \n escapes appear in the + pattern. + + PCRE_NOTBOL + + This option specifies that first character of the subject string is not + the beginning of a line, so the circumflex metacharacter should not + match before it. Setting this without PCRE_MULTILINE (at compile time) + causes circumflex never to match. This option affects only the behav- + iour of the circumflex metacharacter. It does not affect \A. + + PCRE_NOTEOL + + This option specifies that the end of the subject string is not the end + of a line, so the dollar metacharacter should not match it nor (except + in multiline mode) a newline immediately before it. Setting this with- + out PCRE_MULTILINE (at compile time) causes dollar never to match. This + option affects only the behaviour of the dollar metacharacter. It does + not affect \Z or \z. + + PCRE_NOTEMPTY + + An empty string is not considered to be a valid match if this option is + set. If there are alternatives in the pattern, they are tried. If all + the alternatives match the empty string, the entire match fails. For + example, if the pattern + + a?b? + + is applied to a string not beginning with "a" or "b", it matches an + empty string at the start of the subject. With PCRE_NOTEMPTY set, this + match is not valid, so PCRE searches further into the string for occur- + rences of "a" or "b". + + PCRE_NOTEMPTY_ATSTART + + This is like PCRE_NOTEMPTY, except that an empty string match that is + not at the start of the subject is permitted. If the pattern is + anchored, such a match can occur only if the pattern contains \K. + + Perl has no direct equivalent of PCRE_NOTEMPTY or + PCRE_NOTEMPTY_ATSTART, but it does make a special case of a pattern + match of the empty string within its split() function, and when using + the /g modifier. It is possible to emulate Perl's behaviour after + matching a null string by first trying the match again at the same off- + set with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then if that + fails, by advancing the starting offset (see below) and trying an ordi- + nary match again. There is some code that demonstrates how to do this + in the pcredemo sample program. In the most general case, you have to + check to see if the newline convention recognizes CRLF as a newline, + and if so, and the current character is CR followed by LF, advance the + starting offset by two characters instead of one. + + PCRE_NO_START_OPTIMIZE + + There are a number of optimizations that pcre_exec() uses at the start + of a match, in order to speed up the process. For example, if it is + known that an unanchored match must start with a specific character, it + searches the subject for that character, and fails immediately if it + cannot find it, without actually running the main matching function. + This means that a special item such as (*COMMIT) at the start of a pat- + tern is not considered until after a suitable starting point for the + match has been found. When callouts or (*MARK) items are in use, these + "start-up" optimizations can cause them to be skipped if the pattern is + never actually used. The start-up optimizations are in effect a pre- + scan of the subject that takes place before the pattern is run. + + The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, + possibly causing performance to suffer, but ensuring that in cases + where the result is "no match", the callouts do occur, and that items + such as (*COMMIT) and (*MARK) are considered at every possible starting + position in the subject string. If PCRE_NO_START_OPTIMIZE is set at + compile time, it cannot be unset at matching time. The use of + PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, matching + is always done using interpretively. + + Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching + operation. Consider the pattern + + (*COMMIT)ABC + + When this is compiled, PCRE records the fact that a match must start + with the character "A". Suppose the subject string is "DEFABC". The + start-up optimization scans along the subject, finds "A" and runs the + first match attempt from there. The (*COMMIT) item means that the pat- + tern must match the current starting position, which in this case, it + does. However, if the same match is run with PCRE_NO_START_OPTIMIZE + set, the initial scan along the subject string does not happen. The + first match attempt is run starting from "D" and when this fails, + (*COMMIT) prevents any further matches being tried, so the overall + result is "no match". If the pattern is studied, more start-up opti- + mizations may be used. For example, a minimum length for the subject + may be recorded. Consider the pattern + + (*MARK:A)(X|Y) + + The minimum length for a match is one character. If the subject is + "ABC", there will be attempts to match "ABC", "BC", "C", and then + finally an empty string. If the pattern is studied, the final attempt + does not take place, because PCRE knows that the subject is too short, + and so the (*MARK) is never encountered. In this case, studying the + pattern does not affect the overall match result, which is still "no + match", but it does affect the auxiliary information that is returned. + + PCRE_NO_UTF8_CHECK + + 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 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 + 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 + 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- + ered to be more important that an alternative complete match. + + 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 + 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, + and this is by far the most common case. In UTF-8 mode, the byte offset + must point to the start of a UTF-8 character (or the end of the sub- + ject). Unlike the pattern string, the subject may contain binary zero + bytes. + + A non-zero starting offset is useful when searching for another match + in the same subject by calling pcre_exec() again after a previous suc- + cess. Setting startoffset differs from just passing over a shortened + string and setting PCRE_NOTBOL in the case of a pattern that begins + 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, + 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 + 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 + discover that it is preceded by a letter. + + 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 + 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 + 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, + 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 + 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 + 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: + 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 + it is not, it is rounded down. + + When a match is successful, information about captured substrings is + returned in pairs of integers, starting at the beginning of ovector, + and continuing up to two-thirds of its length at the most. The first + element of each pair is set to the byte offset of the first character + in a substring, and the second is set to the byte offset of the first + character after the end of a substring. Note: these values are always + byte offsets, even in UTF-8 mode. They are not character counts. + + The first pair of integers, ovector[0] and ovector[1], identify the + portion of the subject string matched by the entire pattern. The next + pair is used for the first capturing subpattern, and so on. The value + 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 + 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, + it is used as far as possible (up to two-thirds of its length), and the + function returns a value of zero. If neither the actual string matched + nor any captured substrings are of interest, pcre_exec() may be called + with ovector passed as NULL and ovecsize as zero. However, if the pat- + tern contains back references and the ovector is not big enough to + remember the related substrings, PCRE has to get additional memory for + use during matching. Thus it is usually advisable to supply an ovector + 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 + 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 + 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 + 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- + 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, + of course) are set to -1. + + Note: Elements in the first two-thirds of ovector that do not corre- + spond to capturing parentheses in the pattern are never changed. That + is, if a pattern contains n capturing parentheses, no more than ovec- + tor[0] to ovector[2n+1] are set by pcre_exec(). The other elements (in + the first two-thirds) retain whatever values they previously had. + + 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 + defined in the header file: + + PCRE_ERROR_NOMATCH (-1) + + The subject string did not match the pattern. + + PCRE_ERROR_NULL (-2) + + Either code or subject was passed as NULL, or ovector was NULL and + ovecsize was not zero. + + PCRE_ERROR_BADOPTION (-3) + + An unrecognized bit was set in the options argument. + + PCRE_ERROR_BADMAGIC (-4) + + 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 + 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 + overwriting of the compiled pattern. + + PCRE_ERROR_NOMEMORY (-6) + + 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 + 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- + for-recursion. + + PCRE_ERROR_NOSUBSTRING (-7) + + 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 + 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. + See the pcrecallout documentation for details. + + PCRE_ERROR_BADUTF8 (-10) + + A string that contains an invalid UTF-8 byte sequence was passed as a + subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of + the output vector (ovecsize) is at least 2, the byte offset to the + start of the the invalid UTF-8 character is placed in the first ele- + ment, and a reason code is placed in the second element. The reason + 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 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 + 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 + onwards, there are no restrictions on partial matching. + + PCRE_ERROR_INTERNAL (-14) + + 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) + + This error is given if the value of the ovecsize argument is negative. + + 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 + description above. + + PCRE_ERROR_BADNEWLINE (-23) + + An invalid combination of PCRE_NEWLINE_xxx options was given. + + PCRE_ERROR_BADOFFSET (-24) + + The value of startoffset was negative or greater than the length of the + subject, that is, the value in length. + + PCRE_ERROR_SHORTUTF8 (-25) + + This error is returned instead of PCRE_ERROR_BADUTF8 when the subject + string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD + option is set. Information about the failure is returned as for + PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but + this special error code for PCRE_PARTIAL_HARD precedes the implementa- + tion of returned information; it is retained for backwards compatibil- + 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 or 32-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. + + PCRE_ERROR_JIT_BADOPTION + + This error is returned when a pattern that was successfully studied + using a JIT compile option is being matched, but the matching mode + (partial or complete match) does not correspond to any JIT compilation + mode. When the JIT fast path function is used, this error may be also + given for invalid options. See the pcrejit documentation for more + details. + + PCRE_ERROR_BADLENGTH (-32) + + This error is given if pcre_exec() is called with a negative value for + the length argument. + + Error numbers -16 to -20, -22, and 30 are not used by pcre_exec(). + + Reason codes for invalid UTF-8 strings + + This section applies only to the 8-bit library. The corresponding + information for the 16-bit and 32-bit libraries is given in the pcre16 + and pcre32 pages. + + When pcre_exec() returns either PCRE_ERROR_BADUTF8 or PCRE_ERROR_SHORT- + UTF8, and the size of the output vector (ovecsize) is at least 2, the + offset of the start of the invalid UTF-8 character is placed in the + first output vector element (ovector[0]) and a reason code is placed in + the second element (ovector[1]). The reason codes are given names in + the pcre.h header file: + + PCRE_UTF8_ERR1 + PCRE_UTF8_ERR2 + PCRE_UTF8_ERR3 + PCRE_UTF8_ERR4 + PCRE_UTF8_ERR5 + + The string ends with a truncated UTF-8 character; the code specifies + how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 + characters to be no longer than 4 bytes, the encoding scheme (origi- + nally defined by RFC 2279) allows for up to 6 bytes, and this is + checked first; hence the possibility of 4 or 5 missing bytes. + + PCRE_UTF8_ERR6 + PCRE_UTF8_ERR7 + PCRE_UTF8_ERR8 + PCRE_UTF8_ERR9 + PCRE_UTF8_ERR10 + + The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of + the character do not have the binary value 0b10 (that is, either the + most significant bit is 0, or the next bit is 1). + + PCRE_UTF8_ERR11 + PCRE_UTF8_ERR12 + + A character that is valid by the RFC 2279 rules is either 5 or 6 bytes + long; these code points are excluded by RFC 3629. + + PCRE_UTF8_ERR13 + + A 4-byte character has a value greater than 0x10fff; these code points + are excluded by RFC 3629. + + PCRE_UTF8_ERR14 + + A 3-byte character has a value in the range 0xd800 to 0xdfff; this + range of code points are reserved by RFC 3629 for use with UTF-16, and + so are excluded from UTF-8. + + PCRE_UTF8_ERR15 + PCRE_UTF8_ERR16 + PCRE_UTF8_ERR17 + PCRE_UTF8_ERR18 + PCRE_UTF8_ERR19 + + A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes + for a value that can be represented by fewer bytes, which is invalid. + For example, the two bytes 0xc0, 0xae give the value 0x2e, whose cor- + rect coding uses just one byte. + + PCRE_UTF8_ERR20 + + The two most significant bits of the first byte of a character have the + binary value 0b10 (that is, the most significant bit is 1 and the sec- + ond is 0). Such a byte can only validly occur as the second or subse- + quent byte of a multi-byte character. + + PCRE_UTF8_ERR21 + + The first byte of a character has the value 0xfe or 0xff. These values + can never occur in a valid UTF-8 string. + + PCRE_UTF8_ERR2 + + Non-character. These are the last two characters in each plane (0xfffe, + 0xffff, 0x1fffe, 0x1ffff .. 0x10fffe, 0x10ffff), and the characters + 0xfdd0..0xfdef. + + +EXTRACTING CAPTURED SUBSTRINGS BY NUMBER + + int pcre_copy_substring(const char *subject, int *ovector, + int stringcount, int stringnumber, char *buffer, + int buffersize); + + int pcre_get_substring(const char *subject, int *ovector, + int stringcount, int stringnumber, + const char **stringptr); + + 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 + 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 + 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- + string(). Unfortunately, the interface to pcre_get_substring_list() is + 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 + 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 + 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 + 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 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 + 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 + 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 + 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 + empty string. This can be distinguished from a genuine zero-length sub- + 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 + 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- + vided. + + +EXTRACTING CAPTURED SUBSTRINGS BY NAME + + int pcre_get_stringnumber(const pcre *code, + const char *name); + + int pcre_copy_named_substring(const pcre *code, + const char *subject, int *ovector, + int stringcount, const char *stringname, + char *buffer, int buffersize); + + int pcre_get_named_substring(const pcre *code, + const char *subject, int *ovector, + int stringcount, const char *stringname, + const char **stringptr); + + To extract a substring by name, you first have to find associated num- + ber. For example, for this pattern + + (a+)b(?\d+)... + + the number of the subpattern called "xxx" is 2. If the name is known to + 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 + 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 + differences: + + 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 + 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 + 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 + causes an error at compile time. + + +DUPLICATE SUBPATTERN NAMES + + int pcre_get_stringtable_entries(const pcre *code, + const char *name, char **first, char **last); + + When a pattern is compiled with the PCRE_DUPNAMES option, names for + subpatterns are not required to be unique. (Duplicate names are always + allowed for subpatterns with the same number, created by using the (?| + feature. Indeed, if such subpatterns are named, they are required to + 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 + 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, + 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 + 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 + 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 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, + 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 + 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 + 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, + const char *subject, int length, int startoffset, + 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- + tion. + + 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 + repeated here. + + 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 + lot of potential matches. + + Here is an example of a simple call to pcre_dfa_exec(): + + int rc; + int ovector[10]; + int wspace[20]; + rc = pcre_dfa_exec( + re, /* result of pcre_compile() */ + NULL, /* we didn't study the pattern */ + "some string", /* the subject string */ + 11, /* the length of the subject string */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + ovector, /* vector of integers for substring information */ + 10, /* number of elements (NOT size in bytes) */ + wspace, /* working space vector */ + 20); /* number of elements (NOT size in bytes) */ + + 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- + 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 + 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 + 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- + ples, in the pcrepartial documentation. + + PCRE_DFA_SHORTEST + + 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 + 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 + 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- + 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, + if the pattern + + <.*> + + is matched against the string + + This is no more + + the three matched strings are + + + + + + 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. Unlike pcre_exec(), pcre_dfa_exec() + can use the entire ovector for returning matched strings. + + Error returns from pcre_dfa_exec() + + The pcre_dfa_exec() function returns a negative number when it fails. + Many of the errors are the same as for pcre_exec(), and these are + described above. There are in addition the following errors that are + specific to pcre_dfa_exec(): + + PCRE_ERROR_DFA_UITEM (-16) + + This return is given if pcre_dfa_exec() encounters an item in the pat- + tern that it does not support, for instance, the use of \C or a back + reference. + + PCRE_ERROR_DFA_UCOND (-17) + + This return is given if pcre_dfa_exec() encounters a condition item + that uses a back reference for the condition, or a test for recursion + in a specific group. These are not supported. + + PCRE_ERROR_DFA_UMLIMIT (-18) + + This return is given if pcre_dfa_exec() is called with an extra block + that contains a setting of the match_limit or match_limit_recursion + fields. This is not supported (these fields are meaningless for DFA + matching). + + PCRE_ERROR_DFA_WSSIZE (-19) + + 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 + 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 + + pcre16(3), pcre32(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), + pcrematching(3), pcrepartial(3), pcreposix(3), pcreprecompile(3), pcre- + sample(3), pcrestack(3). + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 08 November 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCRECALLOUT(3) PCRECALLOUT(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +SYNOPSIS + + #include + + int (*pcre_callout)(pcre_callout_block *); + + int (*pcre16_callout)(pcre16_callout_block *); + + int (*pcre32_callout)(pcre32_callout_block *); + + +DESCRIPTION + + 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 (pcre16_callout for + the 16-bit library, pcre32_callout for the 32-bit library). By default, + this variable contains NULL, which disables all calling out. + + Within a regular expression, (?C) indicates the points at which the + external function is to be called. 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 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}|--) + + it is processed as if it were + + (?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255) + + Notice that there is a callout before and after each parenthesis and + alternation bar. Automatic callouts can be used for tracking the + progress of pattern matching. The pcretest command has an option that + sets automatic callouts; when it is used, the output indicates how the + pattern is matched. This is useful information when you are trying to + optimize the performance of a particular pattern. + + 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 + 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", + 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 + patterns, if it has been scanned far enough. + + You can disable these optimizations by passing the PCRE_NO_START_OPTI- + MIZE option to the matching function, or by starting the pattern with + (*NO_START_OPT). This slows down the matching process, but does ensure + 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 or pcre[16|32]_callout is called (if it is + set). This applies to both normal and DFA matching. The only argument + to the callout function is a pointer to a pcre_callout or + pcre[16|32]_callout block. These structures contains the following + fields: + + int version; + int callout_number; + int *offset_vector; + const char *subject; (8-bit version) + PCRE_SPTR16 subject; (16-bit version) + PCRE_SPTR32 subject; (32-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) + const PCRE_UCHAR32 *mark; (32-bit version) + + The version field is an integer containing the version number of the + block format. The initial version was 0; the current version is 2. The + version number will change again in future if additional fields are + added, but the intention is never to remove any of the existing fields. + + The callout_number field contains the number of the callout, as com- + piled into the pattern (that is, the number after ?C for manual call- + outs, and 255 for automatically generated callouts). + + The offset_vector field is a pointer to the vector of offsets that was + passed by the caller to the matching function. When pcre_exec() or + pcre[16|32]_exec() is used, the contents can be inspected, in order to + extract substrings that have been matched so far, in the same way as + for extracting substrings after a match has completed. For the DFA + matching functions, this field is not useful. + + The subject and subject_length fields contain copies of the values that + were passed to the matching function. + + The start_match field normally contains the offset within the subject + at which the current match attempt started. However, if the escape + sequence \K has been encountered, this value is changed to reflect the + modified starting point. If the pattern is not anchored, the callout + function may be called several times from the same point in the pattern + for different starting points in the subject. + + The current_position field contains the offset within the subject of + the current match pointer. + + When the pcre_exec() or pcre[16|32]_exec() is used, the capture_top + field contains one more than the number of the highest numbered cap- + tured substring so far. If no substrings have been captured, the value + of capture_top is one. This is always the case when the DFA functions + are used, because they do not support captured substrings. + + The capture_last field contains the number of the most recently cap- + tured substring. If no substrings have been captured, its value is -1. + This is always the case for the DFA matching functions. + + The 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 pcre[16|32]_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 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 pcre[16|32]_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 func- + tions 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, 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- + dard "no match" failure. The error number PCRE_ERROR_CALLOUT is + reserved for use by callout functions; it will never be used by PCRE + itself. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 24 June 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCRECOMPAT(3) PCRECOMPAT(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +DIFFERENCES BETWEEN PCRE AND PERL + + This document describes the differences in the ways that PCRE and Perl + 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 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 + branch. + + 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 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 + messy concept of surrogates." + + 7. 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 + does not have variables). Note the following examples: + + Pattern PCRE matches Perl matches + + \Qabc$xyz\E abc$xyz abc followed by the + contents of $xyz + \Qabc\$xyz\E abc\$xyz abc\$xyz + \Qabc\E\$\Qxyz\E abc$xyz abc$xyz + + The \Q...\E sequence is recognized both inside and outside character + classes. + + 8. 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 as subroutines (whether or not recur- + sively) are always treated as atomic groups in PCRE. This is like + Python, but unlike Perl. Captured values that are set outside a sub- + routine call can be reference from inside in PCRE, but not in Perl. + There is a discussion that explains these differences in more detail in + the section on recursion differences from Perl in the pcrepattern page. + + 10. If any of the backtracking control verbs are used in an assertion + or in a subpattern that is called as a subroutine (whether or not + recursively), their effect is confined to that subpattern; it does not + extend to the surrounding pattern. This is not always the case in Perl. + In particular, if (*THEN) is present in a group that is called as a + subroutine, its action is limited to that group, even if the group does + not contain any | characters. There is one exception to this: the name + from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a success- + ful positive assertion is passed back when a match succeeds (compare + capturing parentheses in assertions). Note that such subpatterns are + processed as anchored at the point where they are tested. + + 11. There are some differences that are concerned with the settings of + captured strings when part of a pattern is repeated. For example, + matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 + unset, but in PCRE it is set to "b". + + 12. PCRE's handling of duplicate subpattern numbers and duplicate sub- + 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)|(? (Oniguruma syntax) are not synonymous. The former is a back + reference; the latter is a subroutine call. + + Generic character types + + Another use of backslash is for specifying generic character types: + + \d any decimal digit + \D any character that is not a decimal digit + \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 char- + acter. This is the same as the "." metacharacter when PCRE_DOTALL is + not set. Perl also uses \N to match characters by name; PCRE does not + support this. + + Each pair of lower and upper case escape sequences partitions the com- + plete set of characters into two disjoint sets. Any given character + matches one, and only one, of each pair. The sequences can appear both + inside and outside character classes. They each match one character of + the appropriate type. If the current matching point is at the end of + the subject string, all of them fail, because there is no character to + match. + + For compatibility with Perl, \s does not match the VT character (code + 11). This makes it different from the the POSIX "space" class. The \s + characters are HT (9), LF (10), FF (12), CR (13), and space (32). If + "use locale;" is included in a Perl script, \s may match the VT charac- + ter. In PCRE, it never does. + + A "word" character is an underscore or any character that is a letter + or digit. By default, the definition of letters and digits is con- + trolled by PCRE's low-valued character tables, and may vary if locale- + specific matching is taking place (see "Locale support" in the pcreapi + page). For example, in a French locale such as "fr_FR" in Unix-like + systems, or "french" in Windows, some character codes greater than 128 + are used for accented letters, and these are then matched by \w. The + use of locales with Unicode is discouraged. + + By default, in a UTF mode, characters with values greater than 128 + never match \d, \s, or \w, and always match \D, \S, and \W. These + sequences retain their original meanings from before UTF support was + available, mainly for efficiency reasons. However, if PCRE is compiled + with Unicode property support, and the PCRE_UCP option is set, the be- + haviour is changed so that Unicode properties are used to determine + character types, as follows: + + \d any character that \p{Nd} matches (decimal digit) + \s any character that \p{Z} matches, plus HT, LF, FF, CR + \w any character that \p{L} or \p{N} matches, plus underscore + + The upper case escapes match the inverse sets of characters. Note that + \d matches only decimal digits, whereas \w matches any Unicode digit, + as well as any Unicode letter, and underscore. Note also that PCRE_UCP + affects \b, and \B because they are defined in terms of \w and \W. + Matching these sequences is noticeably slower when PCRE_UCP is set. + + The sequences \h, \H, \v, and \V are features that were added to Perl + at release 5.10. In contrast to the other sequences, which match only + ASCII characters by default, these always match certain high-valued + codepoints, whether or not PCRE_UCP is set. The horizontal space char- + acters are: + + U+0009 Horizontal tab (HT) + U+0020 Space + U+00A0 Non-break space + U+1680 Ogham space mark + U+180E Mongolian vowel separator + U+2000 En quad + U+2001 Em quad + U+2002 En space + U+2003 Em space + U+2004 Three-per-em space + U+2005 Four-per-em space + U+2006 Six-per-em space + U+2007 Figure space + U+2008 Punctuation space + U+2009 Thin space + U+200A Hair space + U+202F Narrow no-break space + U+205F Medium mathematical space + U+3000 Ideographic space + + The vertical space characters are: + + U+000A Linefeed (LF) + U+000B Vertical tab (VT) + U+000C Form feed (FF) + U+000D Carriage return (CR) + U+0085 Next line (NEL) + 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 8-bit non-UTF-8 mode \R is equivalent + to the following: + + (?>\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 (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 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. + + It is possible to restrict \R to match only CR, LF, or CRLF (instead of + the complete set of Unicode line endings) by setting the option + PCRE_BSR_ANYCRLF either at compile time or when the pattern is matched. + (BSR is an abbrevation for "backslash R".) This can be made the default + when PCRE is built; if this is the case, the other behaviour can be + requested via the PCRE_BSR_UNICODE option. It is also possible to + specify these settings by starting a pattern string with one of the + following sequences: + + (*BSR_ANYCRLF) CR, LF, or CRLF only + (*BSR_UNICODE) any Unicode newline sequence + + 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), (*UTF16), (*UTF32), (*UTF) + 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 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 + \X a Unicode extended grapheme cluster + + The property names represented by xx above are limited to the Unicode + script names, the general category properties, "Any", which matches any + character (including newline), and some special PCRE properties + (described in the next section). Other Perl properties such as "InMu- + sicalSymbols" are not currently supported by PCRE. Note that \P{Any} + does not match any characters, so always causes a match failure. + + Sets of Unicode characters are defined as belonging to certain scripts. + A character from one of these sets can be matched using a script name. + For example: + + \p{Greek} + \P{Han} + + 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, 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- + tion can be specified by including a circumflex between the opening + brace and the property name. For example, \p{^Lu} is the same as + \P{Lu}. + + If only one letter is specified with \p or \P, it includes all the gen- + eral category properties that start with that letter. In this case, in + the absence of negation, the curly brackets in the escape sequence are + optional; these two examples have the same effect: + + \p{L} + \pL + + The following general category property codes are supported: + + C Other + Cc Control + Cf Format + Cn Unassigned + Co Private use + Cs Surrogate + + L Letter + Ll Lower case letter + Lm Modifier letter + Lo Other letter + Lt Title case letter + Lu Upper case letter + + M Mark + Mc Spacing mark + Me Enclosing mark + Mn Non-spacing mark + + N Number + Nd Decimal number + Nl Letter number + No Other number + + P Punctuation + Pc Connector punctuation + Pd Dash punctuation + Pe Close punctuation + Pf Final punctuation + Pi Initial punctuation + Po Other punctuation + Ps Open punctuation + + S Symbol + Sc Currency symbol + Sk Modifier symbol + Sm Mathematical symbol + So Other symbol + + Z Separator + Zl Line separator + Zp Paragraph separator + Zs Space separator + + The special property L& is also supported: it matches a character that + has the Lu, Ll, or Lt property, in other words, a letter that is not + 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 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, + PCRE_NO_UTF16_CHECK and PCRE_NO_UTF32_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 + 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. + For example, \p{Lu} always matches only upper case letters. + + Matching characters by Unicode property is not fast, because PCRE has + to do a multistage table lookup in order to find a character's prop- + erty. That is why the traditional escape sequences such as \d and \w do + not use Unicode properties in PCRE by default, though you can make them + do so by setting the PCRE_UCP option or by starting the pattern with + (*UCP). + + Extended grapheme clusters + + The \X escape matches any number of Unicode characters that form an + "extended grapheme cluster", and treats the sequence as an atomic group + (see below). Up to and including release 8.31, PCRE matched an ear- + lier, simpler definition that was equivalent to + + (?>\PM\pM*) + + That is, it matched a character without the "mark" property, followed + by zero or more characters with the "mark" property. Characters with + the "mark" property are typically non-spacing accents that affect the + preceding character. + + This simple definition was extended in Unicode to include more compli- + cated kinds of composite character by giving each character a grapheme + breaking property, and creating rules that use these properties to + define the boundaries of extended grapheme clusters. In releases of + PCRE later than 8.31, \X matches one of these clusters. + + \X always matches at least one character. Then it decides whether to + add additional characters according to the following rules for ending a + cluster: + + 1. End at the end of the subject string. + + 2. Do not end between CR and LF; otherwise end after any control char- + acter. + + 3. Do not break Hangul (a Korean script) syllable sequences. Hangul + characters are of five types: L, V, T, LV, and LVT. An L character may + be followed by an L, V, LV, or LVT character; an LV or V character may + be followed by a V or T character; an LVT or T character may be follwed + only by a T character. + + 4. Do not end before extending characters or spacing marks. Characters + with the "mark" property always have the "extend" grapheme breaking + property. + + 5. Do not end after prepend characters. + + 6. Otherwise, end the cluster. + + PCRE's additional properties + + As well as the standard Unicode properties described above, PCRE sup- + ports four more that make it possible to convert traditional escape + sequences such as \w and \s and POSIX character classes to use Unicode + properties. PCRE uses these non-standard, non-Perl properties inter- + nally when PCRE_UCP is set. They are: + + Xan Any alphanumeric character + Xps Any POSIX space character + Xsp Any Perl space character + Xwd Any Perl "word" character + + Xan matches characters that have either the L (letter) or the N (num- + ber) property. Xps matches the characters tab, linefeed, vertical tab, + form feed, or carriage return, and any other character that has the Z + (separator) property. Xsp is the same as Xps, except that vertical tab + is excluded. Xwd matches the same characters as Xan, plus underscore. + + Resetting the match start + + 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, + 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 + 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 backslashed assertions are: + + \b matches at a word boundary + \B matches when not at a word boundary + \A matches at the start of the subject + \Z matches at the end of the subject + also matches before a newline at the end of the subject + \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- + acter (for example, \B matches the letter B). However, if the + PCRE_EXTRA option is set, an "invalid escape sequence" error is gener- + ated instead. + + A word boundary is a position in the subject string where the current + character and the previous character do not both match \w or \W (i.e. + one matches \w and the other matches \W), or the start or end of the + string if the first or last character matches \w, respectively. In a + UTF mode, the meanings of \w and \W can be changed by setting the + PCRE_UCP option. When this is done, it also affects \b and \B. Neither + PCRE nor Perl has a separate "start of word" or "end of word" metase- + quence. However, whatever follows \b normally determines which it is. + For example, the fragment \ba matches "a" at the start of a word. + + 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- + 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- + 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 + 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- + 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 + 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 + at a time, it cannot reproduce this behaviour. + + If all the alternatives of a pattern begin with \G, the expression is + anchored to the starting match position, and the "anchored" flag is set + in the compiled regular expression. + + +CIRCUMFLEX AND DOLLAR + + The circumflex and dollar metacharacters are zero-width assertions. + That is, they test for a particular condition being true without con- + suming any characters from the subject string. + + Outside a character class, in the default matching mode, the circumflex + character is an assertion that is true only if the current matching + point is at the start of the subject string. If the startoffset argu- + ment of pcre_exec() is non-zero, circumflex can never match if the + PCRE_MULTILINE option is unset. Inside a character class, circumflex + 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 + constructs that can cause a pattern to be anchored.) + + The dollar character is an assertion that is true only if the current + matching point is at the end of the subject string, or immediately + before a newline at the end of the string (by default). Note, however, + that it does not actually match the newline. Dollar need not be the + last character of the pattern if a number of alternatives are involved, + but it should be the last item in any branch in which it appears. Dol- + lar has no special meaning in a character class. + + The meaning of dollar can be changed so that it matches only at the + very end of the string, by setting the PCRE_DOLLAR_ENDONLY option at + 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 + 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 + 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 + 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. + + When a line ending is defined as a single character, dot never matches + that character; when the two-character sequence CRLF is used, dot does + not match CR if it is immediately followed by LF, but otherwise it + matches all characters (including isolated CRs and LFs). When any Uni- + code line endings are being recognized, dot does not match CR or LF or + any of the other line ending characters. + + The behaviour of dot with regard to newlines can be changed. If the + PCRE_DOTALL option is set, a dot matches any one character, without + exception. If the two-character sequence CRLF is present in the subject + string, it takes two dots to match it. + + The handling of dot is entirely independent of the handling of circum- + flex and dollar, the only relationship being that they both involve + newlines. Dot has no special meaning in a character class. + + The escape sequence \N behaves like a dot, except that it is not + affected by the PCRE_DOTALL option. In other words, it matches any + character except one that signifies the end of a line. Perl also uses + \N to match characters by name; PCRE does not support this. + + +MATCHING A SINGLE DATA UNIT + + Outside a character class, the escape sequence \C matches any one data + unit, whether or not a UTF mode is set. In the 8-bit library, one data + unit is one byte; in the 16-bit library it is a 16-bit unit; in the + 32-bit library it is a 32-bit unit. Unlike a dot, \C always matches + line-ending characters. The feature is provided in Perl in order to + match individual bytes in UTF-8 mode, but it is unclear how it can use- + fully be used. Because \C breaks up characters into individual data + units, matching one unit with \C in a UTF mode means that the rest of + the string may start with a malformed UTF character. This has undefined + results, because PCRE assumes that it is dealing with valid UTF strings + (and by default it checks this at the start of processing unless the + PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK or PCRE_NO_UTF32_CHECK option + is used). + + PCRE does not allow \C to appear in lookbehind assertions (described + below) in a UTF mode, because this would make it impossible to calcu- + 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 + + An opening square bracket introduces a character class, terminated by a + 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 + present) or escaped with a backslash. + + A character class matches a single character in the subject. In a UTF + mode, the character may be more than one data unit long. A matched + 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. + 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 + the current pointer is at the end of the string. + + In UTF-8 (UTF-16, UTF-32) mode, characters with values greater than 255 + (0xffff) can be included in a class as a literal string of data units, + 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 + 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 + a range. + + 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 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, + \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 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 + 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 + 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, + 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 + supports this notation. For example, + + [01[:alpha:]%] + + matches "0", "1", any alphabetic character, or "%". The supported class + names are: + + alnum letters and digits + alpha letters + ascii character codes 0 - 127 + blank space or tab only + cntrl control characters + digit decimal digits (same as \d) + graph printing characters, excluding space + lower lower case letters + print printing characters, including space + punct printing characters, excluding letters and digits and space + space white space (not quite the same as \s) + upper upper case letters + word "word" characters (same as \w) + xdigit hexadecimal digits + + The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), + and space (32). Notice that this list includes the VT character (code + 11). This makes "space" different to \s, which does not include VT (for + Perl compatibility). + + The 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 + POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but + these are not supported, and an error is given if they are encountered. + + By default, in UTF modes, characters with values greater than 128 do + not match any of the POSIX character classes. However, if the PCRE_UCP + option is passed to pcre_compile(), some of the classes are changed so + that Unicode character properties are used. This is achieved by replac- + ing the POSIX classes by other sequences, as follows: + + [:alnum:] becomes \p{Xan} + [:alpha:] becomes \p{L} + [:blank:] becomes \h + [:digit:] becomes \p{Nd} + [:lower:] becomes \p{Ll} + [:space:] becomes \p{Xps} + [:upper:] becomes \p{Lu} + [:word:] becomes \p{Xwd} + + Negated versions, such as [:^alpha:] use \P instead of \p. The other + POSIX classes are unchanged, and match only characters with code points + less than 128. + + +VERTICAL BAR + + 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 + 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 + 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 + between "(?" and ")". The option letters are + + i for PCRE_CASELESS + m for PCRE_MULTILINE + s for PCRE_DOTALL + x for PCRE_EXTENDED + + 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 + 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 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 + 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, + 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 + 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 + some very weird behaviour otherwise. + + 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),(*UTF32), and + (*UCP) leading sequences that can be used to set UTF and Unicode prop- + erty modes; they are equivalent to setting the PCRE_UTF8, PCRE_UTF16, + PCRE_UTF32 and the PCRE_UCP options, respectively. The (*UTF) sequence + is a generic version that can be used with any of the libraries. + + +SUBPATTERNS + + Subpatterns are delimited by parentheses (round brackets), which can be + nested. Turning part of a pattern into a subpattern does two things: + + 1. It localizes a set of alternatives. For example, the pattern + + cat(aract|erpillar|) + + matches "cataract", "caterpillar", or "cat". Without the parentheses, + it would match "cataract", "erpillar" or an empty string. + + 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 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 + matched against the pattern + + the ((?:red|white) (king|queen)) + + 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 + 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 + "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, + 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 + 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- + lowing example is taken from the Perl documentation. The numbers under- + neath show in which buffer the captured content will be stored. + + # before ---------------branch-reset----------- after + / ( 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 + matches "abcabc" or "defdef": + + /(?|(abc)|(def))\1/ + + 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- + ber have matched. + + 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- + 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 + 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 + by number. + + Names consist of up to 32 alphanumeric characters and underscores. + Named capturing parentheses are still allocated numbers as well as + names, exactly as if the names were not present. The PCRE API provides + function calls for extracting the name-to-number translation table from + a compiled pattern. There is also a convenience function for extracting + a captured substring by name. + + 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 + both cases you want to extract the abbreviation. This pattern (ignoring + the line breaks) does the job: + + (?Mon|Fri|Sun)(?:day)?| + (?Tue)(?:sday)?| + (?Wed)(?:nesday)?| + (?Thu)(?:rsday)?| + (?Sat)(?:urday)? + + 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 + subpattern it was. + + If you make a back reference to a non-unique named subpattern from + elsewhere in the pattern, the one that corresponds to the first occur- + rence of the name is used. In the absence of duplicate numbers (see the + previous section) this is the one with the lowest number. If you use a + named reference in a condition test (see the section about conditions + below), either to check whether a subpattern has matched, or to check + for recursion, all subpatterns with the same name are tested. If the + condition is true for any one of them, the overall condition is true. + This is the same behaviour as testing by number. For further details of + the interfaces for handling named subpatterns, see the pcreapi documen- + tation. + + Warning: You cannot use different names to distinguish between two sub- + patterns with the same number because PCRE uses only the numbers when + matching. For this reason, an error is given at compile time if differ- + ent names are given to subpatterns with the same number. However, you + can give the same name to subpatterns with the same number, even when + PCRE_DUPNAMES is not set. + + +REPETITION + + 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 + 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 (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, + 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. Thus + + [aeiou]{3,} + + matches at least 3 successive vowels, but may match many more, while + + \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- + ple, {,6} is not a quantifier, but a literal string of four characters. + + In UTF modes, quantifiers apply to characters rather than to individual + data units. Thus, for example, \x{100}{2} matches two characters, each + of which is represented by a two-byte sequence in a UTF-8 string. Simi- + larly, \X{3} matches three Unicode extended grapheme clusters, each of + which may be several data units long (and they may be of different + lengths). + + The quantifier {0} is permitted, causing the expression to behave as if + the previous item and the quantifier were not present. This may be use- + ful for subpatterns that are referenced as subroutines from elsewhere + in the pattern (but see also the section entitled "Defining subpatterns + for use by reference only" below). Items other than subpatterns that + have a {0} quantifier are omitted from the compiled pattern. + + For convenience, the three most common quantifiers have single-charac- + ter abbreviations: + + * is equivalent to {0,} + + is equivalent to {1,} + ? is equivalent to {0,1} + + It is possible to construct infinite loops by following a subpattern + that can match no characters with a quantifier that has no upper limit, + for example: + + (a?)* + + Earlier versions of Perl and PCRE used to give an error at compile time + for such patterns. However, because there are cases where this can be + useful, such patterns are now accepted, but if any repetition of the + subpattern does in fact match no characters, the loop is forcibly bro- + ken. + + By default, the quantifiers are "greedy", that is, they match as much + as possible (up to the maximum number of permitted times), without + causing the rest of the pattern to fail. The classic example of where + this gives problems is in trying to match comments in C programs. These + appear between /* and */ and within the comment, individual * and / + characters may appear. An attempt to match C comments by applying the + pattern + + /\*.*\*/ + + to the string + + /* first comment */ not comment /* second comment */ + + fails, because it matches the entire string owing to the greediness of + the .* item. + + However, if a quantifier is followed by a question mark, it ceases to + be greedy, and instead matches the minimum number of times possible, so + the pattern + + /\*.*?\*/ + + does the right thing with the C comments. The meaning of the various + quantifiers is not otherwise changed, just the preferred number of + matches. Do not confuse this use of question mark with its use as a + quantifier in its own right. Because it has two uses, it can sometimes + appear doubled, as in + + \d??\d + + which matches one digit by preference, but can match two if that is the + only way the rest of the pattern matches. + + If the PCRE_UNGREEDY option is set (an option that is not available in + Perl), the quantifiers are not greedy by default, but individual ones + can be made greedy by following them with a question mark. In other + words, it inverts the default behaviour. + + When a parenthesized subpattern is quantified with a minimum repeat + count that is greater than 1 or with a limited maximum, more memory is + required for the compiled pattern, in proportion to the size of the + minimum or maximum. + + If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equiv- + alent to Perl's /s) is set, thus allowing the dot to match newlines, + the pattern is implicitly anchored, because whatever follows will be + tried against every character position in the subject string, so there + is no point in retrying the overall match at any position after the + first. PCRE normally treats such a pattern as though it were preceded + by \A. + + In cases where it is known that the subject string contains no new- + lines, it is worth setting PCRE_DOTALL in order to obtain this opti- + mization, or alternatively using ^ to indicate anchoring explicitly. + + However, there are some cases where the optimization cannot be used. + When .* is inside capturing parentheses that are the subject of a back + reference elsewhere in the pattern, a match at the start may fail where + a later one succeeds. Consider, for example: + + (.*)abc\1 + + If the subject is "xyz123abc123" the match point is the fourth charac- + ter. For this reason, such a pattern is not implicitly anchored. + + Another case where implicit anchoring is not applied is when the lead- + ing .* is inside an atomic group. Once again, a match at the start may + fail where a later one succeeds. Consider this pattern: + + (?>.*?a)b + + It matches "ab" in the subject "aab". The use of the backtracking con- + trol verbs (*PRUNE) and (*SKIP) also disable this optimization. + + When a capturing subpattern is repeated, the value captured is the sub- + string that matched the final iteration. For example, after + + (tweedle[dume]{3}\s*)+ + + has matched "tweedledum tweedledee" the value of the captured substring + is "tweedledee". However, if there are nested capturing subpatterns, + the corresponding captured values may have been set in previous itera- + tions. For example, after + + /(a|(b))+/ + + matches "aba" the value of the second captured substring is "b". + + +ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS + + With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy") + repetition, failure of what follows normally causes the repeated item + to be re-evaluated to see if a different number of repeats allows the + rest of the pattern to match. Sometimes it is useful to prevent this, + either to change the nature of the match, or to cause it fail earlier + than it otherwise might, when the author of the pattern knows there is + no point in carrying on. + + Consider, for example, the pattern \d+foo when applied to the subject + line + + 123456bar + + After matching all 6 digits and then failing to match "foo", the normal + action of the matcher is to try again with only 5 digits matching the + \d+ item, and then with 4, and so on, before ultimately failing. + "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides + the means for specifying that once a subpattern has matched, it is not + to be re-evaluated in this way. + + If we use atomic grouping for the previous example, the matcher gives + up immediately on failing to match "foo" the first time. The notation + is a kind of special parenthesis, starting with (?> as in this example: + + (?>\d+)foo + + This kind of parenthesis "locks up" the part of the pattern it con- + tains once it has matched, and a failure further into the pattern is + prevented from backtracking into it. Backtracking past it to previous + items, however, works as normal. + + An alternative description is that a subpattern of this type matches + the string of characters that an identical standalone pattern would + match, if anchored at the current point in the subject string. + + Atomic grouping subpatterns are not capturing subpatterns. Simple cases + such as the above example can be thought of as a maximizing repeat that + must swallow everything it can. So, while both \d+ and \d+? are pre- + pared to adjust the number of digits they match in order to make the + rest of the pattern match, (?>\d+) can only match an entire sequence of + digits. + + Atomic groups in general can of course contain arbitrarily complicated + subpatterns, and can be nested. However, when the subpattern for an + atomic group is just a single repeated item, as in the example above, a + simpler notation, called a "possessive quantifier" can be used. This + consists of an additional + character following a quantifier. Using + this notation, the previous example can be rewritten as + + \d++foo + + Note that a possessive quantifier can be used with an entire group, for + example: + + (abc|xyz){2,3}+ + + Possessive quantifiers are always greedy; the setting of the + PCRE_UNGREEDY option is ignored. They are a convenient notation for the + simpler forms of atomic group. However, there is no difference in the + meaning of a possessive quantifier and the equivalent atomic group, + though there may be a performance difference; possessive quantifiers + should be slightly faster. + + The possessive quantifier syntax is an extension to the Perl 5.8 syn- + tax. Jeffrey Friedl originated the idea (and the name) in the first + edition of his book. Mike McCloskey liked it, so implemented it when he + built Sun's Java package, and PCRE copied it from there. It ultimately + found its way into Perl at release 5.10. + + PCRE has an optimization that automatically "possessifies" certain sim- + ple pattern constructs. For example, the sequence A+B is treated as + A++B because there is no point in backtracking into a sequence of A's + when B must follow. + + When a pattern contains an unlimited repeat inside a subpattern that + can itself be repeated an unlimited number of times, the use of an + atomic group is the only way to avoid some failing matches taking a + very long time indeed. The pattern + + (\D+|<\d+>)*[!?] + + matches an unlimited number of substrings that either consist of non- + digits, or digits enclosed in <>, followed by either ! or ?. When it + matches, it runs quickly. However, if it is applied to + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + it takes a long time before reporting failure. This is because the + string can be divided between the internal \D+ repeat and the external + * repeat in a large number of ways, and all have to be tried. (The + example uses [!?] rather than a single character at the end, because + both PCRE and Perl have an optimization that allows for fast failure + when a single character is used. They remember the last single charac- + ter that is required for a match, and fail early if it is not present + in the string.) If the pattern is changed so that it uses an atomic + group, like this: + + ((?>\D+)|<\d+>)*[!?] + + sequences of non-digits cannot be broken, and failure happens quickly. + + +BACK REFERENCES + + Outside a character class, a backslash followed by a digit greater than + 0 (and possibly further digits) is a back reference to a capturing sub- + pattern earlier (that is, to its left) in the pattern, provided there + have been that many previous capturing left parentheses. + + However, if the decimal number following the backslash is less than 10, + it is always taken as a back reference, and causes an error only if + there are not that many capturing left parentheses in the entire pat- + tern. In other words, the parentheses that are referenced need not be + to the left of the reference for numbers less than 10. A "forward back + reference" of this type can make sense when a repetition is involved + and the subpattern to the right has participated in an earlier itera- + tion. + + It is not possible to have a numerical "forward back reference" to a + subpattern whose number is 10 or more using this syntax because a + sequence such as \50 is interpreted as a character defined in octal. + See the subsection entitled "Non-printing characters" above for further + details of the handling of digits following a backslash. There is no + such problem when named parentheses are used. A back reference to any + subpattern is possible using named parentheses (see below). + + Another way of avoiding the ambiguity inherent in the use of digits + following a backslash is to use the \g escape sequence. This escape + must be followed by an unsigned number or a negative number, optionally + enclosed in braces. These examples are all identical: + + (ring), \1 + (ring), \g1 + (ring), \g{1} + + An unsigned number specifies an absolute reference without the ambigu- + ity that is present in the older syntax. It is also useful when literal + digits follow the reference. A negative number is a relative reference. + Consider this example: + + (abc(def)ghi)\g{-1} + + The sequence \g{-1} is a reference to the most recently started captur- + ing subpattern before \g, that is, is it equivalent to \2 in this exam- + ple. Similarly, \g{-2} would be equivalent to \1. The use of relative + references can be helpful in long patterns, and also in patterns that + are created by joining together fragments that contain references + within themselves. + + A back reference matches whatever actually matched the capturing sub- + pattern in the current subject string, rather than anything matching + the subpattern itself (see "Subpatterns as subroutines" below for a way + of doing that). So the pattern + + (sens|respons)e and \1ibility + + matches "sense and sensibility" and "response and responsibility", but + not "sense and responsibility". If caseful matching is in force at the + time of the back reference, the case of letters is relevant. For exam- + ple, + + ((?i)rah)\s+\1 + + matches "rah rah" and "RAH RAH", but not "RAH rah", even though the + original capturing subpattern is matched caselessly. + + There are several different ways of writing back references to named + subpatterns. The .NET syntax \k{name} and the Perl syntax \k or + \k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's + unified back reference syntax, in which \g can be used for both numeric + and named references, is also supported. We could rewrite the above + example in any of the following ways: + + (?(?i)rah)\s+\k + (?'p1'(?i)rah)\s+\k{p1} + (?P(?i)rah)\s+(?P=p1) + (?(?i)rah)\s+\g{p1} + + A subpattern that is referenced by name may appear in the pattern + before or after the reference. + + There may be more than one back reference to the same subpattern. If a + subpattern has not actually been used in a particular match, any back + references to it always fail by default. For example, the pattern + + (a|(bc))\2 + + always fails if it starts to match "a" rather than "bc". However, if + the PCRE_JAVASCRIPT_COMPAT option is set at compile time, a back refer- + ence to an unset value matches an empty string. + + Because there may be many capturing parentheses in a pattern, all dig- + its following a backslash are taken as part of a potential back refer- + ence number. If the pattern continues with a digit character, some + delimiter must be used to terminate the back reference. If the + PCRE_EXTENDED option is set, this can be white space. Otherwise, the + \g{ syntax or an empty comment (see "Comments" below) can be used. + + Recursive back references + + A back reference that occurs inside the parentheses to which it refers + fails when the subpattern is first used, so, for example, (a\1) never + matches. However, such references can be useful inside repeated sub- + patterns. For example, the pattern + + (a|b\1)+ + + matches any number of "a"s and also "aba", "ababbaa" etc. At each iter- + ation of the subpattern, the back reference matches the character + string corresponding to the previous iteration. In order for this to + work, the pattern must be such that the first iteration does not need + to match the back reference. This can be done using alternation, as in + the example above, or by a quantifier with a minimum of zero. + + Back references of this type cause the group that they reference to be + treated as an atomic group. Once the whole group has been matched, a + subsequent matching failure cannot cause backtracking into the middle + of the group. + + +ASSERTIONS + + An assertion is a test on the characters following or preceding the + current matching point that does not actually consume any characters. + The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are + described above. + + More complicated assertions are coded as subpatterns. There are two + kinds: those that look ahead of the current position in the subject + string, and those that look behind it. An assertion subpattern is + matched in the normal way, except that it does not cause the current + matching position to be changed. + + Assertion subpatterns are not capturing subpatterns. If such an asser- + tion contains capturing subpatterns within it, these are counted for + the purposes of numbering the capturing subpatterns in the whole pat- + tern. However, substring capturing is carried out only for positive + assertions, because it does not make sense for negative assertions. + + 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 + + Lookahead assertions start with (?= for positive assertions and (?! for + negative assertions. For example, + + \w+(?=;) + + matches a word followed by a semicolon, but does not include the semi- + colon in the match, and + + foo(?!bar) + + matches any occurrence of "foo" that is not followed by "bar". Note + that the apparently similar pattern + + (?!foo)bar + + does not find an occurrence of "bar" that is preceded by something + other than "foo"; it finds any occurrence of "bar" whatsoever, because + the assertion (?!foo) is always true when the next three characters are + "bar". A lookbehind assertion is needed to achieve the other effect. + + If you want to force a matching failure at some point in a pattern, the + most convenient way to do it is with (?!) because an empty string + always matches, so an assertion that requires there not to be an empty + string must always fail. The backtracking control verb (*FAIL) or (*F) + is a synonym for (?!). + + Lookbehind assertions + + Lookbehind assertions start with (?<= for positive assertions and (?)...) 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 + 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 + or any subpattern has been made. If digits or a name preceded by amper- + sand follow the letter R, for example: + + (?(R3)...) or (?(R&name)...) + + 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 + 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 + syntax for recursive patterns is described below. + + Defining subpatterns for use by reference only + + If the condition is the string (DEFINE), and there is no subpattern + with the name DEFINE, the condition is always false. In this case, + there may be only one alternative in the subpattern. It is always + skipped if control reaches this point in the pattern; the idea of + DEFINE is that it can be used to define subroutines that can be refer- + enced from elsewhere. (The use of subroutines is described below.) For + example, a pattern to match an IPv4 address such as "192.168.23.245" + 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 + + The first part of the pattern is a DEFINE group inside which a another + group named "byte" is defined. This matches an individual component of + an IPv4 address (a number less than 256). When matching takes place, + this part of the pattern is skipped because DEFINE acts like a false + condition. The rest of the pattern uses references to the named group + to match the four dot-separated components of an IPv4 address, insist- + ing on a word boundary at each end. + + Assertion conditions + + If the condition is not in any of the above formats, it must be an + assertion. This may be a positive or negative lookahead or lookbehind + assertion. Consider this pattern, again containing non-significant + white space, and with the two alternatives on the second line: + + (?(?=[^a-z]*[a-z]) + \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) + + The condition is a positive lookahead assertion that matches an + optional sequence of non-letters followed by a letter. In other words, + it tests for the presence of at least one letter in the subject. If a + letter is found, the subject is matched against the first alternative; + otherwise it is matched against the second. This pattern matches + strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are + letters and dd are digits. + + +COMMENTS + + There are two ways of including comments in patterns that are processed + by PCRE. In both cases, the start of the comment must not be in a char- + acter class, nor in the middle of any other sequence of related charac- + ters such as (?: or a subpattern name or number. The characters that + make up a comment play no part in the pattern matching. + + The sequence (?# marks the start of a comment that continues up to the + next closing parenthesis. Nested parentheses are not permitted. If the + PCRE_EXTENDED option is set, an unescaped # character also introduces a + comment, which in this case continues to immediately after the next + newline character or character sequence in the pattern. Which charac- + ters are interpreted as newlines is controlled by the options passed to + a compiling function or by a special sequence at the start of the pat- + 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 + + On encountering the # character, pcre_compile() skips along, looking + for a newline in the pattern. The sequence \n is still literal at this + stage, so it does not terminate the comment. Only an actual character + with the code value 0x0a (the default newline) does so. + + +RECURSIVE PATTERNS + + Consider the problem of matching a string in parentheses, allowing for + unlimited nested parentheses. Without the use of recursion, the best + that can be done is to use a pattern that matches up to some fixed + depth of nesting. It is not possible to handle an arbitrary nesting + depth. + + For some time, Perl has provided a facility that allows regular expres- + sions to recurse (amongst other things). It does this by interpolating + Perl code in the expression at run time, and the code can refer to the + expression itself. A Perl pattern using code interpolation to solve the + parentheses problem can be created like this: + + $re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x; + + The (?p{...}) item interpolates Perl code at run time, and in this case + refers recursively to the pattern in which it appears. + + Obviously, PCRE cannot support the interpolation of Perl code. Instead, + it supports special syntax for recursion of the entire pattern, and + also for individual subpattern recursion. After its introduction in + PCRE and Python, this kind of recursion was subsequently introduced + into Perl at release 5.10. + + A special item that consists of (? followed by a number greater than + zero and a closing parenthesis is a recursive subroutine call of the + subpattern of the given number, provided that it occurs inside that + subpattern. (If not, it is a non-recursive subroutine call, which is + described in the next section.) The special item (?R) or (?0) is a + 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): + + \( ( [^()]++ | (?R) )* \) + + First it matches an opening parenthesis. Then it matches any number of + substrings which can either be a sequence of non-parentheses, or a + recursive match of the pattern itself (that is, a correctly parenthe- + sized substring). Finally there is a closing parenthesis. Note the use + of a possessive quantifier to avoid backtracking into sequences of non- + parentheses. + + If this were part of a larger pattern, you would not want to recurse + the entire pattern, so instead you could use this: + + ( \( ( [^()]++ | (?1) )* \) ) + + We have put the pattern into parentheses, and caused the recursion to + refer to them instead of the whole pattern. + + In a larger pattern, keeping track of parenthesis numbers can be + tricky. This is made easier by the use of relative references. Instead + of (?1) in the pattern above you can write (?-2) to refer to the second + most recently opened parentheses preceding the recursion. In other + words, a negative number counts capturing parentheses leftwards from + the point at which it is encountered. + + It is also possible to refer to subsequently opened parentheses, by + writing references such as (?+2). However, these cannot be recursive + because the reference is not inside the parentheses that are refer- + enced. They are always non-recursive subroutine calls, as described in + 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 + supported. We could rewrite the above example as follows: + + (? \( ( [^()]++ | (?&pn) )* \) ) + + If there is more than one subpattern with the same name, the earliest + one is used. + + This particular example pattern that we have been looking at contains + nested unlimited repeats, and so the use of a possessive quantifier for + matching strings of non-parentheses is important when applying the pat- + tern to strings that do not match. For example, when this pattern is + applied to + + (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa() + + it yields "no match" quickly. However, if a possessive quantifier is + not used, the match runs for a very long time indeed because there are + so many different ways the + and * repeats can carve up the subject, + and all have to be tested before failure can be reported. + + At the end of a match, the values of capturing parentheses are those + from the outermost level. If you want to obtain intermediate values, a + callout function can be used (see below and the pcrecallout documenta- + tion). If the pattern above is matched against + + (ab(cd)ef) + + the value for the inner capturing parentheses (numbered 2) is "ef", + which is the last value taken on at the top level. If a capturing sub- + pattern is not matched at the top level, its final captured value is + unset, even if it was (temporarily) set at a deeper level during the + 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 + 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- + 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. + The (?R) item is the actual recursive call. + + Differences in recursion processing between PCRE and Perl + + Recursion processing in PCRE differs from Perl in two important ways. + In PCRE (like Python, but unlike Perl), a recursive subpattern call is + always treated as an atomic group. That is, once it has matched some of + the subject string, it is never re-entered, even if it contains untried + alternatives and there is a subsequent matching failure. This can be + illustrated by the following pattern, which purports to match a palin- + dromic string that contains an odd number of characters (for example, + "a", "aba", "abcba", "abcdcba"): + + ^(.|(.)(?1)\2)$ + + The idea is that it either matches a single character, or two identical + characters surrounding a sub-palindrome. In Perl, this pattern works; + in PCRE it does not if the pattern is longer than three characters. + Consider the subject string "abcba": + + At the top level, the first character is matched, but as it is not at + the end of the string, the first alternative fails; the second alterna- + tive is taken and the recursion kicks in. The recursive call to subpat- + tern 1 successfully matches the next character ("b"). (Note that the + beginning and end of line tests are not part of the recursion). + + Back at the top level, the next character ("c") is compared with what + subpattern 2 matched, which was "a". This fails. Because the recursion + is treated as an atomic group, there are now no backtracking points, + and so the entire match fails. (Perl is able, at this point, to re- + enter the recursion and try the second alternative.) However, if the + pattern is written with the alternatives in the other order, things are + different: + + ^((.)(?1)\2|.)$ + + This time, the recursing alternative is tried first, and continues to + recurse until it runs out of characters, at which point the recursion + fails. But this time we do have another alternative to try at the + higher level. That is the big difference: in the previous case the + remaining alternative is at a deeper recursion level, which PCRE cannot + use. + + To change the pattern so that it matches all palindromic strings, not + just those with an odd number of characters, it is tempting to change + the pattern to this: + + ^((.)(?1)\2|.?)$ + + Again, this works in Perl, but not in PCRE, and for the same reason. + When a deeper recursion has matched a single character, it cannot be + entered again in order to match an empty string. The solution is to + separate the two cases, and write out the odd and even cases as alter- + natives at the higher level: + + ^(?:((.)(?1)\2|)|((.)(?3)\4|.)) + + If you want to match typical palindromic phrases, the pattern has to + ignore all non-word characters, which can be done like this: + + ^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$ + + If run with the PCRE_CASELESS option, this pattern matches phrases such + as "A man, a plan, a canal: Panama!" and it works well in both PCRE and + Perl. Note the use of the possessive quantifier *+ to avoid backtrack- + ing into sequences of non-word characters. Without this, PCRE takes a + great deal longer (ten times or more) to match typical phrases, and + Perl takes so long that you think it has gone into a loop. + + WARNING: The palindrome-matching patterns above work only if the sub- + ject string does not start with a palindrome that is shorter than the + entire string. For example, although "abcba" is correctly matched, if + the subject is "ababa", PCRE finds the palindrome "aba" at the start, + then fails at top level because the end of the string does not follow. + Once again, it cannot jump back into the recursion to try other alter- + 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 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)... + (...(?+1)...(relative)... + + An earlier example pointed out that the pattern + + (sens|respons)e and \1ibility + + matches "sense and sensibility" and "response and responsibility", but + not "sense and responsibility". If instead the pattern + + (sens|respons)e and (?1)ibility + + is used, it does match "sense and responsibility" as well as the other + two strings. Another example is given in the discussion of DEFINE + above. + + All subroutine calls, whether recursive or not, are always treated as + atomic groups. That is, once a subroutine has matched some of the sub- + 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. + + Processing options such as case-independence are fixed when a subpat- + tern is defined, so if it is used as a subroutine, such options cannot + be changed for different calls. For example, consider this pattern: + + (abc)(?i:(?-1)) + + It matches "abcabc". It does not match "abcABC" because the change of + processing option does not affect the called subpattern. + + +ONIGURUMA SUBROUTINE SYNTAX + + For compatibility with Oniguruma, the non-Perl syntax \g followed by a + name or a number enclosed either in angle brackets or single quotes, is + an alternative syntax for referencing a subpattern as a subroutine, + possibly recursively. Here are two of the examples used above, rewrit- + ten using this syntax: + + (? \( ( (?>[^()]+) | \g )* \) ) + (sens|respons)e and \g'1'ibility + + PCRE supports an extension to Oniguruma: if a number is preceded by a + plus or a minus sign it is taken as a relative reference. For example: + + (abc)(?i:\g<-1>) + + Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not + synonymous. The former is a back reference; the latter is a subroutine + call. + + +CALLOUTS + + Perl has a feature whereby using the sequence (?{...}) causes arbitrary + Perl code to be obeyed in the middle of matching a regular expression. + This makes it possible, amongst other things, to extract different sub- + strings that match the same pair of parentheses when there is a repeti- + tion. + + PCRE provides a similar feature, but of course it cannot obey arbitrary + Perl code. The feature is called "callout". The caller of PCRE provides + an external function by putting its entry point in the global variable + pcre_callout (8-bit library) or pcre[16|32]_callout (16-bit or 32-bit + library). By default, this variable contains NULL, which disables all + calling out. + + Within a regular expression, (?C) indicates the points at which the + external function is to be called. If you want to identify different + callout points, you can put a number less than 256 after the letter C. + The default value is zero. For example, this pattern has two callout + points: + + (?C1)abc(?C2)def + + If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, call- + outs are automatically installed before each item in the pattern. They + are all numbered 255. + + 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 + + Perl 5.10 introduced a number of "Special Backtracking Control Verbs", + which are described in the Perl documentation as "experimental and sub- + ject to change or removal in a future version of Perl". It goes on to + say: "Their usage in production code should be noted to avoid problems + during upgrades." The same remarks apply to the PCRE features described + in this section. + + Since these verbs are specifically related to backtracking, most of + them can be used only when the pattern is to be matched using one of + the traditional matching functions, which use a backtracking algorithm. + With the exception of (*FAIL), which behaves like a failing negative + assertion, they cause an error if encountered by a DFA matching func- + tion. + + 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. A name is + any sequence of characters that does not include a closing parenthesis. + The maximum length of name is 255 in the 8-bit library and 65535 in the + 16-bit and 32-bit library. If the name is empty, that is, if the clos- + ing parenthesis immediately follows the colon, the effect is as if the + colon were not there. Any number of these verbs may occur in a pattern. + + 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 minimum length of matching subject, or that a particular + character must be present. When one of these optimizations suppresses + the running of a match, any included backtracking verbs will not, of + 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 + be followed by a name. + + (*ACCEPT) + + This verb causes the match to end successfully, skipping the remainder + of the pattern. However, when it is inside a subpattern that is called + as a subroutine, only that subpattern is ended successfully. Matching + then continues at the outer level. If (*ACCEPT) is inside capturing + parentheses, the data so far is captured. For example: + + A((?:A|B(*ACCEPT)|C)D) + + This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap- + tured by the outer parentheses. + + (*FAIL) or (*F) + + This verb causes a matching failure, forcing backtracking to occur. It + is equivalent to (?!) but easier to read. The Perl documentation notes + that it is probably useful only when combined with (?{}) or (??{}). + Those are, of course, Perl features that are not present in PCRE. The + nearest equivalent is the callout feature, as for example in this pat- + tern: + + a+(?C)(*FAIL) + + 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 + 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 + have to be unique. + + When a match succeeds, the name of the last-encountered (*MARK) on the + matching path is passed back to the caller as described in the section + entitled "Extra data for pcre_exec()" in the pcreapi documentation. + Here is an example of pcretest output, where the /K modifier requests + the retrieval and outputting of (*MARK) data: + + re> /X(*MARK:A)Y|X(*MARK:B)Z/K + data> XY + 0: XY + MK: A + XZ + 0: XZ + MK: B + + The (*MARK) name is tagged with "MK:" in this output, and in this exam- + ple it indicates which of the two alternatives matched. This is a more + efficient way of obtaining this information than putting each alterna- + tive in its own capturing parentheses. + + If (*MARK) is encountered in a positive assertion, its name is recorded + and passed back if it is the last-encountered. This does not happen for + negative assertions. + + 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: + + re> /X(*MARK:A)Y|X(*MARK:B)Z/K + data> XP + No match, mark = B + + Note that in this unanchored example the mark is retained from the + 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 + this localization also applies in subroutine calls and assertions.) + + 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 + to fail outright if the rest of the pattern does not match. Even if the + pattern is unanchored, no further attempts to find a match by advancing + the starting point take place. Once (*COMMIT) has been passed, + pcre_exec() is committed to finding a match at the current starting + point, or not at all. For example: + + a+(*COMMIT)b + + 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) + 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 + shown in this pcretest example: + + 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 + 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 + uses of (*PRUNE) that cannot be expressed in any other way. The behav- + iour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an + anchored pattern (*PRUNE) has the same effect as (*COMMIT). + + (*SKIP) + + This verb, when given without a name, is like (*PRUNE), except that if + the pattern is unanchored, the "bumpalong" advance is not to the next + character, but to the position in the subject where (*SKIP) was encoun- + tered. (*SKIP) signifies that whatever text was matched leading up to + it cannot be part of a successful match. Consider: + + a+(*SKIP)b + + If the subject is "aaaac...", after the first match attempt fails + (starting at the first character in the string), the starting point + skips on to start the next attempt at "c". Note that a possessive quan- + tifer does not have the same effect as this example; although it would + suppress backtracking during the first match attempt, the second + attempt would start at the second character instead of skipping on to + "c". + + (*SKIP:NAME) + + When (*SKIP) has an associated name, its behaviour is modified. If the + following pattern fails to match, the previous path through the pattern + is searched for the most recent (*MARK) that has the same name. If one + is found, the "bumpalong" advance is to the subject position that cor- + responds to that (*MARK) instead of to where (*SKIP) was encountered. + If no (*MARK) with a matching name is found, the (*SKIP) is ignored. + + (*THEN) or (*THEN:NAME) + + This verb causes a skip to the next innermost alternative if the rest + of the pattern does not match. That is, it cancels pending backtrack- + ing, but only within the current alternative. Its name comes from the + observation that it can be used for a pattern-based if-then-else block: + + ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ... + + If the COND1 pattern matches, FOO is tried (and possibly further items + after the end of the group if FOO succeeds); on failure, the matcher + skips to the second alternative and tries COND2, without backtracking + into COND1. The behaviour of (*THEN:NAME) is exactly the same as + (*MARK:NAME)(*THEN). If (*THEN) is not inside an alternation, it acts + like (*PRUNE). + + Note that a subpattern that does not contain a | character is just a + part of the enclosing alternative; it is not a nested alternation with + only one alternative. The effect of (*THEN) extends beyond such a sub- + pattern to the enclosing alternative. Consider this pattern, where A, + B, etc. are complex pattern fragments that do not contain any | charac- + ters at this level: + + 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 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 alternative (that is, D) does not + happen because (*COMMIT) overrides. + + +SEE ALSO + + pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3), + pcre16(3), pcre32(3). + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 11 November 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCRESYNTAX(3) PCRESYNTAX(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +PCRE REGULAR EXPRESSION SYNTAX SUMMARY + + The full syntax and semantics of the regular expressions that are sup- + ported by PCRE are described in the pcrepattern documentation. This + document contains a quick-reference summary of the syntax. + + +QUOTING + + \x where x is non-alphanumeric is a literal x + \Q...\E treat enclosed characters as literal + + +CHARACTERS + + \a alarm, that is, the BEL character (hex 07) + \cx "control-x", where x is any ASCII character + \e escape (hex 1B) + \f form feed (hex 0C) + \n newline (hex 0A) + \r carriage return (hex 0D) + \t tab (hex 09) + \ddd character with octal code ddd, or backreference + \xhh character with hex code hh + \x{hhh..} character with hex code hhh.. + + +CHARACTER TYPES + + . any character except newline; + in dotall mode, any character whatsoever + \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 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 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 a Unicode extended grapheme cluster + + In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII + characters, even in a UTF mode. However, this can be changed by setting + the PCRE_UCP option. + + +GENERAL CATEGORY PROPERTIES FOR \p and \P + + C Other + Cc Control + Cf Format + Cn Unassigned + Co Private use + Cs Surrogate + + L Letter + Ll Lower case letter + Lm Modifier letter + Lo Other letter + Lt Title case letter + Lu Upper case letter + L& Ll, Lu, or Lt + + M Mark + Mc Spacing mark + Me Enclosing mark + Mn Non-spacing mark + + N Number + Nd Decimal number + Nl Letter number + No Other number + + P Punctuation + Pc Connector punctuation + Pd Dash punctuation + Pe Close punctuation + Pf Final punctuation + Pi Initial punctuation + Po Other punctuation + Ps Open punctuation + + S Symbol + Sc Currency symbol + Sk Modifier symbol + Sm Mathematical symbol + So Other symbol + + Z Separator + Zl Line separator + Zp Paragraph separator + Zs Space separator + + +PCRE SPECIAL CATEGORY PROPERTIES FOR \p and \P + + Xan Alphanumeric: union of properties L and N + Xps POSIX space: property Z or tab, NL, VT, FF, CR + Xsp Perl space: property Z or tab, NL, FF, CR + Xwd Perl word: property Xan or underscore + + +SCRIPT NAMES FOR \p AND \P + + Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, + Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, + Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, + Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, + Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira- + gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip- + tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, + Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, + 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 + + [...] positive character class + [^...] negative character class + [x-y] range (can be used for hex characters) + [[:xxx:]] positive POSIX named set + [[:^xxx:]] negative POSIX named set + + alnum alphanumeric + alpha alphabetic + ascii 0-127 + blank space or tab + cntrl control character + digit decimal digit + graph printing, excluding space + lower lower case letter + print printing, including space + punct printing, excluding alphanumeric + space white space + upper upper case letter + word same as \w + xdigit hexadecimal digit + + In PCRE, POSIX character set names recognize only ASCII characters by + default, but some of them use Unicode properties if PCRE_UCP is set. + You can use \Q...\E inside a character class. + + +QUANTIFIERS + + ? 0 or 1, greedy + ?+ 0 or 1, possessive + ?? 0 or 1, lazy + * 0 or more, greedy + *+ 0 or more, possessive + *? 0 or more, lazy + + 1 or more, greedy + ++ 1 or more, possessive + +? 1 or more, lazy + {n} exactly n + {n,m} at least n, no more than m, greedy + {n,m}+ at least n, no more than m, possessive + {n,m}? at least n, no more than m, lazy + {n,} n or more, greedy + {n,}+ n or more, possessive + {n,}? n or more, lazy + + +ANCHORS AND SIMPLE ASSERTIONS + + \b word boundary + \B not a word boundary + ^ start of subject + also after internal newline in multiline mode + \A start of subject + $ end of subject + also before newline at end of subject + also before internal newline in multiline mode + \Z end of subject + also before newline at end of subject + \z end of subject + \G first matching position in subject + + +MATCH POINT RESET + + \K reset start of match + + +ALTERNATION + + expr|expr|expr... + + +CAPTURING + + (...) capturing group + (?...) named capturing group (Perl) + (?'name'...) named capturing group (Perl) + (?P...) named capturing group (Python) + (?:...) non-capturing group + (?|...) non-capturing group; reset group numbers for + capturing groups in each alternative + + +ATOMIC GROUPS + + (?>...) atomic, non-capturing group + + +COMMENT + + (?#....) comment (not nestable) + + +OPTION SETTING + + (?i) caseless + (?J) allow duplicate names + (?m) multiline + (?s) single line (dotall) + (?U) default ungreedy (lazy) + (?x) extended (ignore white space) + (?-...) unset option(s) + + The following are recognized only at the start of a pattern or after + 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: 8-bit library (PCRE_UTF8) + (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16) + (*UTF32) set UTF-32 mode: 32-bit library (PCRE_UTF32) + (*UTF) set appropriate UTF mode for the library in use + (*UCP) set PCRE_UCP (use Unicode properties for \d etc) + + +LOOKAHEAD AND LOOKBEHIND ASSERTIONS + + (?=...) positive look ahead + (?!...) negative look ahead + (?<=...) positive look behind + (? reference by name (Perl) + \k'name' reference by name (Perl) + \g{name} reference by name (Perl) + \k{name} reference by name (.NET) + (?P=name) reference by name (Python) + + +SUBROUTINE REFERENCES (POSSIBLY RECURSIVE) + + (?R) recurse whole pattern + (?n) call subpattern by absolute number + (?+n) call subpattern by relative number + (?-n) call subpattern by relative number + (?&name) call subpattern by name (Perl) + (?P>name) call subpattern by name (Python) + \g call subpattern by name (Oniguruma) + \g'name' call subpattern by name (Oniguruma) + \g call subpattern by absolute number (Oniguruma) + \g'n' call subpattern by absolute number (Oniguruma) + \g<+n> call subpattern by relative number (PCRE extension) + \g'+n' call subpattern by relative number (PCRE extension) + \g<-n> call subpattern by relative number (PCRE extension) + \g'-n' call subpattern by relative number (PCRE extension) + + +CONDITIONAL PATTERNS + + (?(condition)yes-pattern) + (?(condition)yes-pattern|no-pattern) + + (?(n)... absolute reference condition + (?(+n)... relative reference condition + (?(-n)... relative reference condition + (?()... named reference condition (Perl) + (?('name')... named reference condition (Perl) + (?(name)... named reference condition (PCRE) + (?(R)... overall recursion condition + (?(Rn)... specific group recursion condition + (?(R&name)... specific recursion condition + (?(DEFINE)... define subpattern for reference + (?(assert)... assertion condition + + +BACKTRACKING CONTROL + + The following act immediately they are reached: + + (*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 + what happens afterwards. Those that advance the start-of-match point do + so only if the pattern is not anchored. + + (*COMMIT) overall failure, no advance of starting point + (*PRUNE) advance to next starting character + (*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_...), (*UTF8), (*UTF16), (*UTF32) or (*UCP) option. + + (*CR) carriage return only + (*LF) linefeed only + (*CRLF) carriage return followed by linefeed + (*ANYCRLF) all three of the above + (*ANY) any Unicode newline sequence + + +WHAT \R MATCHES + + These are recognized only at the very start of the pattern or after a + (*...) option that sets the newline convention or a UTF or UCP mode. + + (*BSR_ANYCRLF) CR, LF, or CRLF + (*BSR_UNICODE) any Unicode newline sequence + + +CALLOUTS + + (?C) callout + (?Cn) callout with data n + + +SEE ALSO + + pcrepattern(3), pcreapi(3), pcrecallout(3), pcrematching(3), pcre(3). + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 11 November 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREUNICODE(3) PCREUNICODE(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +UTF-8, UTF-16, UTF-32, AND UNICODE PROPERTY SUPPORT + + As well as UTF-8 support, PCRE also supports UTF-16 (from release 8.30) + and UTF-32 (from release 8.32), by means of two additional libraries. + They 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) or (*UTF). 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 individual 1-byte characters. + + +UTF-16 AND UTF-32 SUPPORT + + In order process UTF-16 or UTF-32 strings, you must build PCRE's 16-bit + or 32-bit library with UTF support, and, in addition, you must call + pcre16_compile() or pcre32_compile() with the PCRE_UTF16 or PCRE_UTF32 + option flag, as appropriate. Alternatively, the pattern must start with + the sequence (*UTF16), (*UTF32), as appropriate, or (*UTF), which can + be used with either library. When UTF mode is set, both the pattern and + any subject strings that are matched against it are treated as UTF-16 + or UTF-32 strings instead of strings of individual 16-bit or 32-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_UTF[8|16|32] 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&. Full lists is given in the pcrepattern + and pcresyntax 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 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 the surrogate area and the non-characters. + + Characters in the "Surrogate Area" of Unicode are reserved for use by + UTF-16, where they are used in pairs to encode codepoints with values + greater than 0xFFFF. The code points that are encoded by UTF-16 pairs + are available independently in the UTF-8 and UTF-32 encodings. (In + other words, the whole surrogate thing is a fudge for UTF-16 which + unfortunately messes up UTF-8 and UTF-32.) + + Also excluded are the "Non-Character" code points, which are U+FDD0 to + U+FDEF and the last two code points in each plane, U+??FFFE and + U+??FFFF. + + If an invalid UTF-8 string is passed to PCRE, an error return is given. + At compile time, the only additional information is the offset to the + first byte of the failing character. The run-time functions pcre_exec() + 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. 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. + + Note that passing PCRE_NO_UTF8_CHECK to pcre_compile() just disables + the check for the pattern; it does not also apply to subject strings. + If you want to disable the check for a subject string you must pass + this option to pcre_exec() or pcre_dfa_exec(). + + If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, the + result is undefined and your program may crash. + + 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. + + Excluded are the "Non-Character" code points, which are U+FDD0 to + U+FDEF and the last two code points in each plane, U+??FFFE and + U+??FFFF. + + If an invalid UTF-16 string is passed to PCRE, an error return is + given. At compile time, the only additional information is the offset + to the first data unit of the failing character. The run-time functions + 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. However, if an invalid string is + passed, the result is undefined. + + Validity of UTF-32 strings + + When you set the PCRE_UTF32 flag, the strings of 32-bit data units that + are passed as patterns and subjects are (by default) checked for valid- + ity on entry to the relevant functions. This check allows only values + in the range U+0 to U+10FFFF, excluding the surrogate area U+D800 to + U+DFFF, and the "Non-Character" code points, which are U+FDD0 to U+FDEF + and the last two characters in each plane, U+??FFFE and U+??FFFF. + + If an invalid UTF-32 string is passed to PCRE, an error return is + given. At compile time, the only additional information is the offset + to the first data unit of the failing character. The run-time functions + pcre32_exec() and pcre32_dfa_exec() also pass back this information, as + well as a more detailed reason code if the caller has provided memory + in which to do this. + + In some situations, you may already know that your strings are valid, + and therefore want to skip these checks in order to improve perfor- + mance. If you set the PCRE_NO_UTF32_CHECK flag at compile time or at + run time, PCRE assumes that the pattern or subject it is given (respec- + tively) contains only valid UTF-32 sequences. In this case, it does not + diagnose an invalid UTF-32 string. However, if an invalid string is + passed, the result is undefined. + + General comments about UTF modes + + 1. Codepoints less than 256 can be specified in patterns by either + braced or unbraced hexadecimal escape sequences (for example, \x{b3} or + \xb3). Larger values have to use braced sequences. + + 2. Octal numbers up to \777 are recognized, and in UTF-8 mode they + 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, or a single 32-bit + data unit in UTF-32 mode, but its use can lead to some strange effects + because it breaks up multi-unit characters (see the description of \C + in the pcrepattern documentation). The use of \C is not supported in + the alternative matching function pcre[16|32]_dfa_exec(), nor is it + supported in UTF mode by the JIT optimization of pcre[16|32]_exec(). If + JIT optimization is requested for a UTF pattern that contains \C, it + 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. + A few Unicode characters such as Greek sigma have more than two code- + points that are case-equivalent. Up to and including PCRE release 8.31, + only one-to-one case mappings were supported, but later releases (with + Unicode property support) do treat as case-equivalent all versions of + characters such as Greek sigma. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 11 November 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, 16-BIT AND 32-BIT SUPPORT + + JIT support is available for all of the 8-bit, 16-bit and 32-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, sub- + stitute the 16-bit functions and 16-bit structures (for example, + pcre16_jit_stack instead of pcre_jit_stack). If you are using the + 32-bit library, substitute the 32-bit functions and 32-bit structures + (for example, pcre32_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 + SPARC 32-bit (experimental) + + 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 normal API is implemented in a way that falls back to the interpre- + tive code if JIT is not available. For programs that need the best pos- + sible performance, there is also a "fast path" API that is JIT-spe- + cific. + + 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_NO_UTF32_CHECK, PCRE_NOT- + BOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PAR- + TIAL_HARD, and PCRE_PARTIAL_SOFT. + + The unsupported pattern items are: + + \C match a single byte; not supported in UTF-8 mode + (?Cn) callouts + (*PRUNE) ) + (*SKIP) ) backtracking control verbs + (*THEN) ) + + Support for some of these may be added in future. + + +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 achieve + 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); + + +JIT FAST PATH API + + Because the API described above falls back to interpreted execution + when JIT is not available, it is convenient for programs that are writ- + ten for general use in many environments. However, calling JIT via + pcre_exec() does have a performance impact. Programs that are written + for use where JIT is known to be available, and which need the best + possible performance, can instead use a "fast path" API to call JIT + execution directly instead of calling pcre_exec() (obviously only for + patterns that have been successfully studied by JIT). + + The fast path function is called pcre_jit_exec(), and it takes exactly + the same arguments as pcre_exec(), plus one additional argument that + must point to a JIT stack. The JIT stack arrangements described above + do not apply. The return values are the same as for pcre_exec(). + + When you call pcre_exec(), as well as testing for invalid options, a + number of other sanity checks are performed on the arguments. For exam- + ple, if the subject pointer is NULL, or its length is negative, an + immediate error is given. Also, unless PCRE_NO_UTF[8|16|32] is set, a + UTF subject string is tested for validity. In the interests of speed, + these checks do not happen on the JIT fast path, and if invalid data is + passed, the result is undefined. + + Bypassing the sanity checks and the pcre_exec() wrapping can give + speedups of more than 10%. + + +SEE ALSO + + pcreapi(3) + + +AUTHOR + + Philip Hazel (FAQ by Zoltan Herczeg) + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 31 October 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREPARTIAL(3) PCREPARTIAL(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +PARTIAL MATCHING IN PCRE + + In normal use of PCRE, if the subject string that is passed to a match- + 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 + might be a date in the form ddmmmyy, defined by this pattern: + + ^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$ + + If the application sees the user's keystrokes one by one, and can check + that what has been typed so far is potentially valid, it is able to + raise an error as soon as a mistake is made, by beeping and not + reflecting the character that has been typed, for example. This immedi- + ate feedback is likely to be a better user interface than a check that + is delayed until the entire string has been entered. Partial matching + can also be useful when the subject string is very long and is not all + 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 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(), pcre16_study() or pcre32_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 pcre[16|32]_exec() + + A partial match occurs during a call to pcre_exec() or + pcre[16|32]_exec() when the end of the subject string is reached suc- + cessfully, but matching cannot continue because more characters are + needed. However, at least one character in the subject must have been + 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 partially matched string. However, for patterns that contain look- + behind assertions, or \K, or begin with \b or \B, earlier characters + have been inspected while carrying out the match. For example: + + /(?<=abc)123/ + + This pattern matches "123", but only if it is preceded by "abc". If the + subject string is "xyzabc12", the offsets after a partial match are for + the substring "abc12", because all these characters are needed if + another match is tried with extra characters added to the subject. + + 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() OR pcre[16|32]_exec() + + If PCRE_PARTIAL_SOFT is set when pcre_exec() or pcre[16|32]_exec() + identifies a partial match, the partial match is remembered, but match- + ing 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 + the subject string is potentially complete. For example, \z, \Z, and $ + match at the end of the subject, as normal, and for \b and \B the end + of the subject is treated as a non-alphanumeric. + + If there is more than one partial match, the first one that was found + provides the data that is returned. Consider this pattern: + + /123\w+X|dogY/ + + If this is matched against the subject string "abc123dog", both alter- + natives fail to match, but the end of the subject is reached during + matching, so PCRE_ERROR_PARTIAL is returned. The offsets are set to 3 + and 9, identifying "123dog" as the first partial match that was found. + (In this example, there are two partial matches, because "dog" on its + own partially matches the second alternative.) + + PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre[16|32]_exec() + + If PCRE_PARTIAL_HARD is set for pcre_exec() or pcre[16|32]_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 + + The difference between the two partial matching options can be illus- + trated by a pattern such as: + + /dog(sbody)?/ + + This matches either "dog" or "dogsbody", greedily (that is, it prefers + the longer string if possible). If it is matched against the string + "dog" with PCRE_PARTIAL_SOFT, it yields a complete match for "dog". + However, if PCRE_PARTIAL_HARD is set, the result is PCRE_ERROR_PARTIAL. + On the other hand, if the pattern is made ungreedy the result is dif- + ferent: + + /dog(sbody)??/ + + 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", because it will always + find the shorter match first. + + +PARTIAL MATCHING USING pcre_dfa_exec() OR pcre[16|32]_dfa_exec() + + 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 + are returned. However, if PCRE_PARTIAL_HARD is set, a partial match + takes precedence over any complete matches. The portion of the string + that was inspected when the longest partial match was found is set as + the first matching string, provided there are at least two slots in the + offsets vector. + + 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 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 + + If a pattern ends with one of sequences \b or \B, which test for word + boundaries, partial matching with PCRE_PARTIAL_SOFT can give counter- + intuitive results. Consider this pattern: + + /\bcat\b/ + + 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, 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 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 + 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 + 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$/ + data> 25jun04\P + 0: 25jun04 + 1: jun + data> 25dec3\P + Partial match: 23dec3 + data> 3ju\P + Partial match: 3ju + data> 3juj\P + No match + 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- + plete pattern, but the first two are partial matches. Similar output is + obtained 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() OR pcre[16|32]_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 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 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 + Partial match: 23ja + 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 + 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 the DFA + matching functions. + + +MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre[16|32]_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 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 + + Certain types of pattern may give problems with multi-segment matching, + whichever matching function is used. + + 1. If the pattern contains a test for the beginning of a line, you need + to pass the PCRE_NOTBOL option when the subject string for any call + does start at the beginning of a line. There is also a PCRE_NOTEOL + option, but in practice when doing multi-segment matching you should be + using PCRE_PARTIAL_HARD, which includes the effect of PCRE_NOTEOL. + + 2. Lookbehind assertions that have already been obeyed are catered for + 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 + pcre[16|32]_fullinfo() functions to obtain the length of the largest + lookbehind in the pattern. This length is given in characters, not + bytes. If you always retain at least that many characters before the + partially matched string, all should be well. (Of course, near the + 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- + ble. Consider again this pcretest example: + + re> /dog(sbody)?/ + data> dogsb\P + 0: dog + data> do\P\D + Partial match: do + data> gsb\R\P\D + 0: g + data> dogsbody\D + 0: dogsbody + 1: dog + + 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- + ently: + + re> /dog(sbody)?/ + data> dogsb\P\P + Partial match: dogsb + data> do\P\D + Partial match: do + data> gsb\R\P\P\D + Partial match: gsb + + 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 + + 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 + such as: + + 1234|ABCD + + 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 + Partial match: 123 + data> 1237890 + 0: 3789 + + Of course, instead of using PCRE_DFA_RESTART, the same technique of re- + 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 + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 24 June 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREPRECOMPILE(3) PCREPRECOMPILE(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +SAVING AND RE-USING PRECOMPILED PCRE PATTERNS + + If you are running an application that uses a large number of regular + expression patterns, it may be useful to store them in a precompiled + 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. + 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. If the two hosts have different endianness + (byte order), you should run the pcre[16|32]_pat- + tern_to_host_byte_order() function on the new host before trying to + match the pattern. The matching functions return PCRE_ERROR_BADENDIAN- + NESS 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[16|32]_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|32]_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; + pcre *re; + + re = pcre_compile("my pattern", 0, &error, &erroroffset, NULL); + if (re == NULL) { ... handle errors ... } + rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); + if (rc < 0) { ... handle errors ... } + rc = fwrite(re, 1, size, fd); + if (rc != size) { ... handle errors ... } + + In this example, the bytes that comprise the compiled pattern are + copied exactly. Note that this is binary data that may contain any of + the 256 possible byte values. On systems that make a distinction + between binary and non-binary data, be sure that the file is opened for + binary output. + + If you want to write more than one pattern to a file, you will have to + devise a way of separating them. For binary data, preceding each pat- + tern with its length is probably the most straightforward approach. + Another possibility is to write out the data in hexadecimal instead of + binary, one pattern to a line. + + Saving compiled patterns in a file is only one possible way of storing + them for later use. They could equally well be saved in a database, or + 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 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|32]_study() returns a pointer to a pcre[16|32]_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|32]_extra + block itself). The length of the study data can be obtained by calling + pcre[16|32]_fullinfo() with an argument of PCRE_INFO_STUDYSIZE. Remem- + ber to check that pcre[16|32]_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, called pcre[16|32]_pattern_to_host_byte_order() if + necessary, you pass its pointer to pcre[16|32]_exec() or + pcre[16|32]_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[16|32]_compile()), + you must now pass a similar pointer to pcre[16|32]_exec() or + pcre[16|32]_dfa_exec(), because the value saved with the compiled pat- + tern will obviously be nonsense. A field in a pcre[16|32]_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 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[16|32]_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|32]_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 + + In general, it is safest to recompile all saved patterns when you + update to a new PCRE release, though not all updates actually require + this. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 24 June 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREPERFORM(3) PCREPERFORM(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +PCRE PERFORMANCE + + Two aspects of performance are discussed below: memory usage and pro- + cessing time. The way you express your pattern as a regular expression + can affect both of them. + + +COMPILED PATTERN MEMORY USAGE + + 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} + + is compiled as if it were + + (abc|def)(abc|def)((abc|def)(abc|def)?)? + + (Technical aside: It is done this way so that backtrack points within + each of the repetitions can be independently maintained.) + + For regular expressions whose quantifiers use only small numbers, this + is not usually a problem. However, if the numbers are large, and par- + ticularly if such repetitions are nested, the memory usage can become + an embarrassment. For example, the very simple pattern + + ((ab){1,1000}c){1,3} + + 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 + 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 + otherwise handle. + + +STACK USAGE AT RUN TIME + + When pcre_exec() or pcre[16|32]_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- + 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 + 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 + observations about PCRE. + + Using Unicode character properties (the \p, \P, and \X escapes) is + slow, because PCRE has to use a multi-stage table lookup 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, + 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 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 + is set, the pattern is implicitly anchored by PCRE, since it can match + only at the start of a subject string. However, if PCRE_DOTALL is not + set, PCRE cannot make this optimization, because the . metacharacter + does not then match a newline, and if the subject string contains new- + lines, the pattern may match from the character immediately following + one of them instead of from the very start. For example, the pattern + + .*second + + matches the subject "first\nand second" (where \n stands for a newline + character), with the match starting at the seventh character. In order + to do this, PCRE has to retry the match starting after every newline in + the subject. + + If you are using such a pattern with subject strings that do not con- + tain newlines, the best performance is obtained by setting PCRE_DOTALL, + or starting the pattern with ^.* or ^.*? to indicate explicit anchor- + ing. That saves PCRE from having to scan along the subject looking for + a newline to restart at. + + Beware of patterns that contain nested indefinite repeats. These can + take a long time to run when applied to a string that does not match. + Consider the pattern fragment + + ^(a+)* + + This can match "aaaa" in 16 different ways, and this number increases + very rapidly as the string gets longer. (The * repeat can match 0, 1, + 2, 3, or 4 times, and for each of those cases other than 0 or 4, the + + repeats can match different numbers of times.) When the remainder of + the pattern is such that the entire match is going to fail, PCRE has in + principle to try every possible variation, and this can take an + extremely long time, even for relatively short strings. + + An optimization catches some of the more simple cases such as + + (a+)*b + + where a literal character follows. Before embarking on the standard + matching procedure, PCRE checks that there is a "b" later in the sub- + ject string, and if there is not, it fails the match immediately. How- + ever, when there is no following literal this optimization cannot be + used. You can see the difference by comparing the behaviour of + + (a+)*\d + + with the pattern above. The former gives a failure almost instantly + when applied to a whole line of "a" characters, whereas the latter + takes an appreciable time with strings longer than about 20 characters. + + In many cases, the solution to this kind of performance issue is to use + an atomic group or a possessive quantifier. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 25 August 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREPOSIX(3) PCREPOSIX(3) + + +NAME + PCRE - Perl-compatible regular expressions. + + +SYNOPSIS OF POSIX API + + #include + + int regcomp(regex_t *preg, const char *pattern, + int cflags); + + int regexec(regex_t *preg, const char *string, + size_t nmatch, regmatch_t pmatch[], int eflags); + + size_t regerror(int errcode, const regex_t *preg, + char *errbuf, size_t errbuf_size); + + void regfree(regex_t *preg); + + +DESCRIPTION + + 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 and 32-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 + 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 + are not even defined. + + 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 + 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 + 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 + 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 compiled regular expression. + + The argument cflags is either zero, or contains one or more of the bits + defined by the following macros: + + REG_DOTALL + + The PCRE_DOTALL option is set when the regular expression is passed for + compilation to the native function. Note that REG_DOTALL is not part of + the POSIX standard. + + REG_ICASE + + 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- + tion). + + REG_NOSUB + + 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 + 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 + 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 + 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. + 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 + by a negative class such as [^a] (they are). + + 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 + 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 + 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. + + +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 + PCRE: + + Default Change with + + . matches newline no PCRE_DOTALL + newline matches [^a] yes not changeable + $ matches \n at end yes PCRE_DOLLARENDONLY + $ matches \n in middle no PCRE_MULTILINE + ^ matches \n in middle no PCRE_MULTILINE + + This is the equivalent table for POSIX: + + Default Change with + + . matches newline yes REG_NEWLINE + newline matches [^a] yes REG_NEWLINE + $ matches \n at end no REG_NEWLINE + $ matches \n in middle no REG_NEWLINE + ^ 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 + 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 + 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 + can be: + + REG_NOTBOL + + The PCRE_NOTBOL option is set when calling the underlying PCRE matching + function. + + REG_NOTEMPTY + + The PCRE_NOTEMPTY option is set when calling the underlying PCRE match- + ing function. Note that REG_NOTEMPTY is not part of the POSIX standard. + However, setting this option can give more POSIX-like behaviour in some + situations. + + REG_NOTEOL + + The PCRE_NOTEOL option is set when calling the underlying PCRE matching + function. + + 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 + 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 + regexec() are ignored. + + If the value of nmatch is zero, or if the value pmatch is NULL, no data + about any matched strings is returned. + + 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 + 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" + 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 + 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- + 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- + sion. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 09 January 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCRECPP(3) PCRECPP(3) + + +NAME + PCRE - Perl-compatible regular expressions. + + +SYNOPSIS OF C++ WRAPPER + + #include + + +DESCRIPTION + + The C++ wrapper for PCRE was provided by Google Inc. Some additional + functionality was added by Giuseppe Maxia. This brief man page was con- + structed from the notes in the pcrecpp.h file, which should be con- + sulted for further details. Note that the C++ wrapper supports only the + original 8-bit PCRE library. There is no 16-bit or 32-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 + sub-strings that match sub-patterns into them. + + Example: successful match + pcrecpp::RE re("h.*o"); + re.FullMatch("hello"); + + Example: unsuccessful match (requires full match): + pcrecpp::RE re("e"); + !re.FullMatch("hello"); + + 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. + Either could correctly be used for any of these examples. + + You must supply extra pointer arguments to extract matched subpieces. + + Example: extracts "ruby" into "s" and 1234 into "i" + int i; + string s; + pcrecpp::RE re("(\\w+):(\\d+)"); + re.FullMatch("ruby:1234", &s, &i); + + Example: does not try to extract any extra sub-patterns + re.FullMatch("ruby:1234", &s); + + Example: does not try to extract into NULL + re.FullMatch("ruby:1234", NULL, &i); + + Example: integer overflow causes failure + !re.FullMatch("ruby:1234567891234", NULL, &i); + + Example: fails because there aren't enough sub-patterns: + !pcrecpp::RE("\\w+:\\d+").FullMatch("ruby:1234", &s); + + 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 + type, or one of: + + string (matched piece is copied to string) + StringPiece (StringPiece is mutated to point to matched piece) + 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- + isfied: + + a. "text" matches "pattern" exactly; + + b. The number of matched sub-patterns is >= number of supplied + pointers; + + c. The "i"th argument has a suitable type for holding the + string captured as the "i"th sub-pattern. If you pass in + void * NULL for the "i"th argument, or a non-void * NULL + of the correct type, or pass fewer arguments than the + 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 + 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 + 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 + 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, + 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 + "1\.5\-2\.0\?". + + +PARTIAL MATCHES + + You can use the "PartialMatch" operation when you want the pattern to + match any substring of the text. + + Example: simple search for a string: + pcrecpp::RE("ell").PartialMatch("hello"); + + Example: find first number in a string: + int number; + pcrecpp::RE re("(\\d+)"); + re.PartialMatch("x*100 + 20", &number); + assert(number == 100); + + +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 + 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 + of a multi-byte character. + + Example: + pcrecpp::RE_Options options; + options.set_utf8(); + pcrecpp::RE re(utf8_pattern, options); + re.FullMatch(utf8_string); + + Example: using the convenience function UTF8(): + pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8()); + re.FullMatch(utf8_string); + + NOTE: The UTF8 flag is ignored if pcre was not configured with the + --enable-utf8 flag. + + +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- + rently, the following modifiers are supported: + + modifier description Perl corresponding + + PCRE_CASELESS case insensitive match /i + PCRE_MULTILINE multiple lines match /m + 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 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- + ture, while (ab|cd) does. + + 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 + instance, PCRE_CASELESS is handled by + + bool caseless() + + which returns true if the modifier is set, and + + 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 + 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 + RE_Options object, set the appropriate options, and pass this object to + a RE constructor. Example: + + 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 + programs. This lets you do + + RE(pattern, + RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); + + However, new code is better off doing + + RE(pattern, + RE_Options().set_caseless(true).set_multiline(true)) + .PartialMatch(str); + + 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(), + 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 + statement, you may write: + + RE(" ^ xyz \\s+ .* blah$", + RE_Options() + .set_caseless(true) + .set_extended(true) + .set_multiline(true)).PartialMatch(sometext); + + +SCANNING TEXT INCREMENTALLY + + 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 + pcrecpp namespace. + + Example: read lines of the form "var = value" from a string. + string contents = ...; // Fill string somehow + pcrecpp::StringPiece input(contents); // Wrap in a StringPiece + + string var; + int value; + pcrecpp::RE re("(\\w+) = (\\d+)\n"); + while (re.Consume(&input, &var, &value)) { + ...; + } + + 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 + could extract all words from a string by repeatedly calling + + pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word) + + +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 + 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 + base-10. + + Example: + int a, b, c, d; + pcrecpp::RE re("(.*) (.*) (.*) (.*)"); + re.FullMatch("100 40 0100 0x40", + pcrecpp::Octal(&a), pcrecpp::Hex(&b), + pcrecpp::CRadix(&c), pcrecpp::CRadix(&d)); + + will leave 64 in a, b, c, and d. + + +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- + 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 + 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 + 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 + 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 + occurred and the extraction happened successfully; if no match occurs, + the string is left unaffected. + + +AUTHOR + + The C++ wrapper was contributed by Google Inc. + Copyright (c) 2007 Google Inc. + + +REVISION + + Last updated: 08 January 2012 +------------------------------------------------------------------------------ + + +PCRESAMPLE(3) PCRESAMPLE(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +PCRE SAMPLE PROGRAM + + A simple, complete demonstration program, to get you started with using + PCRE, is supplied in the file pcredemo.c in the PCRE distribution. A + listing of this program is given in the pcredemo documentation. If you + do not have a copy of the PCRE distribution, you can save this listing + to re-create pcredemo.c. + + 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 + is going on. + + 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 + 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 + 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- + 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 + 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 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 + systems (e.g. Solaris): + + 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- + tems. You need to add + + -R/usr/local/lib + + (for example) to the compile command to get round this problem. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + 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, 32-bit units for the 32-bit + library, and 32-bit units for the 32-bit library) if PCRE is compiled + with the default internal linkage size of 2 bytes. If you want to + process regular expressions that are truly enormous, you can compile + PCRE with an internal linkage size of 3 or 4 (when building the 16-bit + or 32-bit library, 3 is rounded up to 4). See the README file in the + source distribution and the pcrebuild documentation for details. In + these cases the limit is substantially larger. However, the speed of + 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 and + 32-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) + + +NAME + PCRE - Perl-compatible regular expressions + + +PCRE DISCUSSION OF STACK USAGE + + When you call pcre[16|32]_exec(), it makes use of an internal function + 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 + different numbers of a's. Furthermore, in a number of cases where the + result of the recursive call would immediately be passed back as the + result of the current call (a "tail recursion"), the function is just + restarted instead. + + The above comments apply when pcre[16|32]_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|32]_exec() were not incompati- + ble, 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|32]_dfa_exec() function operates in an entirely different + way, and uses recursion only when there is a regular expression recur- + sion or subroutine call in the pattern. This includes the processing of + assertion and "once-only" subpatterns, which are handled like subrou- + tine calls. Normally, these are never very deep, and the limit on the + complexity of pcre[16|32]_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|32]_dfa_exec() to run out of stack. At present, there is no + protection against this. + + The comments that follow do NOT apply to pcre[16|32]_dfa_exec(); they + are relevant only for pcre[16|32]_exec() without the JIT optimization. + + Reducing pcre[16|32]_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 + large amounts of stack may be needed, despite the recognition of "tail + recursion". You can often reduce the amount of recursion, and there- + fore the amount of stack used, by modifying the pattern that is being + matched. Consider, for example, this pattern: + + ([^<]|<(?!inet))+ + + It matches from wherever it starts until it encounters " +. +. +.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 all 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 "unsigned 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 \fBpcre32_config()\fP, or if the +PCRE_CONFIG_UTF8 or PCRE_CONFIG_UTF32 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 Non-character +. +. +.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 both the 8-bit and the 32-bit libraries were 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, +16-bit and 32-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: 08 November 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcre32.3 b/tools/pcre/doc/pcre32.3 new file mode 100644 index 00000000..48205ca0 --- /dev/null +++ b/tools/pcre/doc/pcre32.3 @@ -0,0 +1,389 @@ +.TH PCRE 3 "08 November 2012" "PCRE 8.32" +.SH NAME +PCRE - Perl-compatible regular expressions +.sp +.B #include +. +. +.SH "PCRE 32-BIT API BASIC FUNCTIONS" +.rs +.sp +.SM +.B pcre32 *pcre32_compile(PCRE_SPTR32 \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 pcre32 *pcre32_compile2(PCRE_SPTR32 \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 pcre32_extra *pcre32_study(const pcre32 *\fIcode\fP, int \fIoptions\fP, +.ti +5n +.B const char **\fIerrptr\fP); +.PP +.B void pcre32_free_study(pcre32_extra *\fIextra\fP); +.PP +.B int pcre32_exec(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," +.ti +5n +.B "PCRE_SPTR32 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); +.PP +.B int pcre32_dfa_exec(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," +.ti +5n +.B "PCRE_SPTR32 \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 32-BIT API STRING EXTRACTION FUNCTIONS" +.rs +.sp +.B int pcre32_copy_named_substring(const pcre32 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP, +.ti +5n +.B PCRE_UCHAR32 *\fIbuffer\fP, int \fIbuffersize\fP); +.PP +.B int pcre32_copy_substring(PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR32 *\fIbuffer\fP, +.ti +5n +.B int \fIbuffersize\fP); +.PP +.B int pcre32_get_named_substring(const pcre32 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP, +.ti +5n +.B PCRE_SPTR32 *\fIstringptr\fP); +.PP +.B int pcre32_get_stringnumber(const pcre32 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR32 \fIname\fP); +.PP +.B int pcre32_get_stringtable_entries(const pcre32 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR32 \fIname\fP, PCRE_UCHAR32 **\fIfirst\fP, PCRE_UCHAR32 **\fIlast\fP); +.PP +.B int pcre32_get_substring(PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, +.ti +5n +.B PCRE_SPTR32 *\fIstringptr\fP); +.PP +.B int pcre32_get_substring_list(PCRE_SPTR32 \fIsubject\fP, +.ti +5n +.B int *\fIovector\fP, int \fIstringcount\fP, "PCRE_SPTR32 **\fIlistptr\fP);" +.PP +.B void pcre32_free_substring(PCRE_SPTR32 \fIstringptr\fP); +.PP +.B void pcre32_free_substring_list(PCRE_SPTR32 *\fIstringptr\fP); +. +. +.SH "PCRE 32-BIT API AUXILIARY FUNCTIONS" +.rs +.sp +.B pcre32_jit_stack *pcre32_jit_stack_alloc(int \fIstartsize\fP, int \fImaxsize\fP); +.PP +.B void pcre32_jit_stack_free(pcre32_jit_stack *\fIstack\fP); +.PP +.B void pcre32_assign_jit_stack(pcre32_extra *\fIextra\fP, +.ti +5n +.B pcre32_jit_callback \fIcallback\fP, void *\fIdata\fP); +.PP +.B const unsigned char *pcre32_maketables(void); +.PP +.B int pcre32_fullinfo(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," +.ti +5n +.B int \fIwhat\fP, void *\fIwhere\fP); +.PP +.B int pcre32_refcount(pcre32 *\fIcode\fP, int \fIadjust\fP); +.PP +.B int pcre32_config(int \fIwhat\fP, void *\fIwhere\fP); +.PP +.B const char *pcre32_version(void); +.PP +.B int pcre32_pattern_to_host_byte_order(pcre32 *\fIcode\fP, +.ti +5n +.B pcre32_extra *\fIextra\fP, const unsigned char *\fItables\fP); +. +. +.SH "PCRE 32-BIT API INDIRECTED FUNCTIONS" +.rs +.sp +.B void *(*pcre32_malloc)(size_t); +.PP +.B void (*pcre32_free)(void *); +.PP +.B void *(*pcre32_stack_malloc)(size_t); +.PP +.B void (*pcre32_stack_free)(void *); +.PP +.B int (*pcre32_callout)(pcre32_callout_block *); +. +. +.SH "PCRE 32-BIT API 32-BIT-ONLY FUNCTION" +.rs +.sp +.B int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *\fIoutput\fP, +.ti +5n +.B PCRE_SPTR32 \fIinput\fP, int \fIlength\fP, int *\fIbyte_order\fP, +.ti +5n +.B int \fIkeep_boms\fP); +. +. +.SH "THE PCRE 32-BIT LIBRARY" +.rs +.sp +Starting with release 8.32, it is possible to compile a PCRE library that +supports 32-bit character strings, including UTF-32 strings, as well as or +instead of the original 8-bit library. This work was done by Christian Persch, +based on the work done by Zoltan Herczeg for the 16-bit library. All three +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 and 32-bit libraries. This page +describes what is different when you use the 32-bit library. +.P +WARNING: A single application can be linked with all or any of the three +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 \fBpcre32_compile()\fP, you must do so +with \fBpcre32_study()\fP, not \fBpcre_study()\fP, and you must free the +study data with \fBpcre32_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 all libraries, as well as definitions of flags, structures, error +codes, etc. +. +. +.SH "THE LIBRARY NAME" +.rs +.sp +In Unix-like systems, the 32-bit library is called \fBlibpcre32\fP, and can +normally be accesss by adding \fB-lpcre32\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 32-bit library, strings are passed as +vectors of unsigned 32-bit quantities. The macro PCRE_UCHAR32 specifies an +appropriate data type, and PCRE_SPTR32 is defined as "const PCRE_UCHAR32 *". In +very many environments, "unsigned int" is a 32-bit data type. When PCRE is +built, it defines PCRE_UCHAR32 as "unsigned int", but checks that it really is +a 32-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 32-bit patterns +and JIT stacks are \fBpcre32\fP and \fBpcre32_jit_stack\fP respectively. The +type of the user-accessible structure that is returned by \fBpcre32_study()\fP +is \fBpcre32_extra\fP, and the type of the structure that is used for passing +data to a callout function is \fBpcre32_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 32-bit instead of +8-bit types. +. +. +.SH "32-BIT FUNCTIONS" +.rs +.sp +For every function in the 8-bit library there is a corresponding function in +the 32-bit library with a name that starts with \fBpcre32_\fP instead of +\fBpcre_\fP. The prototypes are listed above. In addition, there is one extra +function, \fBpcre32_utf32_to_host_byte_order()\fP. This is a utility function +that converts a UTF-32 character string to host byte order if necessary. The +other 32-bit functions expect the strings they are passed to be in host byte +order. +.P +The \fIinput\fP and \fIoutput\fP arguments of +\fBpcre32_utf32_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 32-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 32-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 32-bit units rather than bytes. +. +. +.SH "NAMED SUBPATTERNS" +.rs +.sp +The name-to-number translation table that is maintained for named subpatterns +uses 32-bit characters. The \fBpcre32_get_stringtable_entries()\fP function +returns the length of each entry in the table as the number of 32-bit data +units. +. +. +.SH "OPTION NAMES" +.rs +.sp +There are two new general option names, PCRE_UTF32 and PCRE_NO_UTF32_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-32 strings +.\" +in the +.\" HREF +\fBpcreunicode\fP +.\" +page. +.P +For the \fBpcre32_config()\fP function there is an option PCRE_CONFIG_UTF32 +that returns 1 if UTF-32 support is configured, otherwise 0. If this option is +given to \fBpcre_config()\fP or \fBpcre16_config()\fP, or if the +PCRE_CONFIG_UTF8 or PCRE_CONFIG_UTF16 option is given to \fBpcre32_config()\fP, +the result is the PCRE_ERROR_BADOPTION error. +. +. +.SH "CHARACTER CODES" +.rs +.sp +In 32-bit mode, when PCRE_UTF32 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 0x7fffffff 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-32 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 ill-formed in UTF-32. +.P +A UTF-32 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 +\fBpcre32_utf32_to_host_byte_order()\fP is provided to help with this (see +above). +. +. +.SH "ERROR NAMES" +.rs +.sp +The error PCRE_ERROR_BADUTF32 corresponds to its 8-bit counterpart. +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 +\fBpcre32_exec()\fP. +.P +There are new error codes whose names begin with PCRE_UTF32_ERR for invalid +UTF-32 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-32 errors are: +.sp + PCRE_UTF32_ERR1 Surrogate character (range from 0xd800 to 0xdfff) + PCRE_UTF32_ERR2 Non-character + PCRE_UTF32_ERR3 Character > 0x10ffff +. +. +.SH "ERROR TEXTS" +.rs +.sp +If there is an error while compiling a pattern, the error text that is passed +back by \fBpcre32_compile()\fP or \fBpcre32_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 32-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 32-bit library. If it is run with the +command line option \fB-32\fP, patterns and subject strings are converted from +8-bit to 32-bit before being passed to PCRE, and the 32-bit library functions +are used instead of the 8-bit ones. Returned 32-bit strings are converted to +8-bit for output. If both the 8-bit and the 16-bit libraries were not compiled, +\fBpcretest\fP defaults to 32-bit and the \fB-32\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, +16-bit and 32-bit libraries has been built, and runs the tests appropriately. +. +. +.SH "NOT SUPPORTED IN 32-BIT MODE" +.rs +.sp +Not all the features of the 8-bit library are available with the 32-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: 08 November 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcre_assign_jit_stack.3 b/tools/pcre/doc/pcre_assign_jit_stack.3 new file mode 100644 index 00000000..e1563b6e --- /dev/null +++ b/tools/pcre/doc/pcre_assign_jit_stack.3 @@ -0,0 +1,61 @@ +.TH PCRE_ASSIGN_JIT_STACK 3 "24 June 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); +.PP +.B void pcre32_assign_jit_stack(pcre32_extra *\fIextra\fP, +.ti +5n +.B pcre32_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|32]_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|32]_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|32]_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|32]_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 --git a/tools/pcre/doc/pcre_compile.3 b/tools/pcre/doc/pcre_compile.3 new file mode 100644 index 00000000..d09768d8 --- /dev/null +++ b/tools/pcre/doc/pcre_compile.3 @@ -0,0 +1,98 @@ +.TH PCRE_COMPILE 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B pcre *pcre_compile(const char *\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_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 pcre32 *pcre32_compile(PCRE_SPTR32 \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[16|32]_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 + \fIoptions\fP Zero or more option bits + \fIerrptr\fP Where to put an error message + \fIerroffset\fP Offset in pattern where error was found + \fItableptr\fP Pointer to character tables, or NULL to + use the built-in default +.sp +The option bits are: +.sp + PCRE_ANCHORED Force pattern anchoring + PCRE_AUTO_CALLOUT Compile automatic callouts + PCRE_BSR_ANYCRLF \eR matches only CR, LF, or CRLF + PCRE_BSR_UNICODE \eR matches all Unicode line endings + PCRE_CASELESS Do caseless matching + 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 white space and # comments + PCRE_EXTRA PCRE extra features + (not much use currently) + PCRE_FIRSTLINE Force matching to be before newline + PCRE_JAVASCRIPT_COMPAT JavaScript compatibility + PCRE_MULTILINE ^ and $ match newlines within data + PCRE_NEWLINE_ANY Recognize any Unicode newline sequence + PCRE_NEWLINE_ANYCRLF Recognize CR, LF, and CRLF as newline + sequences + PCRE_NEWLINE_CR Set CR as the newline sequence + PCRE_NEWLINE_CRLF Set CRLF as the newline sequence + 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_UTF32_CHECK Do not check the pattern for UTF-32 + validity (only relevant if + PCRE_UTF32 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_UTF16 Run in \fBpcre16_compile()\fP UTF-16 mode + PCRE_UTF32 Run in \fBpcre32_compile()\fP UTF-32 mode + PCRE_UTF8 Run in \fBpcre_compile()\fP UTF-8 mode +.sp +PCRE must be built with UTF support in order to use PCRE_UTF8/16/32 and +PCRE_NO_UTF8/16/32_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 +compiling regular expressions with one version of PCRE for use with a different +version is not guaranteed to work and may cause crashes. +.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 --git a/tools/pcre/doc/pcre_compile2.3 b/tools/pcre/doc/pcre_compile2.3 new file mode 100644 index 00000000..1fcae433 --- /dev/null +++ b/tools/pcre/doc/pcre_compile2.3 @@ -0,0 +1,106 @@ +.TH PCRE_COMPILE2 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B pcre *pcre_compile2(const char *\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 *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 pcre32 *pcre32_compile2(PCRE_SPTR32 \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[16|32]_compile()\fP, except for the addition of the +\fIerrorcodeptr\fP argument. The arguments are: +. +.sp + \fIpattern\fP A zero-terminated string containing the + regular expression to be compiled + \fIoptions\fP Zero or more option bits + \fIerrorcodeptr\fP Where to put an error code + \fIerrptr\fP Where to put an error message + \fIerroffset\fP Offset in pattern where error was found + \fItableptr\fP Pointer to character tables, or NULL to + use the built-in default +.sp +The option bits are: +.sp + PCRE_ANCHORED Force pattern anchoring + PCRE_AUTO_CALLOUT Compile automatic callouts + PCRE_BSR_ANYCRLF \eR matches only CR, LF, or CRLF + PCRE_BSR_UNICODE \eR matches all Unicode line endings + PCRE_CASELESS Do caseless matching + 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 white space and # comments + PCRE_EXTRA PCRE extra features + (not much use currently) + PCRE_FIRSTLINE Force matching to be before newline + PCRE_JAVASCRIPT_COMPAT JavaScript compatibility + PCRE_MULTILINE ^ and $ match newlines within data + PCRE_NEWLINE_ANY Recognize any Unicode newline sequence + PCRE_NEWLINE_ANYCRLF Recognize CR, LF, and CRLF as newline + sequences + PCRE_NEWLINE_CR Set CR as the newline sequence + PCRE_NEWLINE_CRLF Set CRLF as the newline sequence + 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_UTF32_CHECK Do not check the pattern for UTF-32 + validity (only relevant if + PCRE_UTF32 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_UTF16 Run \fBpcre16_compile()\fP in UTF-16 mode + PCRE_UTF32 Run \fBpcre32_compile()\fP in UTF-32 mode + PCRE_UTF8 Run \fBpcre_compile()\fP in UTF-8 mode +.sp +PCRE must be built with UTF support in order to use PCRE_UTF8/16/32 and +PCRE_NO_UTF8/16/32_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 +compiling regular expressions with one version of PCRE for use with a different +version is not guaranteed to work and may cause crashes. +.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 --git a/tools/pcre/doc/pcre_config.3 b/tools/pcre/doc/pcre_config.3 new file mode 100644 index 00000000..5a6e6be7 --- /dev/null +++ b/tools/pcre/doc/pcre_config.3 @@ -0,0 +1,76 @@ +.TH PCRE_CONFIG 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre_config(int \fIwhat\fP, void *\fIwhere\fP); +.PP +.B int pcre16_config(int \fIwhat\fP, void *\fIwhere\fP); +.PP +.B int pcre32_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. 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 \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 + Internal recursion depth limit + PCRE_CONFIG_NEWLINE Value of the default newline sequence: + 13 (0x000d) for CR + 10 (0x000a) for LF + 3338 (0x0d0a) for CRLF + -2 for ANYCRLF + -1 for ANY + PCRE_CONFIG_BSR Indicates what \eR matches by default: + 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 + PCRE_CONFIG_STACKRECURSE Recursion implementation (1=stack 0=heap) + PCRE_CONFIG_UTF16 Availability of UTF-16 support (1=yes + 0=no); option for \fBpcre16_config()\fP + PCRE_CONFIG_UTF32 Availability of UTF-32 support (1=yes + 0=no); option for \fBpcre32_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. That error +is also given if PCRE_CONFIG_UTF16 or PCRE_CONFIG_UTF32 is passed to +\fBpcre_config()\fP, if PCRE_CONFIG_UTF8 or PCRE_CONFIG_UTF32 is passed to +\fBpcre16_config()\fP, or if PCRE_CONFIG_UTF8 or PCRE_CONFIG_UTF16 is passed to +\fBpcre32_config()\fP. +.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 --git a/tools/pcre/doc/pcre_copy_named_substring.3 b/tools/pcre/doc/pcre_copy_named_substring.3 new file mode 100644 index 00000000..e3281d8f --- /dev/null +++ b/tools/pcre/doc/pcre_copy_named_substring.3 @@ -0,0 +1,59 @@ +.TH PCRE_COPY_NAMED_SUBSTRING 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre_copy_named_substring(const pcre *\fIcode\fP, +.ti +5n +.B const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.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); +.PP +.B int pcre32_copy_named_substring(const pcre32 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP, +.ti +5n +.B PCRE_UCHAR32 *\fIbuffer\fP, int \fIbuffersize\fP); +. +.SH DESCRIPTION +.rs +.sp +This is a convenience function for extracting a captured substring, identified +by name, into a given buffer. The arguments are: +.sp + \fIcode\fP Pattern that was successfully matched + \fIsubject\fP Subject that has been successfully matched + \fIovector\fP Offset vector that \fBpcre[16|32]_exec()\fP used + \fIstringcount\fP Value returned by \fBpcre[16|32]_exec()\fP + \fIstringname\fP Name of the required substring + \fIbuffer\fP Buffer to receive the string + \fIbuffersize\fP Size of buffer +.sp +The yield is the length of the substring, PCRE_ERROR_NOMEMORY if the buffer was +too small, or PCRE_ERROR_NOSUBSTRING if the string name is invalid. +.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 --git a/tools/pcre/doc/pcre_copy_substring.3 b/tools/pcre/doc/pcre_copy_substring.3 new file mode 100644 index 00000000..96bff3a2 --- /dev/null +++ b/tools/pcre/doc/pcre_copy_substring.3 @@ -0,0 +1,52 @@ +.TH PCRE_COPY_SUBSTRING 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre_copy_substring(const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.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); +.PP +.B int pcre32_copy_substring(PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR32 *\fIbuffer\fP, +.ti +5n +.B int \fIbuffersize\fP); +. +.SH DESCRIPTION +.rs +.sp +This is a convenience function for extracting a captured substring into a given +buffer. The arguments are: +.sp + \fIsubject\fP Subject that has been successfully matched + \fIovector\fP Offset vector that \fBpcre[16|32]_exec()\fP used + \fIstringcount\fP Value returned by \fBpcre[16|32]_exec()\fP + \fIstringnumber\fP Number of the required substring + \fIbuffer\fP Buffer to receive the string + \fIbuffersize\fP Size of buffer +.sp +The yield is the length of the string, PCRE_ERROR_NOMEMORY if the buffer was +too small, or PCRE_ERROR_NOSUBSTRING if the string number is invalid. +.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 --git a/tools/pcre/doc/pcre_dfa_exec.3 b/tools/pcre/doc/pcre_dfa_exec.3 new file mode 100644 index 00000000..d1901a5e --- /dev/null +++ b/tools/pcre/doc/pcre_dfa_exec.3 @@ -0,0 +1,125 @@ +.TH PCRE_DFA_EXEC 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre_dfa_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," +.ti +5n +.B "const char *\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); +.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); +.PP +.B int pcre32_dfa_exec(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," +.ti +5n +.B "PCRE_SPTR32 \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 +.sp +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[16|32]_exec()\fP. The arguments for this function +are: +.sp + \fIcode\fP Points to the compiled pattern + \fIextra\fP Points to an associated \fBpcre[16|32]_extra\fP structure, + or is NULL + \fIsubject\fP Points to the subject string + \fIlength\fP Length of the subject string, in bytes + \fIstartoffset\fP Offset in bytes in the subject at which to + start matching + \fIoptions\fP Option bits + \fIovector\fP Points to a vector of ints for result offsets + \fIovecsize\fP Number of elements in the vector + \fIworkspace\fP Points to a vector of ints used as working space + \fIwscount\fP Number of elements in the vector +.sp +The options are: +.sp + PCRE_ANCHORED Match only at the first position + PCRE_BSR_ANYCRLF \eR matches only CR, LF, or CRLF + PCRE_BSR_UNICODE \eR matches all Unicode line endings + PCRE_NEWLINE_ANY Recognize any Unicode newline sequence + PCRE_NEWLINE_ANYCRLF Recognize CR, LF, & CRLF as newline sequences + PCRE_NEWLINE_CR Recognize CR as the only newline sequence + PCRE_NEWLINE_CRLF Recognize CRLF as the only newline sequence + PCRE_NEWLINE_LF Recognize LF as the only newline sequence + PCRE_NOTBOL Subject is not the beginning of a line + PCRE_NOTEOL Subject is not the end of a line + PCRE_NOTEMPTY An empty string is not a valid match + 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_UTF32_CHECK Do not check the subject for UTF-32 + validity (only relevant if PCRE_UTF32 + 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) + PCRE_PARTIAL ) Return PCRE_ERROR_PARTIAL for a partial + PCRE_PARTIAL_SOFT ) match if no full matches are found + PCRE_PARTIAL_HARD Return PCRE_ERROR_PARTIAL for a partial match + even if there is a full match as well + PCRE_DFA_SHORTEST Return only the shortest match + PCRE_DFA_RESTART Restart after a partial match +.sp +There are restrictions on what may appear in a pattern when using this matching +function. Details are given in the +.\" HREF +\fBpcrematching\fP +.\" +documentation. For details of partial matching, see the +.\" HREF +\fBpcrepartial\fP +.\" +page. +.P +A \fBpcre[16|32]_extra\fP structure contains the following fields: +.sp + \fIflags\fP Bits indicating which fields are set + \fIstudy_data\fP Opaque data from \fBpcre[16|32]_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 + \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, +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 +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_exec.3 b/tools/pcre/doc/pcre_exec.3 new file mode 100644 index 00000000..78012edd --- /dev/null +++ b/tools/pcre/doc/pcre_exec.3 @@ -0,0 +1,103 @@ +.TH PCRE_EXEC 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.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, +.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); +.PP +.B int pcre32_exec(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," +.ti +5n +.B "PCRE_SPTR32 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); +. +.SH DESCRIPTION +.rs +.sp +This function matches a compiled regular expression against a given subject +string, using a matching algorithm that is similar to Perl's. It returns +offsets to captured substrings. Its arguments are: +.sp + \fIcode\fP Points to the compiled pattern + \fIextra\fP Points to an associated \fBpcre[16|32]_extra\fP structure, + or is NULL + \fIsubject\fP Points to the subject string + \fIlength\fP Length of the subject string, in bytes + \fIstartoffset\fP Offset in bytes in the subject at which to + start matching + \fIoptions\fP Option bits + \fIovector\fP Points to a vector of ints for result offsets + \fIovecsize\fP Number of elements in the vector (a multiple of 3) +.sp +The options are: +.sp + PCRE_ANCHORED Match only at the first position + PCRE_BSR_ANYCRLF \eR matches only CR, LF, or CRLF + PCRE_BSR_UNICODE \eR matches all Unicode line endings + PCRE_NEWLINE_ANY Recognize any Unicode newline sequence + PCRE_NEWLINE_ANYCRLF Recognize CR, LF, & CRLF as newline sequences + PCRE_NEWLINE_CR Recognize CR as the only newline sequence + PCRE_NEWLINE_CRLF Recognize CRLF as the only newline sequence + PCRE_NEWLINE_LF Recognize LF as the only newline sequence + PCRE_NOTBOL Subject string is not the beginning of a line + PCRE_NOTEOL Subject string is not the end of a line + PCRE_NOTEMPTY An empty string is not a valid match + 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_UTF32_CHECK Do not check the subject for UTF-32 + validity (only relevant if PCRE_UTF32 + 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) + PCRE_PARTIAL ) Return PCRE_ERROR_PARTIAL for a partial + PCRE_PARTIAL_SOFT ) match if no full matches are found + PCRE_PARTIAL_HARD Return PCRE_ERROR_PARTIAL for a partial match + if that is found before a full match +.sp +For details of partial matching, see the +.\" HREF +\fBpcrepartial\fP +.\" +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[16|32]_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 + \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, +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 +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_free_study.3 b/tools/pcre/doc/pcre_free_study.3 new file mode 100644 index 00000000..8826b735 --- /dev/null +++ b/tools/pcre/doc/pcre_free_study.3 @@ -0,0 +1,31 @@ +.TH PCRE_FREE_STUDY 3 "24 June 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); +.PP +.B void pcre32_free_study(pcre32_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|32]_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 --git a/tools/pcre/doc/pcre_free_substring.3 b/tools/pcre/doc/pcre_free_substring.3 new file mode 100644 index 00000000..88c04019 --- /dev/null +++ b/tools/pcre/doc/pcre_free_substring.3 @@ -0,0 +1,31 @@ +.TH PCRE_FREE_SUBSTRING 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B void pcre_free_substring(const char *\fIstringptr\fP); +.PP +.B void pcre16_free_substring(PCRE_SPTR16 \fIstringptr\fP); +.PP +.B void pcre32_free_substring(PCRE_SPTR32 \fIstringptr\fP); +. +.SH DESCRIPTION +.rs +.sp +This is a convenience function for freeing the store obtained by a previous +call to \fBpcre[16|32]_get_substring()\fP or \fBpcre[16|32]_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 +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_free_substring_list.3 b/tools/pcre/doc/pcre_free_substring_list.3 new file mode 100644 index 00000000..248b4bd0 --- /dev/null +++ b/tools/pcre/doc/pcre_free_substring_list.3 @@ -0,0 +1,31 @@ +.TH PCRE_FREE_SUBSTRING_LIST 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B void pcre_free_substring_list(const char **\fIstringptr\fP); +.PP +.B void pcre16_free_substring_list(PCRE_SPTR16 *\fIstringptr\fP); +.PP +.B void pcre32_free_substring_list(PCRE_SPTR32 *\fIstringptr\fP); +. +.SH DESCRIPTION +.rs +.sp +This is a convenience function for freeing the store obtained by a previous +call to \fBpcre[16|32]_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 +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_fullinfo.3 b/tools/pcre/doc/pcre_fullinfo.3 new file mode 100644 index 00000000..ad640fc6 --- /dev/null +++ b/tools/pcre/doc/pcre_fullinfo.3 @@ -0,0 +1,95 @@ +.TH PCRE_FULLINFO 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.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); +.PP +.B int pcre32_fullinfo(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," +.ti +5n +.B int \fIwhat\fP, void *\fIwhere\fP); +. +.SH DESCRIPTION +.rs +.sp +This function returns information about a compiled pattern. Its arguments are: +.sp + \fIcode\fP Compiled regular expression + \fIextra\fP Result of \fBpcre[16|32]_study()\fP or NULL + \fIwhat\fP What information is required + \fIwhere\fP Where to put the information +.sp +The following information is available: +.sp + 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 data unit for a match, or + -1 for start of string + or after newline, or + -2 otherwise + 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_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 + PCRE_INFO_NAMETABLE Pointer to name table + PCRE_INFO_OKPARTIAL Return 1 if partial matching can be tried + (always returns 1 after release 8.00) + PCRE_INFO_OPTIONS Option bits used for compilation + PCRE_INFO_SIZE Size of compiled pattern + PCRE_INFO_STUDYSIZE Size of study data + PCRE_INFO_FIRSTCHARACTER Fixed first data unit for a match + PCRE_INFO_FIRSTCHARACTERFLAGS Returns + 1 if there is a first data character set, which can + then be retrieved using PCRE_INFO_FIRSTCHARACTER, + 2 if the first character is at the start of the data + string or after a newline, and + 0 otherwise + PCRE_INFO_REQUIREDCHAR Literal last data unit required + PCRE_INFO_REQUIREDCHARFLAGS Returns 1 if the last data character is set (which can then + be retrieved using PCRE_INFO_REQUIREDCHAR); 0 otherwise +.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 PCRE_SPTR32 (32-bit library) + PCRE_INFO_NAMETABLE const unsigned char * (8-bit library) + PCRE_INFO_OPTIONS unsigned long int + PCRE_INFO_SIZE size_t + PCRE_INFO_FIRSTCHARACTER uint32_t + PCRE_INFO_REQUIREDCHAR uint32_t +.sp +The yield of the function is zero on success or: +.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 +.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 --git a/tools/pcre/doc/pcre_get_named_substring.3 b/tools/pcre/doc/pcre_get_named_substring.3 new file mode 100644 index 00000000..f81a243c --- /dev/null +++ b/tools/pcre/doc/pcre_get_named_substring.3 @@ -0,0 +1,62 @@ +.TH PCRE_GET_NAMED_SUBSTRING 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre_get_named_substring(const pcre *\fIcode\fP, +.ti +5n +.B const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.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); +.PP +.B int pcre32_get_named_substring(const pcre32 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP, +.ti +5n +.B PCRE_SPTR32 *\fIstringptr\fP); +. +.SH DESCRIPTION +.rs +.sp +This is a convenience function for extracting a captured substring by name. The +arguments are: +.sp + \fIcode\fP Compiled pattern + \fIsubject\fP Subject that has been successfully matched + \fIovector\fP Offset vector that \fBpcre[16|32]_exec()\fP used + \fIstringcount\fP Value returned by \fBpcre[16|32]_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[16|32]_malloc()\fP. The convenience function +\fBpcre[16|32]_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 +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_get_stringnumber.3 b/tools/pcre/doc/pcre_get_stringnumber.3 new file mode 100644 index 00000000..7def00ba --- /dev/null +++ b/tools/pcre/doc/pcre_get_stringnumber.3 @@ -0,0 +1,45 @@ +.TH PCRE_GET_STRINGNUMBER 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.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); +.PP +.B int pcre32_get_stringnumber(const pcre32 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR32 \fIname\fP); +. +.SH DESCRIPTION +.rs +.sp +This convenience function finds the number of a named substring capturing +parenthesis in a compiled pattern. Its arguments are: +.sp + \fIcode\fP Compiled regular expression + \fIname\fP Name whose number is required +.sp +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[16|32]_get_stringnumber()\fP. You can obtain the complete list by calling +\fBpcre[16|32]_get_stringtable_entries()\fP. +.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 --git a/tools/pcre/doc/pcre_get_stringtable_entries.3 b/tools/pcre/doc/pcre_get_stringtable_entries.3 new file mode 100644 index 00000000..39178165 --- /dev/null +++ b/tools/pcre/doc/pcre_get_stringtable_entries.3 @@ -0,0 +1,48 @@ +.TH PCRE_GET_STRINGTABLE_ENTRIES 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.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); +.PP +.B int pcre32_get_stringtable_entries(const pcre32 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR32 \fIname\fP, PCRE_UCHAR32 **\fIfirst\fP, PCRE_UCHAR32 **\fIlast\fP); +. +.SH DESCRIPTION +.rs +.sp +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[16|32]_get_stringnumber()\fP +instead. +.sp + \fIcode\fP Compiled regular expression + \fIname\fP Name whose entries required + \fIfirst\fP Where to return a pointer to the first entry + \fIlast\fP Where to return a pointer to the last entry +.sp +The yield of the function is the length of each entry, or +PCRE_ERROR_NOSUBSTRING if none are found. +.P +There is a complete description of the PCRE native API, including the format of +the table entries, in the +.\" HREF +\fBpcreapi\fP +.\" +page, and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_get_substring.3 b/tools/pcre/doc/pcre_get_substring.3 new file mode 100644 index 00000000..d5bc60c4 --- /dev/null +++ b/tools/pcre/doc/pcre_get_substring.3 @@ -0,0 +1,55 @@ +.TH PCRE_GET_SUBSTRING 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre_get_substring(const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.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); +.PP +.B int pcre32_get_substring(PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, +.ti +5n +.B PCRE_SPTR32 *\fIstringptr\fP); +. +.SH DESCRIPTION +.rs +.sp +This is a convenience function for extracting a captured substring. The +arguments are: +.sp + \fIsubject\fP Subject that has been successfully matched + \fIovector\fP Offset vector that \fBpcre[16|32]_exec()\fP used + \fIstringcount\fP Value returned by \fBpcre[16|32]_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[16|32]_malloc()\fP. The convenience function +\fBpcre[16|32]_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 +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_get_substring_list.3 b/tools/pcre/doc/pcre_get_substring_list.3 new file mode 100644 index 00000000..a1a57496 --- /dev/null +++ b/tools/pcre/doc/pcre_get_substring_list.3 @@ -0,0 +1,49 @@ +.TH PCRE_GET_SUBSTRING_LIST 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.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);" +.PP +.B int pcre32_get_substring_list(PCRE_SPTR32 \fIsubject\fP, +.ti +5n +.B int *\fIovector\fP, int \fIstringcount\fP, "PCRE_SPTR32 **\fIlistptr\fP);" +. +.SH DESCRIPTION +.rs +.sp +This is a convenience function for extracting a list of all the captured +substrings. The arguments are: +.sp + \fIsubject\fP Subject that has been successfully matched + \fIovector\fP Offset vector that \fBpcre[16|32]_exec\fP used + \fIstringcount\fP Value returned by \fBpcre[16|32]_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[16|32]_malloc()\fP. The convenience function +\fBpcre[16|32]_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 +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_jit_exec.3 b/tools/pcre/doc/pcre_jit_exec.3 new file mode 100644 index 00000000..8b9d05bf --- /dev/null +++ b/tools/pcre/doc/pcre_jit_exec.3 @@ -0,0 +1,104 @@ +.TH PCRE_EXEC 3 "31 October 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre_jit_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," +.ti +5n +.B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, +.ti +5n +.B pcre_jit_stack *\fIjstack\fP); +.PP +.B int pcre16_jit_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 pcre_jit_stack *\fIjstack\fP); +.PP +.B int pcre32_jit_exec(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," +.ti +5n +.B "PCRE_SPTR32 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, +.ti +5n +.B pcre_jit_stack *\fIjstack\fP); +. +.SH DESCRIPTION +.rs +.sp +This function matches a compiled regular expression that has been successfully +studied with one of the JIT options against a given subject string, using a +matching algorithm that is similar to Perl's. It is a "fast path" interface to +JIT, and it bypasses some of the sanity checks that \fBpcre_exec()\fP applies. +It returns offsets to captured substrings. Its arguments are: +.sp + \fIcode\fP Points to the compiled pattern + \fIextra\fP Points to an associated \fBpcre[16|32]_extra\fP structure, + or is NULL + \fIsubject\fP Points to the subject string + \fIlength\fP Length of the subject string, in bytes + \fIstartoffset\fP Offset in bytes in the subject at which to + start matching + \fIoptions\fP Option bits + \fIovector\fP Points to a vector of ints for result offsets + \fIovecsize\fP Number of elements in the vector (a multiple of 3) + \fIjstack\fP Pointer to a JIT stack +.sp +The allowed options are: +.sp + PCRE_NOTBOL Subject string is not the beginning of a line + PCRE_NOTEOL Subject string is not the end of a line + PCRE_NOTEMPTY An empty string is not a valid match + PCRE_NOTEMPTY_ATSTART An empty string at the start of the subject + is not a valid match + 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_UTF32_CHECK Do not check the subject for UTF-32 + validity (only relevant if PCRE_UTF32 + 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) + PCRE_PARTIAL ) Return PCRE_ERROR_PARTIAL for a partial + PCRE_PARTIAL_SOFT ) match if no full matches are found + PCRE_PARTIAL_HARD Return PCRE_ERROR_PARTIAL for a partial match + if that is found before a full match +.sp +However, the PCRE_NO_UTF[8|16|32]_CHECK options have no effect, as this check +is never applied. For details of partial matching, see the +.\" HREF +\fBpcrepartial\fP +.\" +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[16|32]_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 + \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, +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 +\fBpcreapi\fP +.\" +page and a description of the JIT API in the +.\" HREF +\fBpcrejit\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_jit_stack_alloc.3 b/tools/pcre/doc/pcre_jit_stack_alloc.3 new file mode 100644 index 00000000..5d2a1178 --- /dev/null +++ b/tools/pcre/doc/pcre_jit_stack_alloc.3 @@ -0,0 +1,45 @@ +.TH PCRE_JIT_STACK_ALLOC 3 "24 June 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); +.PP +.B pcre32_jit_stack *pcre32_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|32]_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|32]_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 --git a/tools/pcre/doc/pcre_jit_stack_free.3 b/tools/pcre/doc/pcre_jit_stack_free.3 new file mode 100644 index 00000000..494724e8 --- /dev/null +++ b/tools/pcre/doc/pcre_jit_stack_free.3 @@ -0,0 +1,35 @@ +.TH PCRE_JIT_STACK_FREE 3 "24 June 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); +.PP +.B void pcre32_jit_stack_free(pcre32_jit_stack *\fIstack\fP); +. +.SH DESCRIPTION +.rs +.sp +This function is used to free a JIT stack that was created by +\fBpcre[16|32]_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 --git a/tools/pcre/doc/pcre_maketables.3 b/tools/pcre/doc/pcre_maketables.3 new file mode 100644 index 00000000..b2c3d23a --- /dev/null +++ b/tools/pcre/doc/pcre_maketables.3 @@ -0,0 +1,33 @@ +.TH PCRE_MAKETABLES 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B const unsigned char *pcre_maketables(void); +.PP +.B const unsigned char *pcre16_maketables(void); +.PP +.B const unsigned char *pcre32_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[16|32]_compile()\fP to override PCRE's +internal, built-in tables (which were made by \fBpcre[16|32]_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 +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_pattern_to_host_byte_order.3 b/tools/pcre/doc/pcre_pattern_to_host_byte_order.3 new file mode 100644 index 00000000..4c306eef --- /dev/null +++ b/tools/pcre/doc/pcre_pattern_to_host_byte_order.3 @@ -0,0 +1,46 @@ +.TH PCRE_PATTERN_TO_HOST_BYTE_ORDER 3 "24 June 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); +.PP +.B int pcre32_pattern_to_host_byte_order(pcre32 *\fIcode\fP, +.ti +5n +.B pcre32_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|32]_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 --git a/tools/pcre/doc/pcre_refcount.3 b/tools/pcre/doc/pcre_refcount.3 new file mode 100644 index 00000000..45a41fef --- /dev/null +++ b/tools/pcre/doc/pcre_refcount.3 @@ -0,0 +1,36 @@ +.TH PCRE_REFCOUNT 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre_refcount(pcre *\fIcode\fP, int \fIadjust\fP); +.PP +.B int pcre16_refcount(pcre16 *\fIcode\fP, int \fIadjust\fP); +.PP +.B int pcre32_refcount(pcre32 *\fIcode\fP, int \fIadjust\fP); +. +.SH DESCRIPTION +.rs +.sp +This function is used to maintain a reference count inside a data block that +contains a compiled pattern. Its arguments are: +.sp + \fIcode\fP Compiled regular expression + \fIadjust\fP Adjustment to reference value +.sp +The yield of the function is the adjusted reference value, which is constrained +to lie between 0 and 65535. +.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 --git a/tools/pcre/doc/pcre_study.3 b/tools/pcre/doc/pcre_study.3 new file mode 100644 index 00000000..1f2b465a --- /dev/null +++ b/tools/pcre/doc/pcre_study.3 @@ -0,0 +1,56 @@ +.TH PCRE_STUDY 3 " 24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.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); +.PP +.B pcre32_extra *pcre32_study(const pcre32 *\fIcode\fP, int \fIoptions\fP, +.ti +5n +.B const char **\fIerrptr\fP); +. +.SH DESCRIPTION +.rs +.sp +This function studies a compiled pattern, to see if additional information can +be extracted that might speed up matching. Its arguments are: +.sp + \fIcode\fP A compiled regular expression + \fIoptions\fP Options for \fBpcre[16|32]_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[16|32]_exec()\fP or \fBpcre[16|32]_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 +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 +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcre_utf16_to_host_byte_order.3 b/tools/pcre/doc/pcre_utf16_to_host_byte_order.3 new file mode 100644 index 00000000..8f0d2d4e --- /dev/null +++ b/tools/pcre/doc/pcre_utf16_to_host_byte_order.3 @@ -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 --git a/tools/pcre/doc/pcre_utf32_to_host_byte_order.3 b/tools/pcre/doc/pcre_utf32_to_host_byte_order.3 new file mode 100644 index 00000000..fa4c1796 --- /dev/null +++ b/tools/pcre/doc/pcre_utf32_to_host_byte_order.3 @@ -0,0 +1,46 @@ +.TH PCRE_UTF32_TO_HOST_BYTE_ORDER 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *\fIoutput\fP, +.ti +5n +.B PCRE_SPTR32 \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 32-bit library, converts a UTF-32 +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 32-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 32-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 --git a/tools/pcre/doc/pcre_version.3 b/tools/pcre/doc/pcre_version.3 new file mode 100644 index 00000000..0f4973f9 --- /dev/null +++ b/tools/pcre/doc/pcre_version.3 @@ -0,0 +1,31 @@ +.TH PCRE_VERSION 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B const char *pcre_version(void); +.PP +.B const char *pcre16_version(void); +.PP +.B const char *pcre32_version(void); +. +.SH DESCRIPTION +.rs +.sp +This function (even in the 16-bit and 32-bit libraries) 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 +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff --git a/tools/pcre/doc/pcreapi.3 b/tools/pcre/doc/pcreapi.3 new file mode 100644 index 00000000..0eebf947 --- /dev/null +++ b/tools/pcre/doc/pcreapi.3 @@ -0,0 +1,2823 @@ +.TH PCREAPI 3 "08 November 2012" "PCRE 8.32" +.SH NAME +PCRE - Perl-compatible regular expressions +.sp +.B #include +. +. +.SH "PCRE NATIVE API BASIC FUNCTIONS" +.rs +.sp +.SM +.B pcre *pcre_compile(const char *\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 pcre *pcre_compile2(const char *\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 pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP, +.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, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); +.PP +.B int pcre_dfa_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," +.ti +5n +.B "const char *\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 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, +.ti +5n +.B int \fIstringcount\fP, const char *\fIstringname\fP, +.ti +5n +.B char *\fIbuffer\fP, int \fIbuffersize\fP); +.PP +.B int pcre_copy_substring(const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP, +.ti +5n +.B int \fIbuffersize\fP); +.PP +.B int pcre_get_named_substring(const pcre *\fIcode\fP, +.ti +5n +.B const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, const char *\fIstringname\fP, +.ti +5n +.B const char **\fIstringptr\fP); +.PP +.B int pcre_get_stringnumber(const pcre *\fIcode\fP, +.ti +5n +.B const char *\fIname\fP); +.PP +.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 pcre_get_substring(const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, +.ti +5n +.B const char **\fIstringptr\fP); +.PP +.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 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 int pcre_jit_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," +.ti +5n +.B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, +.ti +5n +.B pcre_jit_stack *\fIjstack\fP); +.PP +.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 +.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 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 *); +.PP +.B void *(*pcre_stack_malloc)(size_t); +.PP +.B void (*pcre_stack_free)(void *); +.PP +.B int (*pcre_callout)(pcre_callout_block *); +. +. +.SH "PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES" +.rs +.sp +As well as support for 8-bit character strings, PCRE also supports 16-bit +strings (from release 8.30) and 32-bit strings (from release 8.32), by means of +two additional libraries. They can be built as well as, or instead of, the +8-bit library. To avoid too much complication, this document describes the +8-bit versions of the functions, with only occasional references to the 16-bit +and 32-bit libraries. +.P +The 16-bit and 32-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 or \fBpcre32_\fP instead of +\fBpcre_\fP. For every option that has UTF8 in its name (for example, +PCRE_UTF8), there are corresponding 16-bit and 32-bit names with UTF8 replaced +by UTF16 or UTF32, respectively. This facility is in fact just cosmetic; the +16-bit and 32-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, or 32-bit data +quantities and UTF-32 when using the 32-bit library, unless specified +otherwise. More details of the specific differences for the 16-bit and 32-bit +libraries are given in the +.\" HREF +\fBpcre16\fP +.\" +and +.\" HREF +\fBpcre32\fP +.\" +pages. +. +. +.SH "PCRE API OVERVIEW" +.rs +.sp +PCRE has its own native API, which is described in this document. There are +also some wrapper functions (for the 8-bit library only) that 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 (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-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 +including \fBpcre.h\fP or \fBpcrecpp.h\fP, because otherwise the +\fBpcre_malloc()\fP and \fBpcre_free()\fP exported functions will be declared +\fB__declspec(dllimport)\fP, with unwanted results. +.P +The functions \fBpcre_compile()\fP, \fBpcre_compile2()\fP, \fBpcre_study()\fP, +and \fBpcre_exec()\fP are used for compiling and matching regular expressions +in a Perl-compatible manner. A sample program that demonstrates the simplest +way of using them is provided in the file called \fIpcredemo.c\fP in the PCRE +source distribution. A listing of this program is given in the +.\" HREF +\fBpcredemo\fP +.\" +documentation, and the +.\" HREF +\fBpcresample\fP +.\" +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. +.P +From release 8.32 there is also a direct interface for JIT execution, which +gives improved performance. The JIT-specific 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 +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 +.\" HREF +\fBpcrematching\fP +.\" +documentation. +.P +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 \fBpcre_exec()\fP. They are: +.sp + \fBpcre_copy_substring()\fP + \fBpcre_copy_named_substring()\fP + \fBpcre_get_substring()\fP + \fBpcre_get_named_substring()\fP + \fBpcre_get_substring_list()\fP + \fBpcre_get_stringnumber()\fP + \fBpcre_get_stringtable_entries()\fP +.sp +\fBpcre_free_substring()\fP and \fBpcre_free_substring_list()\fP are also +provided, to free the memory used for extracted strings. +.P +The function \fBpcre_maketables()\fP is used to build a set of character tables +in the current locale for passing to \fBpcre_compile()\fP, \fBpcre_exec()\fP, +or \fBpcre_dfa_exec()\fP. 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. +.P +The function \fBpcre_fullinfo()\fP is used to find out information about a +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 +object-oriented applications. +.P +The global variables \fBpcre_malloc\fP and \fBpcre_free\fP initially contain +the entry points of the standard \fBmalloc()\fP and \fBfree()\fP functions, +respectively. PCRE calls the memory management functions via these variables, +so a calling program can replace them if it wishes to intercept the calls. This +should be done before calling any PCRE functions. +.P +The global variables \fBpcre_stack_malloc\fP and \fBpcre_stack_free\fP 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 \fBpcre_exec()\fP function. See the +.\" HREF +\fBpcrebuild\fP +.\" +documentation for details of how to do this. It is a non-standard way of +building PCRE, for use in environments 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 +.\" HREF +\fBpcrestack\fP +.\" +documentation. +.P +The global variable \fBpcre_callout\fP 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 +.\" HREF +\fBpcrecallout\fP +.\" +documentation. +. +. +.\" HTML +.SH NEWLINES +.rs +.sp +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 (form feed, +U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS +(paragraph separator, U+2029). +.P +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 standard. When PCRE is run, the +default can be overridden, either when a pattern is compiled, or when it is +matched. +.P +At compile time, the newline convention can be specified by the \fIoptions\fP +argument of \fBpcre_compile()\fP, or it can be specified by special text at the +start of the pattern itself; this overrides any other settings. See the +.\" HREF +\fBpcrepattern\fP +.\" +page for details of the special character sequences. +.P +In the PCRE documentation the word "newline" is used to mean "the character 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 advancement for a +non-anchored pattern. There is more detail about this in the +.\" HTML +.\" +section on \fBpcre_exec()\fP options +.\" +below. +.P +The choice of newline convention does not affect the interpretation of +the \en or \er escape sequences, nor does it affect what \eR matches, which is +controlled in a similar way, but by separate options. +. +. +.SH MULTITHREADING +.rs +.sp +The PCRE functions can be used in multi-threading applications, with the +proviso that the memory management functions pointed to by \fBpcre_malloc\fP, +\fBpcre_free\fP, \fBpcre_stack_malloc\fP, and \fBpcre_stack_free\fP, and the +callout function pointed to by \fBpcre_callout\fP, are shared by all threads. +.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" +.rs +.sp +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 +.\" HREF +\fBpcreprecompile\fP +.\" +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" +.rs +.sp +.B int pcre_config(int \fIwhat\fP, void *\fIwhere\fP); +.PP +The function \fBpcre_config()\fP makes it possible for a PCRE client to +discover which optional features have been compiled into the PCRE library. The +.\" HREF +\fBpcrebuild\fP +.\" +documentation has more details about these optional features. +.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 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. This value should normally be given to the 8-bit +version of this function, \fBpcre_config()\fP. If it is given to the 16-bit +or 32-bit version of this function, 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 +or 32-bit version of this function, the result is PCRE_ERROR_BADOPTION. +.sp + PCRE_CONFIG_UTF32 +.sp +The output is an integer that is set to one if UTF-32 support is available; +otherwise it is set to zero. This value should normally be given to the 32-bit +version of this function, \fBpcre32_config()\fP. If it is given to the 8-bit +or 16-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 +that is recognized as meaning "newline". The values that are supported in +ASCII/Unicode environments are: 10 for LF, 13 for CR, 3338 for CRLF, -2 for +ANYCRLF, and -1 for ANY. In EBCDIC environments, CR, ANYCRLF, and ANY yield the +same values. However, the value for LF is normally 21, though some EBCDIC +environments use 37. The corresponding values for CRLF are 3349 and 3365. The +default should normally correspond to the standard sequence for your operating +system. +.sp + PCRE_CONFIG_BSR +.sp +The output is an integer whose value indicates what character sequences the \eR +escape sequence matches by default. A value of 0 means that \eR matches any +Unicode line ending sequence; a value of 1 means that \eR matches only CR, LF, +or CRLF. The default can be overridden when a pattern is compiled or matched. +.sp + PCRE_CONFIG_LINK_SIZE +.sp +The output is an integer that contains the number of bytes used for internal +linkage in compiled regular expressions. For the 8-bit library, the value can +be 2, 3, or 4. For the 16-bit library, the value is either 2 or 4 and is still +a number of bytes. For the 32-bit 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 +The output is an integer that contains the threshold above which the POSIX +interface uses \fBmalloc()\fP for output vectors. Further details are given in +the +.\" HREF +\fBpcreposix\fP +.\" +documentation. +.sp + PCRE_CONFIG_MATCH_LIMIT +.sp +The output is a long integer that gives the default limit for the number of +internal matching function calls in a \fBpcre_exec()\fP execution. Further +details are given with \fBpcre_exec()\fP below. +.sp + PCRE_CONFIG_MATCH_LIMIT_RECURSION +.sp +The output is a long integer that gives the default limit for the depth of +recursion when calling the internal matching function in a \fBpcre_exec()\fP +execution. Further details are given with \fBpcre_exec()\fP below. +.sp + PCRE_CONFIG_STACKRECURSE +.sp +The output is an integer that is set to one if internal recursion when running +\fBpcre_exec()\fP is implemented by recursive function calls that use 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, \fBpcre_stack_malloc\fP and +\fBpcre_stack_free\fP are called to manage memory blocks on the heap, thus +avoiding the use of the stack. +. +. +.SH "COMPILING A PATTERN" +.rs +.sp +.B pcre *pcre_compile(const char *\fIpattern\fP, int \fIoptions\fP, +.ti +5n +.B const char **\fIerrptr\fP, int *\fIerroffset\fP, +.ti +5n +.B const unsigned char *\fItableptr\fP); +.sp +.B pcre *pcre_compile2(const char *\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); +.P +Either of the functions \fBpcre_compile()\fP or \fBpcre_compile2()\fP can be +called to compile a pattern into an internal form. The only difference between +the two interfaces is that \fBpcre_compile2()\fP has an additional argument, +\fIerrorcodeptr\fP, via which a numerical error code can be returned. To avoid +too much repetition, we refer just to \fBpcre_compile()\fP below, but the +information applies equally to \fBpcre_compile2()\fP. +.P +The pattern is a C string terminated by a binary zero, and is passed in the +\fIpattern\fP argument. A pointer to a single block of memory that is obtained +via \fBpcre_malloc\fP is returned. This contains the compiled code and related +data. The \fBpcre\fP 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 \fBpcre_free\fP) when it is no longer required. +.P +Although the compiled code of a PCRE regex is relocatable, that is, it does not +depend on memory location, the complete \fBpcre\fP data block is not +fully relocatable, because it may contain a copy of the \fItableptr\fP +argument, which is an address (see below). +.P +The \fIoptions\fP argument contains various bit settings that affect the +compilation. 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 +.\" HREF +\fBpcrepattern\fP +.\" +documentation). For those options that can be different in different parts of +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_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. 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 +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. +.P +If the final argument, \fItableptr\fP, is NULL, PCRE uses a default set of +character tables that are built when PCRE is compiled, using the default C +locale. Otherwise, \fItableptr\fP must be an address that is the result of a +call to \fBpcre_maketables()\fP. This value is stored with the compiled +pattern, and used again by \fBpcre_exec()\fP, unless another table pointer is +passed to it. For more discussion, see the section on locale support below. +.P +This code fragment shows a typical straightforward call to \fBpcre_compile()\fP: +.sp + pcre *re; + const char *error; + int erroffset; + re = pcre_compile( + "^A.*Z", /* the pattern */ + 0, /* default options */ + &error, /* for error message */ + &erroffset, /* for error offset */ + NULL); /* use default character tables */ +.sp +The following names for option bits are defined in the \fBpcre.h\fP header +file: +.sp + PCRE_ANCHORED +.sp +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 only way to do it in +Perl. +.sp + PCRE_AUTO_CALLOUT +.sp +If this bit is set, \fBpcre_compile()\fP automatically inserts callout items, +all with number 255, before each pattern item. For discussion of the callout +facility, see the +.\" HREF +\fBpcrecallout\fP +.\" +documentation. +.sp + PCRE_BSR_ANYCRLF + PCRE_BSR_UNICODE +.sp +These options (which are mutually exclusive) control what the \eR escape +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 setting an option +when a compiled pattern is matched. +.sp + PCRE_CASELESS +.sp +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 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. +.sp + PCRE_DOLLAR_ENDONLY +.sp +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. +.sp + PCRE_DOTALL +.sp +If this bit is set, a dot metacharacter in the pattern matches a character 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 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 such as [^a] always matches newline +characters, independent of the setting of this option. +.sp + PCRE_DUPNAMES +.sp +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 the +.\" HREF +\fBpcrepattern\fP +.\" +documentation. +.sp + PCRE_EXTENDED +.sp +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 +.\" HTML +.\" +"Newline conventions" +.\" +in the \fBpcrepattern\fP documentation. 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. +.P +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 introduces a conditional subpattern. +.sp + PCRE_EXTRA +.sp +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 within a pattern. +.sp + PCRE_FIRSTLINE +.sp +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. +.sp + PCRE_JAVASCRIPT_COMPAT +.sp +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 follows: +.P +(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. +.P +(2) At run time, a back reference to an unset subpattern group matches an empty +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 +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. +.P +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 newlines in a subject string, or no +occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no effect. +.sp + PCRE_NEWLINE_CR + PCRE_NEWLINE_LF + PCRE_NEWLINE_CRLF + PCRE_NEWLINE_ANYCRLF + PCRE_NEWLINE_ANY +.sp +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 recognized. +.P +In an ASCII/Unicode environment, 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). For the 8-bit library, the last two are +recognized only in UTF-8 mode. +.P +When PCRE is compiled to run in an EBCDIC (mainframe) environment, the code for +CR is 0x0d, the same as ASCII. However, the character code for LF is normally +0x15, though in some EBCDIC environments 0x25 is used. Whichever of these is +not LF is made to correspond to Unicode's NEL character. EBCDIC codes are all +less than 256. For more details, see the +.\" HREF +\fBpcrebuild\fP +.\" +documentation. +.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 +plus the five values above). This means that if you set more than one newline +option, the combination may or may not be sensible. For example, +PCRE_NEWLINE_CR with PCRE_NEWLINE_LF is equivalent to PCRE_NEWLINE_CRLF, but +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 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 +data. +.P +The newline option that is set at compile time becomes the default that is used +for \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP, but it can be overridden. +.sp + PCRE_NO_AUTO_CAPTURE +.sp +If this option is set, it disables the use of numbered capturing parentheses 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. +.sp + NO_START_OPTIMIZE +.sp +This is an option that acts at matching time; that is, it is really an option +for \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. If it is set at compile time, +it is remembered with the compiled pattern and assumed at matching time. For +details see the discussion of PCRE_NO_START_OPTIMIZE +.\" HTML +.\" +below. +.\" +.sp + PCRE_UCP +.sp +This option changes the way PCRE processes \eB, \eb, \eD, \ed, \eS, \es, \eW, +\ew, 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 +.\" HTML +.\" +generic character types +.\" +in the +.\" HREF +\fBpcrepattern\fP +.\" +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 +property support. +.sp + PCRE_UNGREEDY +.sp +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. +.sp + 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 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 +\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 +.\" +validity of UTF-8 strings +.\" +in the +.\" HREF +\fBpcreunicode\fP +.\" +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 only. If the same string is being matched +many times, the option can be safely set for the second and subsequent +matchings to improve performance. +. +. +.SH "COMPILATION ERROR CODES" +.rs +.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. Note that error messages are always 8-bit ASCII +strings, even in 16-bit or 32-bit mode. As PCRE has developed, some error codes +have fallen out of use. To avoid confusion, they have not been re-used. +.sp + 0 no error + 1 \e at end of pattern + 2 \ec at end of pattern + 3 unrecognized character follows \e + 4 numbers out of order in {} quantifier + 5 number too big in {} quantifier + 6 missing terminating ] for character class + 7 invalid escape sequence in character class + 8 range out of order in character class + 9 nothing to repeat + 10 [this code is not in use] + 11 internal error: unexpected repeat + 12 unrecognized character after (? or (?- + 13 POSIX named classes are supported only within a class + 14 missing ) + 15 reference to non-existent subpattern + 16 erroffset passed as NULL + 17 unknown option bit(s) set + 18 missing ) after comment + 19 [this code is not in use] + 20 regular expression is too large + 21 failed to get memory + 22 unmatched parentheses + 23 internal error: code overflow + 24 unrecognized character after (?< + 25 lookbehind assertion is not fixed length + 26 malformed number or name after (?( + 27 conditional group contains more than two branches + 28 assertion expected after (?( + 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 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{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 (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 in 8-bit non-UTF-8 mode + 52 internal error: overran compiling workspace + 53 internal error: previously-checked referenced subpattern + not found + 54 DEFINE group contains more than one branch + 55 repeating a DEFINE group is not allowed + 56 inconsistent NEWLINE options + 57 \eg is not followed by a braced, angle-bracketed, or quoted + name/number or by a plain number + 58 a numbered reference must not be zero + 59 an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) + 60 (*VERB) not recognized + 61 number is too big + 62 subpattern name expected + 63 digit expected after (?+ + 64 ] is an invalid data character in JavaScript compatibility mode + 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 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 + 77 invalid UTF-32 string (specifically UTF-32) +.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 +.B pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP +.ti +5n +.B const char **\fIerrptr\fP); +.PP +If a compiled pattern is going to be used several times, it is worth spending +more time analyzing it in order to speed up the time taken for matching. The +function \fBpcre_study()\fP takes a pointer to a compiled pattern as its first +argument. If studying the pattern produces additional information that will +help speed up matching, \fBpcre_study()\fP returns a pointer to a +\fBpcre_extra\fP block, in which the \fIstudy_data\fP field points to the +results of the study. +.P +The returned value from \fBpcre_study()\fP can be passed directly to +\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. However, a \fBpcre_extra\fP block +also contains other fields that can be set by the caller before the block is +passed; these are described +.\" HTML +.\" +below +.\" +in the section on matching a pattern. +.P +If studying the pattern does not produce any useful information, +\fBpcre_study()\fP returns NULL by default. In that circumstance, if the +calling program 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. However, +if \fBpcre_study()\fP is called with the PCRE_STUDY_EXTRA_NEEDED option, it +returns a \fBpcre_extra\fP block even if studying did not find any additional +information. It may still return NULL, however, if an error occurs in +\fBpcre_study()\fP. +.P +The second argument of \fBpcre_study()\fP contains option bits. There are three +further options in addition to PCRE_STUDY_EXTRA_NEEDED: +.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 undefined 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 +set to NULL. Otherwise it is set to point to a textual error message. This is a +static string that is part of the library. You must not try to free it. You +should test the error pointer for NULL after calling \fBpcre_study()\fP, to be +sure that it has run successfully. +.P +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 + 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 */ + &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 +mean that there are any strings of that length that match, but it does +guarantee that no shorter strings match. The value is used to avoid wasting +time by trying to match strings that are shorter than the lower bound. You can +find out the value in a calling program via the \fBpcre_fullinfo()\fP function. +.P +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. (In 16-bit mode, the bitmap is used for 16-bit values less than 256. +In 32-bit mode, the bitmap is used for 32-bit values less than 256.) +.P +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. +.\" +. +. +.\" HTML +.SH "LOCALE SUPPORT" +.rs +.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. +.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. +Normally, the internal tables recognize only ASCII characters. However, when +PCRE is built, it is possible to cause the internal tables to be rebuilt in the +default "C" locale of the local system, which may cause them to be different. +.P +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 Unicode, the need +for this locale support is expected to die away. +.P +External tables are built by calling the \fBpcre_maketables()\fP function, +which has no arguments, in the relevant locale. The result can then be passed +to \fBpcre_compile()\fP or \fBpcre_exec()\fP 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: +.sp + setlocale(LC_CTYPE, "fr_FR"); + tables = pcre_maketables(); + re = pcre_compile(..., tables); +.sp +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". +.P +When \fBpcre_maketables()\fP runs, the tables are built in memory that is +obtained via \fBpcre_malloc\fP. It is the caller's responsibility to ensure +that the memory containing the tables remains available for as long as it is +needed. +.P +The pointer that is passed to \fBpcre_compile()\fP is saved with the compiled +pattern, and the same tables are used via this pointer by \fBpcre_study()\fP +and normally also by \fBpcre_exec()\fP. Thus, by default, for any single +pattern, compilation, studying and matching all happen in the same locale, but +different patterns can be compiled in different locales. +.P +It is possible to pass a table pointer or NULL (indicating the use of the +internal tables) to \fBpcre_exec()\fP. 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. +. +. +.\" HTML +.SH "INFORMATION ABOUT A PATTERN" +.rs +.sp +.B int pcre_fullinfo(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," +.ti +5n +.B int \fIwhat\fP, void *\fIwhere\fP); +.PP +The \fBpcre_fullinfo()\fP function returns information about a compiled +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 +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: +.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_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. 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() */ + sd, /* result of pcre_study(), or NULL */ + PCRE_INFO_SIZE, /* what is required */ + &length); /* where to put the data */ +.sp +The possible values for the third argument are defined in \fBpcre.h\fP, and are +as follows: +.sp + PCRE_INFO_BACKREFMAX +.sp +Return the number of the highest back reference in the pattern. The fourth +argument should point to an \fBint\fP variable. Zero is returned if there are +no back references. +.sp + PCRE_INFO_CAPTURECOUNT +.sp +Return the number of capturing subpatterns in the pattern. The fourth argument +should point to an \fBint\fP variable. +.sp + PCRE_INFO_DEFAULT_TABLES +.sp +Return a pointer to the internal default character tables within PCRE. The +fourth argument should point to an \fBunsigned char *\fP variable. This +information call is provided for internal use by the \fBpcre_study()\fP +function. External callers can cause PCRE to use its internal tables by passing +a NULL table pointer. +.sp + PCRE_INFO_FIRSTBYTE +.sp +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 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. In the 32-bit library the value can be up to 0x10ffff. +.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 +.sp +(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set +(if it were set, the pattern would be anchored), +.sp +-1 is returned, indicating that the pattern matches only at the start of a +subject string or after any newline within the string. Otherwise -2 is +returned. For anchored patterns, -2 is returned. +.P +Since for the 32-bit library using the non-UTF-32 mode, this function is unable +to return the full 32-bit range of the character, this value is deprecated; +instead the PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER values +should be used. +.sp + 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 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 + PCRE_INFO_HASCRORLF +.sp +Return 1 if the pattern contains any explicit matches for CR or LF characters, +otherwise 0. The fourth argument should point to an \fBint\fP variable. An +explicit match is either a literal CR or LF character, or \er or \en. +.sp + PCRE_INFO_JCHANGED +.sp +Return 1 if the (?J) or (?-J) option setting is used in the pattern, otherwise +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 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. +.P +Since for the 32-bit library using the non-UTF-32 mode, this function is unable +to return the full 32-bit range of the character, this value is deprecated; +instead the PCRE_INFO_REQUIREDCHARFLAGS and PCRE_INFO_REQUIREDCHAR values should +be used. +.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, 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. +.sp + PCRE_INFO_NAMECOUNT + PCRE_INFO_NAMEENTRYSIZE + PCRE_INFO_NAMETABLE +.sp +PCRE supports the use of named as well as numbered capturing parentheses. The +names are just an additional way of identifying the parentheses, which still +acquire numbers. Several convenience functions such as +\fBpcre_get_named_substring()\fP are provided for extracting captured +substrings by name. It is also possible to extract the data directly, by first +converting the name to a number in order to access the correct pointers in the +output vector (described with \fBpcre_exec()\fP below). To do the conversion, +you need to use the name-to-number map, which is described by these three +values. +.P +The map consists of a number of fixed-size entries. PCRE_INFO_NAMECOUNT gives +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. 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. +In the 32-bit library, the pointer points to 32-bit data units, the first of +which contains the parenthesis number. The rest +of the entry is the corresponding name, zero terminated. +.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 +.\" HTML +.\" +section on duplicate subpattern numbers +.\" +in the +.\" HREF +\fBpcrepattern\fP +.\" +page. Duplicate names for subpatterns with different numbers are permitted only +if PCRE_DUPNAMES is set. In all cases of duplicate names, they appear in the +table in the order in which they were found in the pattern. In the absence of +(?| this is the order of increasing number; when (?| is used this is not +necessarily the case because later subpatterns may have lower numbers. +.P +As a simple example of the name/number table, consider the following pattern +after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white +space - including newlines - is ignored): +.sp +.\" JOIN + (? (?(\ed\ed)?\ed\ed) - + (?\ed\ed) - (?\ed\ed) ) +.sp +There are four named subpatterns, so the table has four entries, and each entry +in the table is eight bytes long. The table is as follows, with non-printing +bytes shows in hexadecimal, and undefined bytes shown as ??: +.sp + 00 01 d a t e 00 ?? + 00 05 d a y 00 ?? ?? + 00 04 m o n t h 00 + 00 02 y e a r 00 ?? +.sp +When writing code to extract data from named subpatterns using the +name-to-number map, remember that the length of the entries is likely to be +different for each compiled pattern. +.sp + PCRE_INFO_OKPARTIAL +.sp +Return 1 if the pattern can be used for partial matching with +\fBpcre_exec()\fP, otherwise 0. The fourth argument should point to an +\fBint\fP variable. From release 8.00, this always returns 1, because the +restrictions that previously applied to partial matching have been lifted. The +.\" HREF +\fBpcrepartial\fP +.\" +documentation gives details of partial matching. +.sp + PCRE_INFO_OPTIONS +.sp +Return a copy of the options with which the pattern was compiled. The fourth +argument should point to an \fBunsigned long int\fP variable. These option bits +are those specified in the call to \fBpcre_compile()\fP, modified by any +top-level option settings at the start of the pattern itself. In other words, +they are the options that will be in force when matching starts. For example, +if the pattern /(?im)abc(?-i)d/ is compiled with the PCRE_EXTENDED option, the +result is PCRE_CASELESS, PCRE_MULTILINE, and PCRE_EXTENDED. +.P +A pattern is automatically anchored by PCRE if all of its top-level +alternatives begin with one of the following: +.sp + ^ unless PCRE_MULTILINE is set + \eA always + \eG always +.\" JOIN + .* if PCRE_DOTALL is set and there are no back + references to the subpattern in which .* appears +.sp +For such patterns, the PCRE_ANCHORED bit is set in the options returned by +\fBpcre_fullinfo()\fP. +.sp + PCRE_INFO_SIZE +.sp +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 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. 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). +.sp + PCRE_INFO_FIRSTCHARACTERFLAGS +.sp +Return information about the first data unit of any matched string, for a +non-anchored pattern. The fourth argument should point to an \fBint\fP +variable. +.P +If there is a fixed first value, for example, the letter "c" from a pattern +such as (cat|cow|coyote), 1 is returned, and the character value can be +retrieved using PCRE_INFO_FIRSTCHARACTER. +.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 +.sp +(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set +(if it were set, the pattern would be anchored), +.sp +2 is returned, indicating that the pattern matches only at the start of a +subject string or after any newline within the string. Otherwise 0 is +returned. For anchored patterns, 0 is returned. +.sp + PCRE_INFO_FIRSTCHARACTER +.sp +Return the fixed first character value, if PCRE_INFO_FIRSTCHARACTERFLAGS +returned 1; otherwise returns 0. The fourth argument should point to an +\fBuint_t\fP variable. +.P +In the 8-bit library, the value is always less than 256. In the 16-bit library +the value can be up to 0xffff. In the 32-bit library in UTF-32 mode the value +can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode. +.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 +.sp +(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set +(if it were set, the pattern would be anchored), +.sp +-1 is returned, indicating that the pattern matches only at the start of a +subject string or after any newline within the string. Otherwise -2 is +returned. For anchored patterns, -2 is returned. +.sp + PCRE_INFO_REQUIREDCHARFLAGS +.sp +Returns 1 if there is a rightmost literal data unit that must exist in any +matched string, other than at its start. The fourth argument should point to +an \fBint\fP variable. If there is no such value, 0 is returned. If returning +1, the character value itself can be retrieved using PCRE_INFO_REQUIREDCHAR. +.P +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 1 (with "z" returned from PCRE_INFO_REQUIREDCHAR), but for +/^a\edz\ed/ the returned value is 0. +.sp + PCRE_INFO_REQUIREDCHAR +.sp +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 \fBuint32_t\fP variable. If there is no such +value, 0 is returned. +. +. +.SH "REFERENCE COUNTS" +.rs +.sp +.B int pcre_refcount(pcre *\fIcode\fP, int \fIadjust\fP); +.PP +The \fBpcre_refcount()\fP 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, 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. +.P +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 +\fIadjust\fP 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 outside these limits, +it is forced to the appropriate limit value. +.P +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.) +. +. +.SH "MATCHING A PATTERN: THE TRADITIONAL FUNCTION" +.rs +.sp +.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, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); +.P +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. 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 +.\" +in the section about the \fBpcre_dfa_exec()\fP function. +.P +In most applications, the pattern will have been compiled (and optionally +studied) in the same process that calls \fBpcre_exec()\fP. 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 discussion +about this, see the +.\" HREF +\fBpcreprecompile\fP +.\" +documentation. +.P +Here is an example of a simple call to \fBpcre_exec()\fP: +.sp + int rc; + int ovector[30]; + rc = pcre_exec( + re, /* result of pcre_compile() */ + NULL, /* we didn't study the pattern */ + "some string", /* the subject string */ + 11, /* the length of the subject string */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + ovector, /* vector of integers for substring information */ + 30); /* number of elements (NOT size in bytes) */ +. +. +.\" HTML +.SS "Extra data for \fBpcre_exec()\fR" +.rs +.sp +If the \fIextra\fP argument is not NULL, it must point to a \fBpcre_extra\fP +data block. The \fBpcre_study()\fP function returns such a block (when it +doesn't return NULL), but you can also create one for yourself, and pass +additional information in it. The \fBpcre_extra\fP block contains the following +fields (not necessarily in this order): +.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 +In the 16-bit version of this structure, the \fImark\fP field has type +"PCRE_UCHAR16 **". +.sp +In the 32-bit version of this structure, the \fImark\fP field has type +"PCRE_UCHAR32 **". +.P +The \fIflags\fP field is used to specify which of the other fields are set. The +flag bits are: +.sp + PCRE_EXTRA_CALLOUT_DATA + PCRE_EXTRA_EXECUTABLE_JIT + PCRE_EXTRA_MARK + PCRE_EXTRA_MATCH_LIMIT + PCRE_EXTRA_MATCH_LIMIT_RECURSION + PCRE_EXTRA_STUDY_DATA + PCRE_EXTRA_TABLES +.sp +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, \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 +override the default by suppling \fBpcre_exec()\fP with a \fBpcre_extra\fP +block in which \fImatch_limit\fP is set, and PCRE_EXTRA_MATCH_LIMIT is set in +the \fIflags\fP field. If the limit is exceeded, \fBpcre_exec()\fP returns +PCRE_ERROR_MATCHLIMIT. +.P +The \fImatch_limit_recursion\fP field is similar to \fImatch_limit\fP, but +instead of limiting the total number of times that \fBmatch()\fP 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 \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 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 +\fImatch_limit\fP. You can override the default by suppling \fBpcre_exec()\fP +with a \fBpcre_extra\fP block in which \fImatch_limit_recursion\fP is set, and +PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the \fIflags\fP field. If the limit +is exceeded, \fBpcre_exec()\fP returns PCRE_ERROR_RECURSIONLIMIT. +.P +The \fIcallout_data\fP field is used in conjunction with the "callout" feature, +and is described in the +.\" HREF +\fBpcrecallout\fP +.\" +documentation. +.P +The \fItables\fP field is used to pass a character tables pointer to +\fBpcre_exec()\fP; 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 \fBpcre_compile()\fP via its \fItableptr\fP argument. +If NULL is passed to \fBpcre_exec()\fP 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 \fBpcre_exec()\fP is +called. See the +.\" HREF +\fBpcreprecompile\fP +.\" +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 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 is set to NULL. For details of the +backtracking control verbs, see the section entitled +.\" HTML +.\" +"Backtracking control" +.\" +in the +.\" HREF +\fBpcrepattern\fP +.\" +documentation. +. +. +.\" HTML +.SS "Option bits for \fBpcre_exec()\fP" +.rs +.sp +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_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 +The PCRE_ANCHORED option limits \fBpcre_exec()\fP to matching at the first +matching position. If a pattern was compiled with PCRE_ANCHORED, or turned out +to be anchored by virtue of its contents, it cannot be made unachored at +matching time. +.sp + PCRE_BSR_ANYCRLF + PCRE_BSR_UNICODE +.sp +These options (which are mutually exclusive) control what the \eR escape +sequence matches. The choice is either to match only CR, LF, or CRLF, or to +match any Unicode newline sequence. These options override the choice that was +made or defaulted when the pattern was compiled. +.sp + PCRE_NEWLINE_CR + PCRE_NEWLINE_LF + PCRE_NEWLINE_CRLF + PCRE_NEWLINE_ANYCRLF + PCRE_NEWLINE_ANY +.sp +These options override the newline definition that was chosen or defaulted when +the pattern was compiled. For details, see the description of +\fBpcre_compile()\fP above. During matching, the newline choice affects the +behaviour of the dot, circumflex, and dollar metacharacters. It may also alter +the way the match position is advanced after a match failure for an unanchored +pattern. +.P +When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is set, and a +match attempt for an unanchored pattern fails when the current position is at a +CRLF sequence, and the pattern contains no explicit matches for CR or LF +characters, the match position is advanced by two characters instead of one, in +other words, to after the CRLF. +.P +The above rule is a compromise that makes the most common cases work as +expected. For example, if the pattern is .+A (and the PCRE_DOTALL option is not +set), it does not match the string "\er\enA" because, after failing at the +start, it skips both the CR and the LF before retrying. However, the pattern +[\er\en]A does match that string, because it contains an explicit CR or LF +reference, and so advances only by one character after the first failure. +.P +An explicit match for CR of LF is either a literal appearance of one of those +characters, or one of the \er or \en escape sequences. Implicit matches such as +[^X] do not count, nor does \es (which includes CR and LF in the characters +that it matches). +.P +Notwithstanding the above, anomalous effects may still occur when CRLF is a +valid newline sequence and explicit \er or \en escapes appear in the pattern. +.sp + PCRE_NOTBOL +.sp +This option specifies that first character of the subject string is not the +beginning of a line, so the circumflex metacharacter should not match before +it. Setting this without PCRE_MULTILINE (at compile time) causes circumflex +never to match. This option affects only the behaviour of the circumflex +metacharacter. It does not affect \eA. +.sp + PCRE_NOTEOL +.sp +This option specifies that the end of the subject string is not the end of a +line, so the dollar metacharacter should not match it nor (except in multiline +mode) a newline immediately before it. Setting this without PCRE_MULTILINE (at +compile time) causes dollar never to match. This option affects only the +behaviour of the dollar metacharacter. It does not affect \eZ or \ez. +.sp + PCRE_NOTEMPTY +.sp +An empty string is not considered to be a valid match if this option is set. If +there are alternatives in the pattern, they are tried. If all the alternatives +match the empty string, the entire match fails. For example, if the pattern +.sp + a?b? +.sp +is applied to a string not beginning with "a" or "b", it matches an empty +string at the start of the subject. With PCRE_NOTEMPTY set, this match is not +valid, so PCRE searches further into the string for occurrences of "a" or "b". +.sp + PCRE_NOTEMPTY_ATSTART +.sp +This is like PCRE_NOTEMPTY, except that an empty string match that is not at +the start of the subject is permitted. If the pattern is anchored, such a match +can occur only if the pattern contains \eK. +.P +Perl has no direct equivalent of PCRE_NOTEMPTY or PCRE_NOTEMPTY_ATSTART, but it +does make a special case of a pattern match of the empty string within its +\fBsplit()\fP function, and when using the /g modifier. It is possible to +emulate Perl's behaviour after matching a null string by first trying the match +again at the same offset with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then +if that fails, by advancing the starting offset (see below) and trying an +ordinary match again. There is some code that demonstrates how to do this in +the +.\" HREF +\fBpcredemo\fP +.\" +sample program. In the most general case, you have to check to see if the +newline convention recognizes CRLF as a newline, and if so, and the current +character is CR followed by LF, advance the starting offset by two characters +instead of one. +.sp + PCRE_NO_START_OPTIMIZE +.sp +There are a number of optimizations that \fBpcre_exec()\fP uses at the start of +a match, in order to speed up the process. For example, if it is known that an +unanchored match must start with a specific character, it searches the subject +for that character, and fails immediately if it cannot find it, without +actually running the main matching function. This means that a special item +such as (*COMMIT) at the start of a pattern is not considered until after a +suitable starting point for the match has been found. When callouts or (*MARK) +items are in use, these "start-up" optimizations can cause them to be skipped +if the pattern is never actually used. The start-up optimizations are in effect +a pre-scan of the subject that takes place before the pattern is run. +.P +The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, possibly +causing performance to suffer, but ensuring that in cases where the result is +"no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) +are considered at every possible starting position in the subject string. If +PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching +time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, +matching is always done using interpretively. +.P +Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. +Consider the pattern +.sp + (*COMMIT)ABC +.sp +When this is compiled, PCRE records the fact that a match must start with the +character "A". Suppose the subject string is "DEFABC". The start-up +optimization scans along the subject, finds "A" and runs the first match +attempt from there. The (*COMMIT) item means that the pattern must match the +current starting position, which in this case, it does. However, if the same +match is run with PCRE_NO_START_OPTIMIZE set, the initial scan along the +subject string does not happen. The first match attempt is run starting from +"D" and when this fails, (*COMMIT) prevents any further matches being tried, so +the overall result is "no match". If the pattern is studied, more start-up +optimizations may be used. For example, a minimum length for the subject may be +recorded. Consider the pattern +.sp + (*MARK:A)(X|Y) +.sp +The minimum length for a match is one character. If the subject is "ABC", there +will be attempts to match "ABC", "BC", "C", and then finally an empty string. +If the pattern is studied, the final attempt does not take place, because PCRE +knows that the subject is too short, and so the (*MARK) is never encountered. +In this case, studying the pattern does not affect the overall match result, +which is still "no match", but it does affect the auxiliary information that is +returned. +.sp + PCRE_NO_UTF8_CHECK +.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 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 +.\" +validity of UTF-8 strings +.\" +in the +.\" HREF +\fBpcreunicode\fP +.\" +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 +checks for performance reasons, you can set the PCRE_NO_UTF8_CHECK option when +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 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 + PCRE_PARTIAL_SOFT +.sp +These options turn on the partial matching feature. For backwards +compatibility, 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 match can be found. +.P +If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this case, if a +partial match is found, \fBpcre_exec()\fP immediately returns +PCRE_ERROR_PARTIAL, without considering any other alternatives. In other words, +when PCRE_PARTIAL_HARD is set, a partial match is considered to be more +important that an alternative complete match. +.P +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 examples, in the +.\" HREF +\fBpcrepartial\fP +.\" +documentation. +. +. +.SS "The string to be matched by \fBpcre_exec()\fP" +.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 +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, +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 subject). Unlike the +pattern string, the subject may contain binary zero bytes. +.P +A non-zero starting offset is useful when searching for another match in the +same subject by calling \fBpcre_exec()\fP again after a previous success. +Setting \fIstartoffset\fP 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 +.sp + \eBiss\eB +.sp +which finds occurrences of "iss" in the middle of words. (\eB matches only if +the current position in the subject is not a word boundary.) When applied to +the string "Mississipi" the first call to \fBpcre_exec()\fP finds the first +occurrence. If \fBpcre_exec()\fP is called again with just the remainder of the +subject, namely "issipi", it does not match, because \eB is always false at the +start of the subject, which is deemed to be a word boundary. However, if +\fBpcre_exec()\fP is passed the entire string again, but with \fIstartoffset\fP +set to 4, it finds the second occurrence of "iss" because it is able to look +behind the starting point to discover that it is preceded by a letter. +.P +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 again. There is some code that demonstrates how to +do this in the +.\" HREF +\fBpcredemo\fP +.\" +sample program. In the most general case, you have to check to see if the +newline convention recognizes CRLF as a newline, and if so, and the current +character is CR followed by LF, advance the starting offset by two characters +instead of one. +.P +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 subject. +. +. +.SS "How \fBpcre_exec()\fP returns captured substrings" +.rs +.sp +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 substring. PCRE supports several other +kinds of parenthesized subpattern that do not cause substrings to be captured. +.P +Captured substrings are returned to the caller via a vector of integers whose +address is passed in \fIovector\fP. The number of elements in the vector is +passed in \fIovecsize\fP, which must be a non-negative number. \fBNote\fP: this +argument is NOT the size of \fIovector\fP in bytes. +.P +The first two-thirds of the vector is used to pass back captured substrings, +each substring using a pair of integers. The remaining third of the vector is +used as workspace by \fBpcre_exec()\fP while matching capturing subpatterns, +and is not available for passing back information. The number passed in +\fIovecsize\fP should always be a multiple of three. If it is not, it is +rounded down. +.P +When a match is successful, information about captured substrings is returned +in pairs of integers, starting at the beginning of \fIovector\fP, 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. \fBNote\fP: these values are always byte offsets, even in UTF-8 +mode. They are not character counts. +.P +The first pair of integers, \fIovector[0]\fP and \fIovector[1]\fP, 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 +\fBpcre_exec()\fP 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 value from a successful match is +1, indicating that just the first pair of offsets has been set. +.P +If a capturing subpattern is matched repeatedly, it is the last portion of the +string that it matched that is returned. +.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 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 +\fIovector\fP that will allow for \fIn\fP captured substrings, in addition to +the offsets of the substring matched by the whole pattern, is (\fIn\fP+1)*3. +.P +It is possible for capturing subpattern number \fIn+1\fP to match some part of +the subject when subpattern \fIn\fP has not been used at all. For example, 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 corresponding to unused subpatterns +are set to -1. +.P +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. +.P +\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 +.sp +If \fBpcre_exec()\fP fails, it returns a negative number. The following are +defined in the header file: +.sp + PCRE_ERROR_NOMATCH (-1) +.sp +The subject string did not match the pattern. +.sp + PCRE_ERROR_NULL (-2) +.sp +Either \fIcode\fP or \fIsubject\fP was passed as NULL, or \fIovector\fP was +NULL and \fIovecsize\fP was not zero. +.sp + PCRE_ERROR_BADOPTION (-3) +.sp +An unrecognized bit was set in the \fIoptions\fP argument. +.sp + PCRE_ERROR_BADMAGIC (-4) +.sp +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 gives when the magic number is +not present. +.sp + PCRE_ERROR_UNKNOWN_OPCODE (-5) +.sp +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 overwriting +of the compiled pattern. +.sp + PCRE_ERROR_NOMEMORY (-6) +.sp +If a pattern contains back references, but the \fIovector\fP that is passed to +\fBpcre_exec()\fP 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 \fBpcre_malloc()\fP fails, this error is given. The memory is +automatically freed at the end of matching. +.P +This error is also given if \fBpcre_stack_malloc()\fP fails in +\fBpcre_exec()\fP. This can happen only when PCRE has been compiled with +\fB--disable-stack-for-recursion\fP. +.sp + PCRE_ERROR_NOSUBSTRING (-7) +.sp +This error is used by the \fBpcre_copy_substring()\fP, +\fBpcre_get_substring()\fP, and \fBpcre_get_substring_list()\fP functions (see +below). It is never returned by \fBpcre_exec()\fP. +.sp + PCRE_ERROR_MATCHLIMIT (-8) +.sp +The backtracking limit, as specified by the \fImatch_limit\fP field in a +\fBpcre_extra\fP structure (or defaulted) was reached. See the description +above. +.sp + PCRE_ERROR_CALLOUT (-9) +.sp +This error is never generated by \fBpcre_exec()\fP itself. It is provided for +use by callout functions that want to yield a distinctive error code. See the +.\" HREF +\fBpcrecallout\fP +.\" +documentation for details. +.sp + PCRE_ERROR_BADUTF8 (-10) +.sp +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 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) +.sp +The subject string did not match, but it did match partially. See the +.\" HREF +\fBpcrepartial\fP +.\" +documentation for details of partial matching. +.sp + PCRE_ERROR_BADPARTIAL (-13) +.sp +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. +.sp + PCRE_ERROR_INTERNAL (-14) +.sp +An unexpected internal error has occurred. This error could be caused by a bug +in PCRE or by overwriting of the compiled pattern. +.sp + PCRE_ERROR_BADCOUNT (-15) +.sp +This error is given if the value of the \fIovecsize\fP argument is negative. +.sp + PCRE_ERROR_RECURSIONLIMIT (-21) +.sp +The internal recursion limit, as specified by the \fImatch_limit_recursion\fP +field in a \fBpcre_extra\fP structure (or defaulted) was reached. See the +description above. +.sp + PCRE_ERROR_BADNEWLINE (-23) +.sp +An invalid combination of PCRE_NEWLINE_\fIxxx\fP options was given. +.sp + PCRE_ERROR_BADOFFSET (-24) +.sp +The value of \fIstartoffset\fP was negative or greater than the length of the +subject, that is, the value in \fIlength\fP. +.sp + PCRE_ERROR_SHORTUTF8 (-25) +.sp +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 or 32-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. +.sp + PCRE_ERROR_JIT_BADOPTION +.sp +This error is returned when a pattern that was successfully studied using a JIT +compile option is being matched, but the matching mode (partial or complete +match) does not correspond to any JIT compilation mode. When the JIT fast path +function is used, this error may be also given for invalid options. See the +.\" HREF +\fBpcrejit\fP +.\" +documentation for more details. +.sp + PCRE_ERROR_BADLENGTH (-32) +.sp +This error is given if \fBpcre_exec()\fP is called with a negative value for +the \fIlength\fP argument. +.P +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 and 32-bit libraries is given in the +.\" HREF +\fBpcre16\fP +.\" +and +.\" HREF +\fBpcre32\fP +.\" +pages. +.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. +.sp + PCRE_UTF8_ERR2 +.sp +Non-character. These are the last two characters in each plane (0xfffe, 0xffff, +0x1fffe, 0x1ffff .. 0x10fffe, 0x10ffff), and the characters 0xfdd0..0xfdef. +. +. +.SH "EXTRACTING CAPTURED SUBSTRINGS BY NUMBER" +.rs +.sp +.B int pcre_copy_substring(const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP, +.ti +5n +.B int \fIbuffersize\fP); +.PP +.B int pcre_get_substring(const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, +.ti +5n +.B const char **\fIstringptr\fP); +.PP +.B int pcre_get_substring_list(const char *\fIsubject\fP, +.ti +5n +.B int *\fIovector\fP, int \fIstringcount\fP, "const char ***\fIlistptr\fP);" +.PP +Captured substrings can be accessed directly by using the offsets returned by +\fBpcre_exec()\fP in \fIovector\fP. For convenience, the functions +\fBpcre_copy_substring()\fP, \fBpcre_get_substring()\fP, and +\fBpcre_get_substring_list()\fP 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. +.P +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 \fBpcre_copy_substring()\fP and \fBpcre_get_substring()\fP. +Unfortunately, the interface to \fBpcre_get_substring_list()\fP is not adequate +for handling strings containing binary zeros, because the end of the final +string is not independently indicated. +.P +The first three arguments are the same for all three of these functions: +\fIsubject\fP is the subject string that has just been successfully matched, +\fIovector\fP is a pointer to the vector of integer offsets that was passed to +\fBpcre_exec()\fP, and \fIstringcount\fP is the number of substrings that were +captured by the match, including the substring that matched the entire regular +expression. This is the value returned by \fBpcre_exec()\fP if it is greater +than zero. If \fBpcre_exec()\fP returned zero, indicating that it ran out of +space in \fIovector\fP, the value passed as \fIstringcount\fP should be the +number of elements in the vector divided by three. +.P +The functions \fBpcre_copy_substring()\fP and \fBpcre_get_substring()\fP +extract a single substring, whose number is given as \fIstringnumber\fP. A +value of zero extracts the substring that matched the entire pattern, whereas +higher values extract the captured substrings. For \fBpcre_copy_substring()\fP, +the string is placed in \fIbuffer\fP, whose length is given by +\fIbuffersize\fP, while for \fBpcre_get_substring()\fP a new block of memory is +obtained via \fBpcre_malloc\fP, and its address is returned via +\fIstringptr\fP. The yield of the function is the length of the string, not +including the terminating zero, or one of these error codes: +.sp + PCRE_ERROR_NOMEMORY (-6) +.sp +The buffer was too small for \fBpcre_copy_substring()\fP, or the attempt to get +memory failed for \fBpcre_get_substring()\fP. +.sp + PCRE_ERROR_NOSUBSTRING (-7) +.sp +There is no substring whose number is \fIstringnumber\fP. +.P +The \fBpcre_get_substring_list()\fP function extracts all available substrings +and builds a list of pointers to them. All this is done in a single block of +memory that is obtained via \fBpcre_malloc\fP. The address of the memory block +is returned via \fIlistptr\fP, 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 +.sp + PCRE_ERROR_NOMEMORY (-6) +.sp +if the attempt to get the memory block failed. +.P +When any of these functions encounter a substring that is unset, which can +happen when capturing subpattern number \fIn+1\fP matches some part of the +subject, but subpattern \fIn\fP has not been used at all, they return an empty +string. This can be distinguished from a genuine zero-length substring by +inspecting the appropriate offset in \fIovector\fP, which is negative for unset +substrings. +.P +The two convenience functions \fBpcre_free_substring()\fP and +\fBpcre_free_substring_list()\fP can be used to free the memory returned by +a previous call of \fBpcre_get_substring()\fP or +\fBpcre_get_substring_list()\fP, respectively. They do nothing more than call +the function pointed to by \fBpcre_free\fP, which of course could be called +directly from a C program. However, PCRE is used in some situations where it is +linked via a special interface to another programming language that cannot use +\fBpcre_free\fP directly; it is for these cases that the functions are +provided. +. +. +.SH "EXTRACTING CAPTURED SUBSTRINGS BY NAME" +.rs +.sp +.B int pcre_get_stringnumber(const pcre *\fIcode\fP, +.ti +5n +.B const char *\fIname\fP); +.PP +.B int pcre_copy_named_substring(const pcre *\fIcode\fP, +.ti +5n +.B const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, const char *\fIstringname\fP, +.ti +5n +.B char *\fIbuffer\fP, int \fIbuffersize\fP); +.PP +.B int pcre_get_named_substring(const pcre *\fIcode\fP, +.ti +5n +.B const char *\fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, const char *\fIstringname\fP, +.ti +5n +.B const char **\fIstringptr\fP); +.PP +To extract a substring by name, you first have to find associated number. +For example, for this pattern +.sp + (a+)b(?\ed+)... +.sp +the number of the subpattern called "xxx" is 2. If the name is known to be +unique (PCRE_DUPNAMES was not set), you can find the number from the name by +calling \fBpcre_get_stringnumber()\fP. The first argument is the compiled +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 subpattern of +that name. +.P +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. +.P +Most of the arguments of \fBpcre_copy_named_substring()\fP and +\fBpcre_get_named_substring()\fP 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: +.P +First, instead of a substring number, a substring name is given. Second, 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 name-to-number +translation table. +.P +These functions call \fBpcre_get_stringnumber()\fP, and if it succeeds, they +then call \fBpcre_copy_substring()\fP or \fBpcre_get_substring()\fP, as +appropriate. \fBNOTE:\fP If PCRE_DUPNAMES is set and there are duplicate names, +the behaviour may not be what you want (see the next section). +.P +\fBWarning:\fP If the pattern uses the (?| feature to set up multiple +subpatterns with the same number, as described in the +.\" HTML +.\" +section on duplicate subpattern numbers +.\" +in the +.\" HREF +\fBpcrepattern\fP +.\" +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. +. +. +.SH "DUPLICATE SUBPATTERN NAMES" +.rs +.sp +.B int pcre_get_stringtable_entries(const pcre *\fIcode\fP, +.ti +5n +.B const char *\fIname\fP, char **\fIfirst\fP, char **\fIlast\fP); +.PP +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.) +.P +Normally, patterns with duplicate names are such that in any one match, only +one of the named subpatterns participates. An example is shown in the +.\" HREF +\fBpcrepattern\fP +.\" +documentation. +.P +When duplicates are present, \fBpcre_copy_named_substring()\fP and +\fBpcre_get_named_substring()\fP 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 \fBpcre_get_stringnumber()\fP function +returns one of the numbers that are associated with the name, but it is not +defined which it is. +.P +If you want to get full details of all captured substrings for a given name, +you must use the \fBpcre_get_stringtable_entries()\fP 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 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 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. +. +. +.SH "FINDING ALL POSSIBLE MATCHES" +.rs +.sp +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 of the callout facility, which is described in +the +.\" HREF +\fBpcrecallout\fP +.\" +documentation. +.P +What you have to do is to insert a callout right at the end of the pattern. +When your callout function is called, extract and save the current matched +substring. Then return 1, which forces \fBpcre_exec()\fP to backtrack and try +other alternatives. Ultimately, when it runs out of matches, \fBpcre_exec()\fP +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 +.sp +.B int pcre_dfa_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," +.ti +5n +.B "const char *\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); +.P +The function \fBpcre_dfa_exec()\fP 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. Nevertheless, 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 \fBpcre_dfa_exec()\fP does not support, see the +.\" HREF +\fBpcrematching\fP +.\" +documentation. +.P +The arguments for the \fBpcre_dfa_exec()\fP function are the same as for +\fBpcre_exec()\fP, plus two extras. The \fIovector\fP argument is used in a +different way, and this is described below. The other common arguments are used +in the same way as for \fBpcre_exec()\fP, so their description is not repeated +here. +.P +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 lot of potential matches. +.P +Here is an example of a simple call to \fBpcre_dfa_exec()\fP: +.sp + int rc; + int ovector[10]; + int wspace[20]; + rc = pcre_dfa_exec( + re, /* result of pcre_compile() */ + NULL, /* we didn't study the pattern */ + "some string", /* the subject string */ + 11, /* the length of the subject string */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + ovector, /* vector of integers for substring information */ + 10, /* number of elements (NOT size in bytes) */ + wspace, /* working space vector */ + 20); /* number of elements (NOT size in bytes) */ +. +.SS "Option bits for \fBpcre_dfa_exec()\fP" +.rs +.sp +The unused bits of the \fIoptions\fP argument for \fBpcre_dfa_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_UTF8_CHECK, PCRE_BSR_ANYCRLF, PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, +PCRE_PARTIAL_HARD, PCRE_PARTIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. +All but the last four of these are exactly the same as for \fBpcre_exec()\fP, +so their description is not repeated here. +.sp + PCRE_PARTIAL_HARD + PCRE_PARTIAL_SOFT +.sp +These have the same general effect as they do for \fBpcre_exec()\fP, but the +details are slightly different. When PCRE_PARTIAL_HARD is set for +\fBpcre_dfa_exec()\fP, it returns PCRE_ERROR_PARTIAL if the end of the subject +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 +examples, in the +.\" HREF +\fBpcrepartial\fP +.\" +documentation. +.sp + PCRE_DFA_SHORTEST +.sp +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 alternative algorithm +works, this is necessarily the shortest possible match at the first possible +matching point in the subject string. +.sp + PCRE_DFA_RESTART +.sp +When \fBpcre_dfa_exec()\fP 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 +\fIworkspace\fP and \fIwscount\fP 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 +.\" HREF +\fBpcrepartial\fP +.\" +documentation. +. +. +.SS "Successful returns from \fBpcre_dfa_exec()\fP" +.rs +.sp +When \fBpcre_dfa_exec()\fP succeeds, it may have matched more than one +substring 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, if the pattern +.sp + <.*> +.sp +is matched against the string +.sp + This is no more +.sp +the three matched strings are +.sp + + + +.sp +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 +\fIovector\fP. 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 \fBpcre_exec()\fP +returns data, even though the meaning of the strings is different.) +.P +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. 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 +.sp +The \fBpcre_dfa_exec()\fP function returns a negative number when it fails. +Many of the errors are the same as for \fBpcre_exec()\fP, and these are +described +.\" HTML +.\" +above. +.\" +There are in addition the following errors that are specific to +\fBpcre_dfa_exec()\fP: +.sp + PCRE_ERROR_DFA_UITEM (-16) +.sp +This return is given if \fBpcre_dfa_exec()\fP encounters an item in the pattern +that it does not support, for instance, the use of \eC or a back reference. +.sp + PCRE_ERROR_DFA_UCOND (-17) +.sp +This return is given if \fBpcre_dfa_exec()\fP encounters a condition item that +uses a back reference for the condition, or a test for recursion in a specific +group. These are not supported. +.sp + 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 or +\fImatch_limit_recursion\fP fields. This is not supported (these fields are +meaningless for DFA matching). +.sp + PCRE_ERROR_DFA_WSSIZE (-19) +.sp +This return is given if \fBpcre_dfa_exec()\fP runs out of space in the +\fIworkspace\fP vector. +.sp + PCRE_ERROR_DFA_RECURSE (-20) +.sp +When a recursive subpattern is processed, the matching function calls itself +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 +\fBpcre16\fP(3), \fBpcre32\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). +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 08 November 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcrebuild.3 b/tools/pcre/doc/pcrebuild.3 new file mode 100644 index 00000000..b9ae4744 --- /dev/null +++ b/tools/pcre/doc/pcrebuild.3 @@ -0,0 +1,520 @@ +.TH PCREBUILD 3 "30 October 2012" "PCRE 8.32" +.SH NAME +PCRE - Perl-compatible regular expressions +. +. +.SH "PCRE BUILD-TIME OPTIONS" +.rs +.sp +This document describes the optional features of PCRE that can be selected when +the library is compiled. It assumes use of the \fBconfigure\fP script, where +the optional features are selected or deselected by providing options to +\fBconfigure\fP before running the \fBmake\fP command. However, the same +options can be selected in both Unix-like and non-Unix-like environments using +the GUI facility of \fBcmake-gui\fP if you are using \fBCMake\fP instead of +\fBconfigure\fP to build PCRE. +.P +There is a lot more information about building PCRE without using +\fBconfigure\fP (including information about using \fBCMake\fP or building "by +hand") in the file called \fINON-AUTOTOOLS-BUILD\fP, which is part of the PCRE +distribution. You should consult this file as well as the \fIREADME\fP file if +you are building in a non-Unix-like environment. +.P +The complete list of options for \fBconfigure\fP (which includes the standard +ones such as the selection of the installation directory) can be obtained by +running +.sp + ./configure --help +.sp +The following sections include descriptions of options whose names begin with +--enable or --disable. These settings specify changes to the defaults for the +\fBconfigure\fP command. Because of the way that \fBconfigure\fP works, +--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. +. +. +.SH "BUILDING 8-BIT, 16-BIT AND 32-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. You can also build a separate +library, called \fBlibpcre32\fP, in which strings are contained in vectors of +32-bit data units and interpreted either as single-unit characters or UTF-32 +strings, by adding +.sp + --enable-pcre32 +.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 three 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 or +32-bit libraries. +. +. +.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, 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, UTF-16 AND UTF-32 SUPPORT" +.rs +.sp +To build PCRE with support for UTF Unicode character strings, add +.sp + --enable-utf +.sp +to the \fBconfigure\fP command. This setting applies to all three libraries, +adding support for UTF-8 to the 8-bit library, support for UTF-16 to the 16-bit +library, and support for UTF-32 to the to the 32-bit library. There are no +separate options for enabling UTF-8, UTF-16 and UTF-32 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 another 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, UTF-16 or +UTF-32. As well as compiling PCRE with this option, you also have have to set +the PCRE_UTF8, PCRE_UTF16 or PCRE_UTF32 option (as appropriate) when you call +one of the pattern compiling functions. +.P +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. +. +. +.SH "UNICODE CHARACTER PROPERTY SUPPORT" +.rs +.sp +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 support, even if you have +not explicitly requested it. +.P +Including Unicode property support adds around 30K of tables to the PCRE +library. Only the general category properties such as \fILu\fP and \fINd\fP are +supported. Details are given in the +.\" HREF +\fBpcrepattern\fP +.\" +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 +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 +compile PCRE to use carriage return (CR) instead, by adding +.sp + --enable-newline-is-cr +.sp +to the \fBconfigure\fP command. There is also a --enable-newline-is-lf option, +which explicitly specifies linefeed as the newline character. +.sp +Alternatively, you can specify that line endings are to be indicated by the two +character sequence CRLF. If you want this, add +.sp + --enable-newline-is-crlf +.sp +to the \fBconfigure\fP command. There is a fourth option, specified by +.sp + --enable-newline-is-anycrlf +.sp +which causes PCRE to recognize any of the three sequences CR, LF, or CRLF as +indicating a line ending. Finally, a fifth option, specified by +.sp + --enable-newline-is-any +.sp +causes PCRE to recognize any Unicode newline sequence. +.P +Whatever line ending convention is selected when PCRE is built can be +overridden when the library functions are called. At build time it is +conventional to use the standard for your operating system. +. +. +.SH "WHAT \eR MATCHES" +.rs +.sp +By default, the sequence \eR in a pattern matches any Unicode newline sequence, +whatever has been selected as the line ending sequence. If you specify +.sp + --enable-bsr-anycrlf +.sp +the default is changed so that \eR matches only CR, LF, or CRLF. Whatever is +selected when PCRE is built can be overridden when the library functions are +called. +. +. +.SH "POSIX MALLOC USAGE" +.rs +.sp +When the 8-bit library is called through the POSIX interface (see the +.\" HREF +\fBpcreposix\fP +.\" +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 function uses space on the stack, because this +is faster than using \fBmalloc()\fP 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 +.sp + --with-posix-malloc-threshold=20 +.sp +to the \fBconfigure\fP command. +. +. +.SH "HANDLING VERY LARGE PATTERNS" +.rs +.sp +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, in the 8-bit and 16-bit libraries, 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 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. For the +16-bit library, a value of 3 is rounded up to 4. In these libraries, using +longer offsets slows down the operation of PCRE because it has to load +additional data when handling them. For the 32-bit library the value is always +4 and cannot be overridden; the value of --with-link-size is ignored. +. +. +.SH "AVOIDING EXCESSIVE STACK USAGE" +.rs +.sp +When matching with the \fBpcre_exec()\fP function, PCRE implements backtracking +by making recursive calls to an internal function called \fBmatch()\fP. In +environments where the size of the stack is limited, this can severely 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 +.\" HREF +\fBpcrestack\fP +.\" +documentation.) 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 +.sp + --disable-stack-for-recursion +.sp +to the \fBconfigure\fP command. With this configuration, PCRE will use the +\fBpcre_stack_malloc\fP and \fBpcre_stack_free\fP variables to call memory +management functions. By default these point to \fBmalloc()\fP and +\fBfree()\fP, but you can replace the pointers so that your own functions are +used instead. +.P +Separate functions are provided rather than using \fBpcre_malloc\fP and +\fBpcre_free\fP 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 \fBmalloc()\fP and \fBfree()\fP. PCRE runs noticeably more +slowly when built in this way. This option affects only the \fBpcre_exec()\fP +function; it is not relevant for \fBpcre_dfa_exec()\fP. +. +. +.SH "LIMITING PCRE RESOURCE USAGE" +.rs +.sp +Internally, PCRE has a function called \fBmatch()\fP, which it calls repeatedly +(sometimes recursively) when matching a pattern with the \fBpcre_exec()\fP +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 \fBpcre_exec()\fP. The limit can be changed +at run time, as described in the +.\" HREF +\fBpcreapi\fP +.\" +documentation. The default is 10 million, but this can be changed by adding a +setting such as +.sp + --with-match-limit=500000 +.sp +to the \fBconfigure\fP command. This setting has no effect on the +\fBpcre_dfa_exec()\fP matching function. +.P +In some environments it is desirable to limit the depth of recursive calls of +\fBmatch()\fP more strictly than the total number of calls, in order 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 by adding, for example, +.sp + --with-match-limit-recursion=10000 +.sp +to the \fBconfigure\fP command. This value can also be overridden at run time. +. +. +.SH "CREATING CHARACTER TABLES AT BUILD TIME" +.rs +.sp +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 \fIpcre_chartables.c.dist\fP. These tables are for ASCII codes +only. If you add +.sp + --enable-rebuild-chartables +.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 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 +hand".) +. +. +.SH "USING EBCDIC CODE" +.rs +.sp +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, however, be compiled to run in an +EBCDIC environment by adding +.sp + --enable-ebcdic +.sp +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-utf. +.P +The EBCDIC character that corresponds to an ASCII LF is assumed to have the +value 0x15 by default. However, in some EBCDIC environments, 0x25 is used. In +such an environment you should use +.sp + --enable-ebcdic-nl25 +.sp +as well as, or instead of, --enable-ebcdic. The EBCDIC character for CR has the +same value as in ASCII, namely, 0x0d. Whichever of 0x15 and 0x25 is \fInot\fP +chosen as LF is made to correspond to the Unicode NEL character (which, in +Unicode, is 0x85). +.P +The options that select newline behaviour, such as --enable-newline-is-cr, +and equivalent run-time options, refer to these character values in an EBCDIC +environment. +. +. +.SH "PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT" +.rs +.sp +By default, \fBpcregrep\fP reads all files as plain text. You can build it so +that it recognizes files whose names end in \fB.gz\fP or \fB.bz2\fP, and reads +them with \fBlibz\fP or \fBlibbz2\fP, respectively, by adding one or both of +.sp + --enable-pcregrep-libz + --enable-pcregrep-libbz2 +.sp +to the \fBconfigure\fP command. These options naturally require that the +relevant libraries are installed on your system. Configuration will fail if +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 +If you add +.sp + --enable-pcretest-libreadline +.sp +to the \fBconfigure\fP command, \fBpcretest\fP is linked with the +\fBlibreadline\fP library, and when its input is from a terminal, it reads it +using the \fBreadline()\fP function. This provides line-editing and history +facilities. Note that \fBlibreadline\fP is GPL-licensed, so if you distribute a +binary of \fBpcretest\fP linked in this way, there may be licensing issues. +.P +Setting this option causes the \fB-lreadline\fP option to be added to the +\fBpcretest\fP build. In many operating environments with a sytem-installed +\fBlibreadline\fP this is sufficient. However, in some environments (e.g. +if an unmodified distribution version of readline is in use), some extra +configuration may be necessary. The INSTALL file for \fBlibreadline\fP says +this: +.sp + "Readline uses the termcap functions, but does not link with the + termcap or curses library itself, allowing applications which link + with readline the to choose an appropriate library." +.sp +If your environment has not been set up so that an appropriate library is +automatically included, you may need to add something like +.sp + LIBS="-ncurses" +.sp +immediately before the \fBconfigure\fP command. +. +. +.SH "DEBUGGING WITH VALGRIND SUPPORT" +.rs +.sp +By adding the +.sp + --enable-valgrind +.sp +option to to the \fBconfigure\fP command, PCRE will use valgrind annotations +to mark certain memory regions as unaddressable. This allows it to detect +invalid memory accesses, and is mostly useful for debugging PCRE itself. +. +. +.SH "CODE COVERAGE REPORTING" +.rs +.sp +If your C compiler is gcc, you can build a version of PCRE that can generate a +code coverage report for its test suite. To enable this, you must install +\fBlcov\fP version 1.6 or above. Then specify +.sp + --enable-coverage +.sp +to the \fBconfigure\fP command and build PCRE in the usual way. +.P +Note that using \fBccache\fP (a caching C compiler) is incompatible with code +coverage reporting. If you have configured \fBccache\fP to run automatically +on your system, you must set the environment variable +.sp + CCACHE_DISABLE=1 +.sp +before running \fBmake\fP to build PCRE, so that \fBccache\fP is not used. +.P +When --enable-coverage is used, the following addition targets are added to the +\fIMakefile\fP: +.sp + make coverage +.sp +This creates a fresh coverage report for the PCRE test suite. It is equivalent +to running "make coverage-reset", "make coverage-baseline", "make check", and +then "make coverage-report". +.sp + make coverage-reset +.sp +This zeroes the coverage counters, but does nothing else. +.sp + make coverage-baseline +.sp +This captures baseline coverage information. +.sp + make coverage-report +.sp +This creates the coverage report. +.sp + make coverage-clean-report +.sp +This removes the generated coverage report without cleaning the coverage data +itself. +.sp + make coverage-clean-data +.sp +This removes the captured coverage data without removing the coverage files +created at compile time (*.gcno). +.sp + make coverage-clean +.sp +This cleans all coverage data including the generated coverage report. For more +information about code coverage, see the \fBgcov\fP and \fBlcov\fP +documentation. +. +. +.SH "SEE ALSO" +.rs +.sp +\fBpcreapi\fP(3), \fBpcre16\fP, \fBpcre32\fP, \fBpcre_config\fP(3). +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 30 October 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcrecallout.3 b/tools/pcre/doc/pcrecallout.3 new file mode 100644 index 00000000..5681335c --- /dev/null +++ b/tools/pcre/doc/pcrecallout.3 @@ -0,0 +1,214 @@ +.TH PCRECALLOUT 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int (*pcre_callout)(pcre_callout_block *); +.PP +.B int (*pcre16_callout)(pcre16_callout_block *); +.PP +.B int (*pcre32_callout)(pcre32_callout_block *); +. +.SH DESCRIPTION +.rs +.sp +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 (\fIpcre16_callout\fP for the 16-bit +library, \fIpcre32_callout\fP for the 32-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 +a number less than 256 after the letter C. The default value is zero. +For example, this pattern has two callout points: +.sp + (?C1)abc(?C2)def +.sp +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 +it is processed as if it were +.sp +(?C255)A(?C255)((?C255)\ed{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255) +.sp +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 +.\" HREF +\fBpcretest\fP +.\" +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" +.rs +.sp +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 +.sp + ab(?C4)cd +.sp +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", though the result is still +no match, the callout is obeyed. +.P +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. +.P +You can disable these optimizations by passing the PCRE_NO_START_OPTIMIZE +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 or \fIpcre[16|32]_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 \fBpcre[16|32]_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) + PCRE_SPTR32 \fIsubject\fP; (32-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) + const PCRE_UCHAR32 *\fImark\fP; (32-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 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 +The \fIcallout_number\fP field contains the number of the callout, as compiled +into the pattern (that is, the number after ?C for manual callouts, and 255 for +automatically generated callouts). +.P +The \fIoffset_vector\fP field is a pointer to the vector of offsets that was +passed by the caller to the matching function. When \fBpcre_exec()\fP or +\fBpcre[16|32]_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 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 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 +has been encountered, this value is changed to reflect the modified starting +point. If the pattern is not anchored, the callout function may be called +several times from the same point in the pattern for different starting points +in the subject. +.P +The \fIcurrent_position\fP field contains the offset within the subject of the +current match pointer. +.P +When the \fBpcre_exec()\fP or \fBpcre[16|32]_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 for the DFA matching functions. +.P +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 \fBpcre[16|32]_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 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 \fBpcre[16|32]_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" +.rs +.sp +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, 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. +The error number PCRE_ERROR_CALLOUT is reserved for use by callout functions; +it will never be used by PCRE itself. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 24 June 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcrecompat.3 b/tools/pcre/doc/pcrecompat.3 new file mode 100644 index 00000000..f24823f8 --- /dev/null +++ b/tools/pcre/doc/pcrecompat.3 @@ -0,0 +1,185 @@ +.TH PCRECOMPAT 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH "DIFFERENCES BETWEEN PCRE AND PERL" +.rs +.sp +This document describes the differences in the ways that PCRE and Perl handle +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 Unicode support. Details of what it does +have are given in the +.\" HREF +\fBpcreunicode\fP +.\" +page. +.P +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 +numerical variables from any such patterns that are matched before the +assertion fails to match something (thereby succeeding), but only if the +negative lookahead assertion contains just one branch. +.P +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 normal C string, +terminated by zero. The escape sequence \e0 can be used in the pattern to +represent a binary zero. +.P +5. The following Perl escape sequences are not supported: \el, \eu, \eL, +\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 +tested with \ep and \eP are limited to the general category properties 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 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 +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 +following examples: +.sp + Pattern PCRE matches Perl matches +.sp +.\" JOIN + \eQabc$xyz\eE abc$xyz abc followed by the + contents of $xyz + \eQabc\e$xyz\eE abc\e$xyz abc\e$xyz + \eQabc\eE\e$\eQxyz\eE abc$xyz abc$xyz +.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}) +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 +the +.\" HREF +\fBpcrecallout\fP +.\" +documentation for details. +.P +9. 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 +.\" +in the +.\" HREF +\fBpcrepattern\fP +.\" +page. +.P +10. If any of the backtracking control verbs are used in an assertion or in a +subpattern that is called as a subroutine (whether or not recursively), their +effect is confined to that subpattern; it does not extend to the surrounding +pattern. This is not always the case in Perl. In particular, if (*THEN) is +present in a group that is called as a subroutine, its action is limited to +that group, even if the group does not contain any | characters. There is one +exception to this: the name from a *(MARK), (*PRUNE), or (*THEN) that is +encountered in a 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 +11. 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 +12. 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)|(? +. +.SH DESCRIPTION +.rs +.sp +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 \fIpcrecpp.h\fP file, which should be consulted for +further details. Note that the C++ wrapper supports only the original 8-bit +PCRE library. There is no 16-bit or 32-bit support at present. +. +. +.SH "MATCHING INTERFACE" +.rs +.sp +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. +.sp + Example: successful match + pcrecpp::RE re("h.*o"); + re.FullMatch("hello"); +.sp + Example: unsuccessful match (requires full match): + pcrecpp::RE re("e"); + !re.FullMatch("hello"); +.sp + Example: creating a temporary RE object: + pcrecpp::RE("h.*o").FullMatch("hello"); +.sp +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. +.P +You must supply extra pointer arguments to extract matched subpieces. +.sp + Example: extracts "ruby" into "s" and 1234 into "i" + int i; + string s; + pcrecpp::RE re("(\e\ew+):(\e\ed+)"); + re.FullMatch("ruby:1234", &s, &i); +.sp + Example: does not try to extract any extra sub-patterns + re.FullMatch("ruby:1234", &s); +.sp + Example: does not try to extract into NULL + re.FullMatch("ruby:1234", NULL, &i); +.sp + Example: integer overflow causes failure + !re.FullMatch("ruby:1234567891234", NULL, &i); +.sp + Example: fails because there aren't enough sub-patterns: + !pcrecpp::RE("\e\ew+:\e\ed+").FullMatch("ruby:1234", &s); +.sp + Example: fails because string cannot be stored in integer + !pcrecpp::RE("(.*)").FullMatch("ruby", &i); +.sp +The provided pointer arguments can be pointers to any scalar numeric +type, or one of: +.sp + string (matched piece is copied to string) + StringPiece (StringPiece is mutated to point to matched piece) + T (where "bool T::ParseFrom(const char*, int)" exists) + NULL (the corresponding matched sub-pattern is not copied) +.sp +The function returns true iff all of the following conditions are satisfied: +.sp + a. "text" matches "pattern" exactly; +.sp + b. The number of matched sub-patterns is >= number of supplied + pointers; +.sp + c. The "i"th argument has a suitable type for holding the + string captured as the "i"th sub-pattern. If you pass in + void * NULL for the "i"th argument, or a non-void * NULL + of the correct type, or pass fewer arguments than the + number of sub-patterns, "i"th captured sub-pattern is + ignored. +.sp +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): +.sp + int number; + pcrecpp::RE::FullMatch("abc", "[a-z]+(\e\ed+)?", &number); +.sp +The matching interface supports at most 16 arguments per call. +If you need more, consider using the more general interface +\fBpcrecpp::RE::DoMatch\fP. See \fBpcrecpp.h\fP for the signature for +\fBDoMatch\fP. +.P +NOTE: Do not use \fBno_arg\fP, 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. +. +. +.SH "QUOTING METACHARACTERS" +.rs +.sp +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. +.sp + Example: + string quoted = RE::QuoteMeta(unquoted); +.sp +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\e.5\e-2\e.0\e?". +. +.SH "PARTIAL MATCHES" +.rs +.sp +You can use the "PartialMatch" operation when you want the pattern +to match any substring of the text. +.sp + Example: simple search for a string: + pcrecpp::RE("ell").PartialMatch("hello"); +.sp + Example: find first number in a string: + int number; + pcrecpp::RE re("(\e\ed+)"); + re.PartialMatch("x*100 + 20", &number); + assert(number == 100); +. +. +.SH "UTF-8 AND THE MATCHING INTERFACE" +.rs +.sp +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 of a multi-byte character. +.sp + Example: + pcrecpp::RE_Options options; + options.set_utf8(); + pcrecpp::RE re(utf8_pattern, options); + re.FullMatch(utf8_string); +.sp + Example: using the convenience function UTF8(): + pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8()); + re.FullMatch(utf8_string); +.sp +NOTE: The UTF8 flag is ignored if pcre was not configured with the + --enable-utf8 flag. +. +. +.SH "PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE" +.rs +.sp +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. Currently, the following modifiers are +supported: +.sp + modifier description Perl corresponding +.sp + PCRE_CASELESS case insensitive match /i + PCRE_MULTILINE multiple lines match /m + 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 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 (*) +.sp +(*) Both Perl and PCRE allow non capturing parentheses by means of the +"?:" modifier within the pattern itself. e.g. (?:ab|cd) does not +capture, while (ab|cd) does. +.P +For a full account on how each modifier works, please check the +PCRE API reference page. +.P +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 +.sp + bool caseless() +.sp +which returns true if the modifier is set, and +.sp + RE_Options & set_caseless(bool) +.sp +which sets or unsets the modifier. Moreover, PCRE_EXTRA_MATCH_LIMIT can be +accessed through the \fBset_match_limit()\fP and \fBmatch_limit()\fP member +functions. Setting \fImatch_limit\fP to a non-zero value will limit the +execution 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 \fImatch_limit\fP to zero disables +match limiting. Alternatively, you can call \fBmatch_limit_recursion()\fP +which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to limit how much PCRE +recurses. \fBmatch_limit()\fP limits the number of matches PCRE does; +\fBmatch_limit_recursion()\fP limits the depth of internal recursion, and +therefore the amount of stack that is used. +.P +Normally, to pass one or more modifiers to a RE class, you declare +a \fIRE_Options\fP object, set the appropriate options, and pass this +object to a RE constructor. Example: +.sp + RE_Options opt; + opt.set_caseless(true); + if (RE("HELLO", opt).PartialMatch("hello world")) ... +.sp +RE_options has two constructors. The default constructor takes no arguments and +creates a set of flags that are off by default. The optional parameter +\fIoption_flags\fP is to facilitate transfer of legacy code from C programs. +This lets you do +.sp + RE(pattern, + RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); +.sp +However, new code is better off doing +.sp + RE(pattern, + RE_Options().set_caseless(true).set_multiline(true)) + .PartialMatch(str); +.sp +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 +appropriate modifier already set: \fBCASELESS()\fP, \fBUTF8()\fP, +\fBMULTILINE()\fP, \fBDOTALL\fP(), and \fBEXTENDED()\fP. +.P +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 \fBset_xxxxx()\fP 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: +.sp + RE(" ^ xyz \e\es+ .* blah$", + RE_Options() + .set_caseless(true) + .set_extended(true) + .set_multiline(true)).PartialMatch(sometext); +.sp +. +. +.SH "SCANNING TEXT INCREMENTALLY" +.rs +.sp +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 pcrecpp namespace. +.sp + Example: read lines of the form "var = value" from a string. + string contents = ...; // Fill string somehow + pcrecpp::StringPiece input(contents); // Wrap in a StringPiece +.sp + string var; + int value; + pcrecpp::RE re("(\e\ew+) = (\e\ed+)\en"); + while (re.Consume(&input, &var, &value)) { + ...; + } +.sp +Each successful call to "Consume" will set "var/value", and also +advance "input" so it points past the matched text. +.P +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 +.sp + pcrecpp::RE("(\e\ew+)").FindAndConsume(&input, &word) +. +. +.SH "PARSING HEX/OCTAL/C-RADIX NUMBERS" +.rs +.sp +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 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 base-10. +.sp + Example: + int a, b, c, d; + pcrecpp::RE re("(.*) (.*) (.*) (.*)"); + re.FullMatch("100 40 0100 0x40", + pcrecpp::Octal(&a), pcrecpp::Hex(&b), + pcrecpp::CRadix(&c), pcrecpp::CRadix(&d)); +.sp +will leave 64 in a, b, c, and d. +. +. +.SH "REPLACING PARTS OF STRINGS" +.rs +.sp +You can replace the first match of "pattern" in "str" with "rewrite". +Within "rewrite", backslash-escaped digits (\e1 to \e9) can be +used to insert text matching corresponding parenthesized group +from the pattern. \e0 in "rewrite" refers to the entire matching +text. For example: +.sp + string s = "yabba dabba doo"; + pcrecpp::RE("b+").Replace("d", &s); +.sp +will leave "s" containing "yada dabba doo". The result is true if the pattern +matches and a replacement occurs, false otherwise. +.P +\fBGlobalReplace\fP is like \fBReplace\fP except that it replaces all +occurrences of the pattern in the string with the rewrite. Replacements are +not subject to re-matching. For example: +.sp + string s = "yabba dabba doo"; + pcrecpp::RE("b+").GlobalReplace("d", &s); +.sp +will leave "s" containing "yada dada doo". It returns the number of +replacements made. +.P +\fBExtract\fP is like \fBReplace\fP, 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. +. +. +.SH AUTHOR +.rs +.sp +.nf +The C++ wrapper was contributed by Google Inc. +Copyright (c) 2007 Google Inc. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 08 January 2012 +.fi diff --git a/tools/pcre/doc/pcregrep.1 b/tools/pcre/doc/pcregrep.1 new file mode 100644 index 00000000..7fa5b65e --- /dev/null +++ b/tools/pcre/doc/pcregrep.1 @@ -0,0 +1,679 @@ +.TH PCREGREP 1 "13 September 2012" "PCRE 8.32" +.SH NAME +pcregrep - a grep with Perl-compatible regular expressions. +.SH SYNOPSIS +.B pcregrep [options] [long options] [pattern] [path1 path2 ...] +. +.SH DESCRIPTION +.rs +.sp +\fBpcregrep\fP searches files for character patterns, in the same way as other +grep commands do, but it uses the PCRE regular expression library to support +patterns that are compatible with the regular expressions of Perl 5. See +.\" HREF +\fBpcrepattern\fP(3) +.\" +for a full description of syntax and semantics of the regular expressions +that PCRE supports. +.P +Patterns, whether supplied on the command line or in a separate file, are given +without delimiters. For example: +.sp + pcregrep Thursday /etc/motd +.sp +If you attempt to use delimiters (for example, by surrounding a pattern with +slashes, as is common in Perl scripts), they are interpreted as part of the +pattern. Quotes can of course be used to delimit patterns on the command line +because they are interpreted by the shell, and indeed quotes are required if a +pattern contains white space or shell metacharacters. +.P +The first argument that follows any option settings is treated as the single +pattern to be matched when neither \fB-e\fP nor \fB-f\fP is present. +Conversely, when one or both of these options are used to specify patterns, all +arguments are treated as path names. At least one of \fB-e\fP, \fB-f\fP, or an +argument pattern must be provided. +.P +If no files are specified, \fBpcregrep\fP reads the standard input. The +standard input can also be referenced by a name consisting of a single hyphen. +For example: +.sp + pcregrep some-pattern /file1 - /file3 +.sp +By default, each line that matches a pattern is copied to the standard +output, and if there is more than one file, the file name is output at the +start of each line, followed by a colon. However, there are options that can +change how \fBpcregrep\fP behaves. In particular, the \fB-M\fP option makes it +possible to search for patterns that span line boundaries. What defines a line +boundary is controlled by the \fB-N\fP (\fB--newline\fP) option. +.P +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 can be no longer than 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 a line, no further patterns are +considered. However, if \fB--colour\fP (or \fB--color\fP) is used to colour the +matching substrings, or if \fB--only-matching\fP, \fB--file-offsets\fP, or +\fB--line-offsets\fP 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 follow the one that matched are not tried on the earlier part +of the line. +.P +This behaviour means that the order in which multiple patterns are specified +can affect the output when one of the above options is used. This is no longer +the same behaviour as GNU grep, which now manages to display earlier matches +for later patterns (as long as there is no overlap). +.P +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 being shown. +.P +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. +. +. +.SH "SUPPORT FOR COMPRESSED FILES" +.rs +.sp +It is possible to compile \fBpcregrep\fP so that it uses \fBlibz\fP or +\fBlibbz2\fP to read files whose names end in \fB.gz\fP or \fB.bz2\fP, +respectively. You can find out whether your binary has support for one or both +of these file types by running it with the \fB--help\fP option. If the +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. Similarly, except where noted below, if an option is given twice, the +later setting is used. 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 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 +\fB-A\fP \fInumber\fP, \fB--after-context=\fP\fInumber\fP +Output \fInumber\fP lines of context after each matching line. If filenames +and/or line numbers are being output, a hyphen separator 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 \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 +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 \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. +.TP +\fB-c\fP, \fB--count\fP +Do not output individual lines from the files that are being scanned; instead +output the number of lines that would otherwise have been shown. If no lines +are selected, the number zero is output. If several files are are being +scanned, a count is output for each of them. However, if the +\fB--files-with-matches\fP option is also used, only those files whose counts +are greater than zero are listed. When \fB-c\fP is used, the \fB-A\fP, +\fB-B\fP, and \fB-C\fP options are ignored. +.TP +\fB--colour\fP, \fB--color\fP +If this option is given without any data, it is equivalent to "--colour=auto". +If data is required, it must be given in the same shell item, separated by an +equals sign. +.TP +\fB--colour=\fP\fIvalue\fP, \fB--color=\fP\fIvalue\fP +This option specifies under what circumstances the parts of a line that matched +a pattern should be coloured in the output. By default, the output is not +coloured. The value (which is optional, see above) may be "never", "always", or +"auto". In the latter case, colouring happens only if the standard output is +connected to a terminal. More resources are used when colouring is enabled, +because \fBpcregrep\fP has to search for all possible matches in a line, not +just one, in order to colour them all. +.sp +The colour that is used can be specified by setting the environment variable +PCREGREP_COLOUR or PCREGREP_COLOR. The value of this variable should be a +string of two numbers, separated by a semicolon. They are copied directly into +the control string for setting colour on a terminal, so it is your +responsibility to ensure that they make sense. If neither of the environment +variables is set, the default is "1;31", which gives red. +.TP +\fB-D\fP \fIaction\fP, \fB--devices=\fP\fIaction\fP +If an input path is not a regular file or a directory, "action" specifies how +it is to be processed. Valid values are "read" (the default) or "skip" +(silently skip the path). +.TP +\fB-d\fP \fIaction\fP, \fB--directories=\fP\fIaction\fP +If an input path is a directory, "action" specifies how it is to be processed. +Valid values are "read" (the default in non-Windows environments, for +compatibility with GNU grep), "recurse" (equivalent to the \fB-r\fP option), or +"skip" (silently skip the path, the default in Windows environments). In the +"read" case, directories are read as if they were ordinary files. In some +operating systems the effect of reading a directory like this is an immediate +end-of-file; in others it may provoke an error. +.TP +\fB-e\fP \fIpattern\fP, \fB--regex=\fP\fIpattern\fP, \fB--regexp=\fP\fIpattern\fP +Specify a pattern to be matched. This option can be used multiple times in +order to specify several patterns. It can also be used as a way of specifying a +single pattern that starts with a hyphen. When \fB-e\fP is used, no argument +pattern is taken from the command line; all arguments are treated as file +names. There is no limit to the number of patterns. They are applied to each +line in the order in which they are defined until one matches. +.sp +If \fB-f\fP is used with \fB-e\fP, the command line patterns are matched first, +followed by the patterns from the file(s), independent of the order in which +these options are specified. Note that multiple use of \fB-e\fP is not the same +as a single pattern with alternatives. For example, X|Y finds the first +character in a line that is X or Y, whereas if the two patterns are given +separately, with X first, \fBpcregrep\fP finds X if it is present, even if it +follows Y in the line. It finds Y only if there is no X in the line. This +matters only if you are using \fB-o\fP or \fB--colo(u)r\fP to show the part(s) +of the line that matched. +.TP +\fB--exclude\fP=\fIpattern\fP +Files (but not directories) whose names match the pattern are skipped without +being processed. This applies to all files, whether listed on the command line, +obtained from \fB--file-list\fP, or by scanning a directory. The pattern is a +PCRE regular expression, and is matched against the final component of the file +name, not the entire path. The \fB-F\fP, \fB-w\fP, and \fB-x\fP options do not +apply to this pattern. The option may be given any number of times in order to +specify multiple patterns. If a file name matches both an \fB--include\fP +and an \fB--exclude\fP pattern, it is excluded. There is no short form for this +option. +.TP +\fB--exclude-from=\fP\fIfilename\fP +Treat each non-empty line of the file as the data for an \fB--exclude\fP +option. What constitutes a newline when reading the file is the operating +system's default. The \fB--newline\fP option has no effect on this option. This +option may be given more than once in order to specify a number of files to +read. +.TP +\fB--exclude-dir\fP=\fIpattern\fP +Directories whose names match the pattern are skipped without being processed, +whatever the setting of the \fB--recursive\fP option. This applies to all +directories, whether listed on the command line, obtained from +\fB--file-list\fP, or by scanning a parent directory. The pattern is a PCRE +regular expression, and is matched against the final component of the directory +name, not the entire path. The \fB-F\fP, \fB-w\fP, and \fB-x\fP options do not +apply to this pattern. The option may be given any number of times in order to +specify more than one pattern. If a directory matches both \fB--include-dir\fP +and \fB--exclude-dir\fP, it is excluded. There is no short form for this +option. +.TP +\fB-F\fP, \fB--fixed-strings\fP +Interpret each data-matching pattern as a list of fixed strings, separated by +newlines, instead of as a regular expression. What constitutes a newline for +this purpose is controlled by the \fB--newline\fP option. The \fB-w\fP (match +as a word) and \fB-x\fP (match whole line) options can be used with \fB-F\fP. +They apply to each of the fixed strings. A line is selected if any of the fixed +strings are found in it (subject to \fB-w\fP or \fB-x\fP, if present). This +option applies only to the patterns that are matched against the contents of +files; it does not apply to patterns specified by any of the \fB--include\fP or +\fB--exclude\fP options. +.TP +\fB-f\fP \fIfilename\fP, \fB--file=\fP\fIfilename\fP +Read patterns from the file, one per line, and match them against +each line of input. What constitutes a newline when reading the file is the +operating system's default. The \fB--newline\fP option has no effect on this +option. 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. +.sp +If this option is given more than once, all the specified files are +read. A data line is output if any of the patterns match it. A 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 the names of paths to be searched. +.TP +\fB--file-list\fP=\fIfilename\fP +Read a list of files and/or directories that are to be scanned from the given +file, one per line. Trailing white space is removed from each line, and blank +lines are ignored. These paths are processed before any that are 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. If this option is given more than once, all the specified files are +read. +.TP +\fB--file-offsets\fP +Instead of showing lines or parts of lines that match, show each match as an +offset from the start of the file and a length, separated by a comma. In this +mode, no context is shown. That is, the \fB-A\fP, \fB-B\fP, and \fB-C\fP +options are ignored. If there is more than one match in a line, each of them is +shown separately. This option is mutually exclusive with \fB--line-offsets\fP +and \fB--only-matching\fP. +.TP +\fB-H\fP, \fB--with-filename\fP +Force the inclusion of the filename at the start of output lines when searching +a single file. By default, the filename is not shown in this case. For matching +lines, the filename is followed by a colon; for context lines, a hyphen +separator is used. If a line number is also being output, it follows the file +name. +.TP +\fB-h\fP, \fB--no-filename\fP +Suppress the output filenames when searching multiple files. By default, +filenames are shown when multiple files are searched. For matching lines, the +filename is followed by a colon; for context lines, a hyphen separator is used. +If a line number is also being output, it follows the file name. +.TP +\fB--help\fP +Output a help message, giving brief details of the command options and file +type support, and then exit. Anything else on the command line is +ignored. +.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 +\fB--include\fP=\fIpattern\fP +If any \fB--include\fP patterns are specified, the only files that are +processed are those that match one of the patterns (and do not match an +\fB--exclude\fP pattern). This option does not affect directories, but it +applies to all files, whether listed on the command line, obtained from +\fB--file-list\fP, or by scanning a directory. The pattern is a PCRE regular +expression, and is matched against the final component of the file name, not +the entire path. The \fB-F\fP, \fB-w\fP, and \fB-x\fP options do not apply to +this pattern. The option may be given any number of times. If a file name +matches both an \fB--include\fP and an \fB--exclude\fP pattern, it is excluded. +There is no short form for this option. +.TP +\fB--include-from=\fP\fIfilename\fP +Treat each non-empty line of the file as the data for an \fB--include\fP +option. What constitutes a newline for this purpose is the operating system's +default. The \fB--newline\fP option has no effect on this option. This option +may be given any number of times; all the files are read. +.TP +\fB--include-dir\fP=\fIpattern\fP +If any \fB--include-dir\fP patterns are specified, the only directories that +are processed are those that match one of the patterns (and do not match an +\fB--exclude-dir\fP pattern). This applies to all directories, whether listed +on the command line, obtained from \fB--file-list\fP, or by scanning a parent +directory. The pattern is a PCRE regular expression, and is matched against the +final component of the directory name, not the entire path. The \fB-F\fP, +\fB-w\fP, and \fB-x\fP options do not apply to this pattern. The option may be +given any number of times. If a directory matches both \fB--include-dir\fP and +\fB--exclude-dir\fP, it is excluded. There is no short form for this option. +.TP +\fB-L\fP, \fB--files-without-match\fP +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 separate line. +.TP +\fB-l\fP, \fB--files-with-matches\fP +Instead of outputting lines from the files, just output the names of the files +containing lines that would have been output. 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 \fB-c\fP (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 \fB-c\fP is a way of suppressing the listing of files with no matches. +.TP +\fB--label\fP=\fIname\fP +This option supplies a name to be used for the standard input when file names +are being output. If not supplied, "(standard input)" is used. There is no +short form for this option. +.TP +\fB--line-buffered\fP +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 \fBpcregrep\fP can determine that it is reading from a terminal (which +is currently possible only in Unix-like environments). Output to terminal is +normally automatically flushed by the operating system. This option can be +useful when the input or output is attached to a pipe and you do not want +\fBpcregrep\fP to buffer up large amounts of data. However, its use will affect +performance, and the \fB-M\fP (multiline) option ceases to work. +.TP +\fB--line-offsets\fP +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 \fB-n\fP option), and the +offset and length are separated by a comma. In this mode, no context is shown. +That is, the \fB-A\fP, \fB-B\fP, and \fB-C\fP options are ignored. If there is +more than one match in a line, each of them is shown separately. This option is +mutually exclusive with \fB--file-offsets\fP and \fB--only-matching\fP. +.TP +\fB--locale\fP=\fIlocale-name\fP +This option specifies a locale to be used for pattern matching. It overrides +the value in the \fBLC_ALL\fP or \fBLC_CTYPE\fP environment 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. +.TP +\fB--match-limit\fP=\fInumber\fP +Processing some regular expression patterns can require a very large amount of +memory, leading in some cases to a program crash if not enough is available. +Other patterns may take a very long time to search for all possible matching +strings. The \fBpcre_exec()\fP function that is called by \fBpcregrep\fP to do +the matching has two parameters that can limit the resources that it uses. +.sp +The \fB--match-limit\fP 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 function +called \fBmatch()\fP which it calls repeatedly (sometimes recursively). The +limit set by \fB--match-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. +.sp +The \fB--recursion-limit\fP option is similar to \fB--match-limit\fP, but +instead of limiting the total number of times that \fBmatch()\fP 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, because not all calls to \fBmatch()\fP are recursive. This limit is +of use only if it is set smaller than \fB--match-limit\fP. +.sp +There are no short forms for these options. The default settings are specified +when the PCRE library is compiled, with the default default being 10 million. +.TP +\fB-M\fP, \fB--multiline\fP +Allow patterns to match more than one line. When this option is given, patterns +may usefully contain literal newline characters 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. +.sp +When this option is set, the PCRE library is called in "multiline" mode. +There is a limit to the number of lines that can be matched, imposed by the way +that \fBpcregrep\fP buffers the input file as it scans it. However, +\fBpcregrep\fP ensures that at least 8K characters or the rest of the document +(whichever is the shorter) are available for forward matching, and similarly +the previous 8K characters (or all the previous characters, 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 \fP--line-buffered\fP.) +.TP +\fB-N\fP \fInewline-type\fP, \fB--newline\fP=\fInewline-type\fP +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 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 +(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. +This is normally the standard sequence for the operating system. Unless +otherwise specified by this option, \fBpcregrep\fP uses the library's default. +The possible values for this option are CR, LF, CRLF, ANYCRLF, or ANY. This +makes it possible to use \fBpcregrep\fP to scan 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, +\fBpcregrep\fP may behave in strange ways. Note that this option does not +apply to files specified by the \fB-f\fP, \fB--exclude-from\fP, or +\fB--include-from\fP options, which are expected to use the operating system's +standard newline sequence. +.TP +\fB-n\fP, \fB--line-number\fP +Precede each output line by its line number in the file, followed 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 +\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 +\fB-C\fP options are ignored. If there is more than one match in a line, each +of them is shown separately. If \fB-o\fP is combined with \fB-v\fP (invert the +sense of the match to find non-matching lines), no output is generated, but the +return code is set appropriately. If the matched portion of the line is empty, +nothing is output unless the file name or line number are being printed, in +which case they are shown on an otherwise empty line. This option is mutually +exclusive with \fB--file-offsets\fP and \fB--line-offsets\fP. +.TP +\fB-o\fP\fInumber\fP, \fB--only-matching\fP=\fInumber\fP +Show only the part of the line that matched the capturing parentheses of the +given number. Up to 32 capturing parentheses are supported, and -o0 is +equivalent to \fB-o\fP without a number. Because these options can be given +without an argument (see above), if an argument is present, it must be given in +the same shell item, for example, -o3 or --only-matching=2. The comments given +for the non-argument case above also apply to this case. If the specified +capturing parentheses do not exist in the pattern, or were not set in the +match, nothing is output unless the file name or line number are being printed. +.sp +If this option is given multiple times, multiple substrings are output, in the +order the options are given. For example, -o3 -o1 -o3 causes the substrings +matched by capturing parentheses 3 and 1 and then 3 again to be output. By +default, there is no separator (but see the next option). +.TP +\fB--om-separator\fP=\fItext\fP +Specify a separating string for multiple occurrences of \fB-o\fP. The default +is an empty string. Separating strings are never coloured. +.TP +\fB-q\fP, \fB--quiet\fP +Work quietly, that is, display nothing except error messages. The exit +status indicates whether or not any matches were found. +.TP +\fB-r\fP, \fB--recursive\fP +If any given path is a directory, recursively scan the files it contains, +taking note of any \fB--include\fP and \fB--exclude\fP settings. By default, a +directory is read as a normal file; in some operating systems this gives an +immediate end-of-file. This option is a shorthand for setting the \fB-d\fP +option to "recurse". +.TP +\fB--recursion-limit\fP=\fInumber\fP +See \fB--match-limit\fP above. +.TP +\fB-s\fP, \fB--no-messages\fP +Suppress error messages about non-existent or unreadable files. Such files are +quietly skipped. However, the return code is still 2, even if matches were +found in other files. +.TP +\fB-u\fP, \fB--utf-8\fP +Operate in UTF-8 mode. This option is available only if PCRE has been compiled +with UTF-8 support. All patterns (including those for any \fB--exclude\fP and +\fB--include\fP options) and all subject lines that are scanned must be valid +strings of UTF-8 characters. +.TP +\fB-V\fP, \fB--version\fP +Write the version numbers of \fBpcregrep\fP and the PCRE library to the +standard output and then exit. Anything else on the command line is +ignored. +.TP +\fB-v\fP, \fB--invert-match\fP +Invert the sense of the match, so that lines which do \fInot\fP match any of +the patterns are the ones that are found. +.TP +\fB-w\fP, \fB--word-regex\fP, \fB--word-regexp\fP +Force the patterns to match only whole words. This is equivalent to having \eb +at the start and end of the pattern. This option applies only to the patterns +that are matched against the contents of files; it does not apply to patterns +specified by any of the \fB--include\fP or \fB--exclude\fP options. +.TP +\fB-x\fP, \fB--line-regex\fP, \fB--line-regexp\fP +Force the patterns to be anchored (each must start matching at the beginning of +a line) and in addition, require them to match entire lines. This is equivalent +to having ^ and $ characters at the start and end of each alternative branch in +every pattern. This option applies only to the patterns that are matched +against the contents of files; it does not apply to patterns specified by any +of the \fB--include\fP or \fB--exclude\fP options. +. +. +.SH "ENVIRONMENT VARIABLES" +.rs +.sp +The environment variables \fBLC_ALL\fP and \fBLC_CTYPE\fP are examined, in that +order, for a locale. The first one that is set is used. This can be overridden +by the \fB--locale\fP option. If no locale is set, the PCRE library's default +(usually the "C" locale) is used. +. +. +.SH "NEWLINES" +.rs +.sp +The \fB-N\fP (\fB--newline\fP) option allows \fBpcregrep\fP to scan files with +different newline conventions from the default. Any parts of the input files +that are written to the standard output are copied identically, with whatever +newline sequences they have in the input. However, the setting of this option +does not affect the interpretation of files specified by the \fB-f\fP, +\fB--exclude-from\fP, or \fB--include-from\fP options, which are assumed to use +the operating system's standard newline sequence, nor does it affect the way in +which \fBpcregrep\fP writes informational messages to the standard error and +output streams. For these it uses the string "\en" to indicate newlines, +relying on the C I/O library to convert this to an appropriate sequence. +. +. +.SH "OPTIONS COMPATIBILITY" +.rs +.sp +Many of the short and long forms of \fBpcregrep\fP's options are the same +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-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--om-separator\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 +for GNU \fBgrep\fP, but a regular expression for \fBpcregrep\fP. If both the +\fB-c\fP and \fB-l\fP options are given, GNU grep lists only file names, +without counts, but \fBpcregrep\fP gives the counts. +. +. +.SH "OPTIONS WITH DATA" +.rs +.sp +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 +exception) in the next command line item. For example: +.sp + -f/some/file + -f /some/file +.sp +The exception is the \fB-o\fP option, which may appear with or without data. +Because of this, if data is present, it must follow immediately in the same +item, for example -o3. +.P +If a long form option is used, the data may appear in the same command line +item, separated by an equals character, or (with two exceptions) it may appear +in the next command line item. For example: +.sp + --file=/some/file + --file /some/file +.sp +Note, however, that if you want to supply a file name beginning with ~ as data +in a shell command, and have the shell expand ~ to a home directory, you must +separate the file name from the option, because the shell does not treat ~ +specially unless it is at the start of an item. +.P +The exceptions to the above are the \fB--colour\fP (or \fB--color\fP) and +\fB--only-matching\fP options, for which the data is optional. If one of these +options does have data, it must be given in the first form, using an equals +character. Otherwise \fBpcregrep\fP will assume that it has no data. +. +. +.SH "MATCHING ERRORS" +.rs +.sp +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 +repeats, for example: (a+)*\ed when matched against a line of a's with no final +digit. The PCRE matching function has a resource limit that causes it to abort +in these circumstances. If this happens, \fBpcregrep\fP outputs an error +message and the line that caused the problem to the standard error stream. If +there are more than 20 such errors, \fBpcregrep\fP gives up. +.P +The \fB--match-limit\fP option of \fBpcregrep\fP can be used to set the overall +resource limit; there is a second option called \fB--recursion-limit\fP that +sets a limit on the amount of memory (usually stack) that is used (see the +discussion of these options above). +. +. +.SH DIAGNOSTICS +.rs +.sp +Exit status is 0 if any matches were found, 1 if no matches were found, 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 +\fB-s\fP option to suppress error messages about inaccessible files does not +affect the return code. +. +. +.SH "SEE ALSO" +.rs +.sp +\fBpcrepattern\fP(3), \fBpcresyntax\fP(3), \fBpcretest\fP(1). +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 13 September 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcregrep.txt b/tools/pcre/doc/pcregrep.txt new file mode 100644 index 00000000..0d5a12fb --- /dev/null +++ b/tools/pcre/doc/pcregrep.txt @@ -0,0 +1,740 @@ +PCREGREP(1) PCREGREP(1) + + +NAME + pcregrep - a grep with Perl-compatible regular expressions. + + +SYNOPSIS + pcregrep [options] [long options] [pattern] [path1 path2 ...] + + +DESCRIPTION + + pcregrep searches files for character patterns, in the same way as + other grep commands do, but it uses the PCRE regular expression library + to support patterns that are compatible with the regular expressions of + Perl 5. See pcrepattern(3) for a full description of syntax and seman- + tics of the regular expressions that PCRE supports. + + Patterns, whether supplied on the command line or in a separate file, + are given without delimiters. For example: + + pcregrep Thursday /etc/motd + + If you attempt to use delimiters (for example, by surrounding a pattern + with slashes, as is common in Perl scripts), they are interpreted as + part of the pattern. Quotes can of course be used to delimit patterns + on the command line because they are interpreted by the shell, and + indeed quotes are required if a pattern contains white space or shell + metacharacters. + + The first argument that follows any option settings is treated as the + single pattern to be matched when neither -e nor -f is present. Con- + versely, when one or both of these options are used to specify pat- + terns, all arguments are treated as path names. At least one of -e, -f, + or an argument pattern must be provided. + + If no files are specified, pcregrep reads the standard input. The stan- + dard input can also be referenced by a name consisting of a single + hyphen. For example: + + pcregrep some-pattern /file1 - /file3 + + By default, each line that matches a pattern is copied to the standard + output, and if there is more than one file, the file name is output at + the start of each line, followed by a colon. However, there are options + that can change how pcregrep behaves. In particular, the -M option + makes it possible to search for patterns that span line boundaries. + What defines a line boundary is controlled by the -N (--newline) + option. + + 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 can be no longer than 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 a line, no further patterns + are considered. However, if --colour (or --color) is used to colour the + matching substrings, or if --only-matching, --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 follow the one that matched + are not tried on the earlier part of the line. + + This behaviour means that the order in which multiple patterns are + specified can affect the output when one of the above options is used. + This is no longer the same behaviour as GNU grep, which now manages to + display earlier matches for later patterns (as long as there is no + overlap). + + 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 + 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 + 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 + 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 + 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. Similarly, except where noted below, if an option is + given twice, the later setting is used. Numerical values for options + may be followed by K or M, to signify multiplication by 1024 or + 1024*1024 respectively. + + -- 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. + + -A number, --after-context=number + Output number lines of context after 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, + 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 + 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, + 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 + to the same value. + + -c, --count + Do not output individual lines from the files that are being + scanned; instead output the number of lines that would other- + wise have been shown. If no lines are selected, the number + zero is output. If several files are are being scanned, a + count is output for each of them. However, if the --files- + with-matches option is also used, only those files whose + counts are greater than zero are listed. When -c is used, the + -A, -B, and -C options are ignored. + + --colour, --color + If this option is given without any data, it is equivalent to + "--colour=auto". If data is required, it must be given in + the same shell item, separated by an equals sign. + + --colour=value, --color=value + This option specifies under what circumstances the parts of a + line that matched a pattern should be coloured in the output. + By default, the output is not coloured. The value (which is + optional, see above) may be "never", "always", or "auto". In + the latter case, colouring happens only if the standard out- + put is connected to a terminal. More resources are used when + colouring is enabled, because pcregrep has to search for all + possible matches in a line, not just one, in order to colour + them all. + + The colour that is used can be specified by setting the envi- + ronment variable PCREGREP_COLOUR or PCREGREP_COLOR. The value + of this variable should be a string of two numbers, separated + by a semicolon. They are copied directly into the control + string for setting colour on a terminal, so it is your + responsibility to ensure that they make sense. If neither of + the environment variables is set, the default is "1;31", + which gives red. + + -D action, --devices=action + If an input path is not a regular file or a directory, + "action" specifies how it is to be processed. Valid values + are "read" (the default) or "skip" (silently skip the path). + + -d action, --directories=action + If an input path is a directory, "action" specifies how it is + to be processed. Valid values are "read" (the default in + non-Windows environments, for compatibility with GNU grep), + "recurse" (equivalent to the -r option), or "skip" (silently + skip the path, the default in Windows environments). In the + "read" case, directories are read as if they were ordinary + files. In some operating systems the effect of reading a + directory like this is an immediate end-of-file; in others it + may provoke an error. + + -e pattern, --regex=pattern, --regexp=pattern + Specify a pattern to be matched. This option can be used mul- + tiple times in order to specify several patterns. It can also + be used as a way of specifying a single pattern that starts + with a hyphen. When -e is used, no argument pattern is taken + from the command line; all arguments are treated as file + names. There is no limit to the number of patterns. They are + applied to each line in the order in which they are defined + until one matches. + + If -f is used with -e, the command line patterns are matched + first, followed by the patterns from the file(s), independent + of the order in which these options are specified. Note that + multiple use of -e is not the same as a single pattern with + alternatives. For example, X|Y finds the first character in a + line that is X or Y, whereas if the two patterns are given + separately, with X first, pcregrep finds X if it is present, + even if it follows Y in the line. It finds Y only if there is + no X in the line. This matters only if you are using -o or + --colo(u)r to show the part(s) of the line that matched. + + --exclude=pattern + Files (but not directories) whose names match the pattern are + skipped without being processed. This applies to all files, + whether listed on the command line, obtained from --file- + list, or by scanning a directory. The pattern is a PCRE regu- + lar expression, and is matched against the final component of + the file name, not the entire path. The -F, -w, and -x + options do not apply to this pattern. The option may be given + any number of times in order to specify multiple patterns. If + a file name matches both an --include and an --exclude pat- + tern, it is excluded. There is no short form for this option. + + --exclude-from=filename + Treat each non-empty line of the file as the data for an + --exclude option. What constitutes a newline when reading the + file is the operating system's default. The --newline option + has no effect on this option. This option may be given more + than once in order to specify a number of files to read. + + --exclude-dir=pattern + Directories whose names match the pattern are skipped without + being processed, whatever the setting of the --recursive + option. This applies to all directories, whether listed on + the command line, obtained from --file-list, or by scanning a + parent directory. The pattern is a PCRE regular expression, + and is matched against the final component of the directory + name, not the entire path. The -F, -w, and -x options do not + apply to this pattern. The option may be given any number of + times in order to specify more than one pattern. If a direc- + tory matches both --include-dir and --exclude-dir, it is + excluded. There is no short form for this option. + + -F, --fixed-strings + Interpret each data-matching pattern as a list of fixed + strings, separated by newlines, instead of as a regular + expression. What constitutes a newline for this purpose is + controlled by the --newline option. The -w (match as a word) + and -x (match whole line) options can be used with -F. They + apply to each of the fixed strings. A line is selected if any + of the fixed strings are found in it (subject to -w or -x, if + present). This option applies only to the patterns that are + matched against the contents of files; it does not apply to + patterns specified by any of the --include or --exclude + options. + + -f filename, --file=filename + Read patterns from the file, one per line, and match them + against each line of input. What constitutes a newline when + reading the file is the operating system's default. The + --newline option has no effect on this option. 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. + + If this option is given more than once, all the specified + files are read. A data line is output if any of the patterns + match it. A 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 the + names of paths to be searched. + + --file-list=filename + Read a list of files and/or directories that are to be + scanned from the given file, one per line. Trailing white + space is removed from each line, and blank lines are ignored. + These paths are processed before any that are listed on the + command line. The filename can be given as "-" to refer to + the standard input. If --file and --file-list are both spec- + ified 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. If this option is given more than once, all the + specified files are read. + + --file-offsets + Instead of showing lines or parts of lines that match, show + each match as an offset from the start of the file and a + length, 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 + separately. This option is mutually exclusive with --line- + offsets and --only-matching. + + -H, --with-filename + Force the inclusion of the filename at the start of output + lines when searching a single file. By default, the filename + is not shown in this case. For matching lines, the filename + is followed by a colon; for context lines, a hyphen separator + is used. If a line number is also being output, it follows + the file name. + + -h, --no-filename + Suppress the output filenames when searching multiple files. + By default, filenames are shown when multiple files are + searched. For matching lines, the filename is followed by a + colon; for context lines, a hyphen separator is used. If a + line number is also being output, it follows the file name. + + --help Output a help message, giving brief details of the command + options and file type support, and then exit. Anything else + on the command line is ignored. + + -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. + + --include=pattern + If any --include patterns are specified, the only files that + are processed are those that match one of the patterns (and + do not match an --exclude pattern). This option does not + affect directories, but it applies to all files, whether + listed on the command line, obtained from --file-list, or by + scanning a directory. The pattern is a PCRE regular expres- + sion, and is matched against the final component of the file + name, not the entire path. The -F, -w, and -x options do not + apply to this pattern. The option may be given any number of + times. If a file name matches both an --include and an + --exclude pattern, it is excluded. There is no short form + for this option. + + --include-from=filename + Treat each non-empty line of the file as the data for an + --include option. What constitutes a newline for this purpose + is the operating system's default. The --newline option has + no effect on this option. This option may be given any number + of times; all the files are read. + + --include-dir=pattern + If any --include-dir patterns are specified, the only direc- + tories that are processed are those that match one of the + patterns (and do not match an --exclude-dir pattern). This + applies to all directories, whether listed on the command + line, obtained from --file-list, or by scanning a parent + directory. The pattern is a PCRE regular expression, and is + matched against the final component of the directory name, + not the entire path. The -F, -w, and -x options do not apply + to this pattern. The option may be given any number of times. + If a directory 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- + rate line. + + -l, --files-with-matches + 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 + with their counts. Using this option with -c is a way of sup- + pressing the listing of files with no matches. + + --label=name + This option supplies a name to be used for the standard input + when file names are being output. If not supplied, "(standard + 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-like environments). Output to + terminal is normally automatically flushed by the operating + system. 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 + 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- + 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 + 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 + resources that it uses. + + 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 + 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, + 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 + the default default being 10 million. + + -M, --multiline + 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. + 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 + least 8K characters or the rest of the document (whichever is + 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 + 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- + 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 (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 for the operating system. Unless otherwise specified + 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 to scan files + that have come from other environments without having to mod- + ify their line endings. If the data that is being scanned + does not agree with the convention set by this option, pcre- + grep may behave in strange ways. Note that this option does + not apply to files specified by the -f, --exclude-from, or + --include-from options, which are expected to use the operat- + ing system's standard newline sequence. + + -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 + 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 + is, the -A, -B, and -C options are ignored. If there is more + than one match in a line, each of them is shown separately. + If -o is combined with -v (invert the sense of the match to + find non-matching lines), no output is generated, but the + return code is set appropriately. If the matched portion of + the line is empty, nothing is output unless the file name or + line number are being printed, in which case they are shown + on an otherwise empty line. This option is mutually exclusive + with --file-offsets and --line-offsets. + + -onumber, --only-matching=number + Show only the part of the line that matched the capturing + parentheses of the given number. Up to 32 capturing parenthe- + ses are supported, and -o0 is equivalent to -o without a num- + ber. Because these options can be given without an argument + (see above), if an argument is present, it must be given in + the same shell item, for example, -o3 or --only-matching=2. + The comments given for the non-argument case above also apply + to this case. If the specified capturing parentheses do not + exist in the pattern, or were not set in the match, nothing + is output unless the file name or line number are being + printed. + + If this option is given multiple times, multiple substrings + are output, in the order the options are given. For example, + -o3 -o1 -o3 causes the substrings matched by capturing paren- + theses 3 and 1 and then 3 again to be output. By default, + there is no separator (but see the next option). + + --om-separator=text + Specify a separating string for multiple occurrences of -o. + The default is an empty string. Separating strings are never + coloured. + + -q, --quiet + Work quietly, that is, display nothing except error messages. + The exit status indicates whether or not any matches were + found. + + -r, --recursive + If any given path is a directory, recursively scan the files + it contains, taking note of any --include and --exclude set- + tings. By default, a directory is read as a normal file; in + some operating systems this gives an immediate end-of-file. + This option is a shorthand for setting the -d option to + "recurse". + + --recursion-limit=number + See --match-limit above. + + -s, --no-messages + Suppress error messages about non-existent or unreadable + files. Such files are quietly skipped. However, the return + code is still 2, even if matches were found in other files. + + -u, --utf-8 + Operate in UTF-8 mode. This option is available only if PCRE + has been compiled with UTF-8 support. All patterns (including + those for any --exclude and --include options) and all sub- + ject lines that are scanned must be valid strings of UTF-8 + characters. + + -V, --version + Write the version numbers of pcregrep and the PCRE library to + the standard output and then exit. Anything else on the com- + mand line is ignored. + + -v, --invert-match + Invert the sense of the match, so that lines which do not + match any of the patterns are the ones that are found. + + -w, --word-regex, --word-regexp + Force the patterns to match only whole words. This is equiva- + lent to having \b at the start and end of the pattern. This + option applies only to the patterns that are matched against + the contents of files; it does not apply to patterns speci- + fied by any of the --include or --exclude options. + + -x, --line-regex, --line-regexp + Force the patterns to be anchored (each must start matching + at the beginning of a line) and in addition, require them to + match entire lines. This is equivalent to having ^ and $ + characters at the start and end of each alternative branch in + every pattern. This option applies only to the patterns that + are matched against the contents of files; it does not apply + to patterns specified by any of the --include or --exclude + options. + + +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 + + The -N (--newline) option allows pcregrep to scan files with different + newline conventions from the default. Any parts of the input files that + are written to the standard output are copied identically, with what- + ever newline sequences they have in the input. However, the setting of + this option does not affect the interpretation of files specified by + the -f, --exclude-from, or --include-from options, which are assumed to + use the operating system's standard newline sequence, nor does it + affect the way in which pcregrep writes informational messages to the + standard error and output streams. For these it uses the string "\n" to + indicate newlines, relying on the C I/O library to convert this to an + appropriate sequence. + + +OPTIONS COMPATIBILITY + + Many of the short and long forms of pcregrep's options are the same as + 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, --om-separa- + tor, --recursion-limit, -u, and --utf-8 options are specific to pcre- + grep, 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 + glob for GNU grep, but a regular expression for pcregrep. If both the + -c and -l options are given, GNU grep lists only file names, without + counts, but pcregrep gives the counts. + + +OPTIONS WITH DATA + + There are four different ways in which an option with data can be spec- + ified. If a short form option is used, the data may follow immedi- + ately, or (with one exception) in the next command line item. For exam- + ple: + + -f/some/file + -f /some/file + + The exception is the -o option, which may appear with or without data. + Because of this, if data is present, it must follow immediately in the + same item, for example -o3. + + If a long form option is used, the data may appear in the same command + line item, separated by an equals character, or (with two exceptions) + it may appear in the next command line item. For example: + + --file=/some/file + --file /some/file + + Note, however, that if you want to supply a file name beginning with ~ + as data in a shell command, and have the shell expand ~ to a home + directory, you must separate the file name from the option, because the + shell does not treat ~ specially unless it is at the start of an item. + + The exceptions to the above are the --colour (or --color) and --only- + matching options, for which the data is optional. If one of these + 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 + + 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 repeats, for example: (a+)*\d when matched against a + line of a's with no final digit. The PCRE matching function has a + resource limit that causes it to abort in these circumstances. If this + happens, pcregrep outputs an error message and the line that caused the + problem to the standard error stream. If there are more than 20 such + errors, pcregrep gives up. + + The --match-limit option of pcregrep can be used to set the overall + resource limit; there is a second option called --recursion-limit that + sets a limit on the amount of memory (usually stack) that is used (see + the discussion of these options above). + + +DIAGNOSTICS + + Exit status is 0 if any matches were found, 1 if no matches were found, + 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 + + pcrepattern(3), pcresyntax(3), pcretest(1). + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 13 September 2012 + Copyright (c) 1997-2012 University of Cambridge. diff --git a/tools/pcre/doc/pcrejit.3 b/tools/pcre/doc/pcrejit.3 new file mode 100644 index 00000000..f05ad653 --- /dev/null +++ b/tools/pcre/doc/pcrejit.3 @@ -0,0 +1,437 @@ +.TH PCREJIT 3 "31 October 2012" "PCRE 8.32" +.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, 16-BIT AND 32-BIT SUPPORT" +.rs +.sp +JIT support is available for all of the 8-bit, 16-bit and 32-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). If you are using the 32-bit library, +substitute the 32-bit functions and 32-bit structures (for example, +\fIpcre32_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 + SPARC 32-bit (experimental) +.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 normal API is implemented +in a way that falls back to the interpretive code if JIT is not available. For +programs that need the best possible performance, there is also a "fast path" +API that is JIT-specific. +.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_NO_UTF32_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 achieve 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 "JIT FAST PATH API" +.rs +.sp +Because the API described above falls back to interpreted execution when JIT is +not available, it is convenient for programs that are written for general use +in many environments. However, calling JIT via \fBpcre_exec()\fP does have a +performance impact. Programs that are written for use where JIT is known to be +available, and which need the best possible performance, can instead use a +"fast path" API to call JIT execution directly instead of calling +\fBpcre_exec()\fP (obviously only for patterns that have been successfully +studied by JIT). +.P +The fast path function is called \fBpcre_jit_exec()\fP, and it takes exactly +the same arguments as \fBpcre_exec()\fP, plus one additional argument that +must point to a JIT stack. The JIT stack arrangements described above do not +apply. The return values are the same as for \fBpcre_exec()\fP. +.P +When you call \fBpcre_exec()\fP, as well as testing for invalid options, a +number of other sanity checks are performed on the arguments. For example, if +the subject pointer is NULL, or its length is negative, an immediate error is +given. Also, unless PCRE_NO_UTF[8|16|32] is set, a UTF subject string is tested +for validity. In the interests of speed, these checks do not happen on the JIT +fast path, and if invalid data is passed, the result is undefined. +.P +Bypassing the sanity checks and the \fBpcre_exec()\fP wrapping can give +speedups of more than 10%. +. +. +.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: 31 October 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcrelimits.3 b/tools/pcre/doc/pcrelimits.3 new file mode 100644 index 00000000..14ffbc46 --- /dev/null +++ b/tools/pcre/doc/pcrelimits.3 @@ -0,0 +1,67 @@ +.TH PCRELIMITS 3 "24 June 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, 32-bit units for the 32-bit library, and 32-bit units for +the 32-bit library) if PCRE is compiled with the default internal linkage size +of 2 bytes. If you want to process regular expressions that are truly enormous, +you can compile PCRE with an internal linkage size of 3 or 4 (when building the +16-bit or 32-bit library, 3 is rounded up to 4). See the \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 and 32-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 --git a/tools/pcre/doc/pcrematching.3 b/tools/pcre/doc/pcrematching.3 new file mode 100644 index 00000000..a9977d5e --- /dev/null +++ b/tools/pcre/doc/pcrematching.3 @@ -0,0 +1,206 @@ +.TH PCREMATCHING 3 "08 January 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH "PCRE MATCHING ALGORITHMS" +.rs +.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, +\fBpcre16_exec()\fP and \fBpcre32_exec()\fP functions. These work in the same +as 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, +\fBpcre16_dfa_exec()\fP and \fBpcre32_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, +when there are multiple possibilities. For example, if the pattern +.sp + ^<.*> +.sp +is matched against the string +.sp + +.sp +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 +The set of strings that are matched by a regular expression can be represented +as a tree structure. An unlimited repetition in the pattern makes the tree of +infinite size, but it is still a tree. Matching the pattern to a given subject +string (from a given starting point) can be thought of as a search of the tree. +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 +In the terminology of Jeffrey Friedl's book "Mastering Regular +Expressions", the standard algorithm is an "NFA algorithm". It conducts a +depth-first search of the pattern tree. That is, it proceeds along a single +path through the tree, checking that the subject matches what is required. When +there is a mismatch, the algorithm tries any alternatives at the current point, +and if they all fail, it backs up to the previous branch point in the tree, and +tries the next alternative branch at that level. This often involves backing up +(moving to the left) in the subject string as well. The order in which +repetition branches are tried is controlled by the greedy or ungreedy nature of +the quantifier. +.P +If a leaf node is reached, a matching string has been found, and at that point +the algorithm stops. Thus, if there is more than one possible match, this +algorithm returns the first one that it finds. Whether this is the shortest, +the longest, or some intermediate length depends on the way the greedy and +ungreedy repetition quantifiers are specified in the pattern. +.P +Because it ends up with a single path through the tree, it is relatively +straightforward for this algorithm to keep track of the substrings that are +matched by portions of the pattern in parentheses. This provides support for +capturing parentheses and back references. +. +. +.SH "THE ALTERNATIVE MATCHING ALGORITHM" +.rs +.sp +This algorithm conducts a breadth-first search of the tree. Starting from the +first matching point in the subject, it scans the subject string from left to +right, once, character by character, and as it does this, it remembers all the +paths through the tree that represent valid matches. In Friedl's terminology, +this is a kind of "DFA algorithm", though it is not implemented as a +traditional finite state machine (it keeps multiple states active +simultaneously). +.P +Although the general principle of this matching algorithm is that it scans the +subject string only once, without backtracking, there is one exception: when a +lookaround assertion is encountered, the characters following or preceding the +current point have to be independently inspected. +.P +The scan continues until either the end of the subject is reached, or there are +no more unterminated paths. At this point, terminated paths represent the +different matching possibilities (if there are none, the match has failed). +Thus, if there is more than one possible match, this algorithm finds all of +them, and in particular, it finds the longest. The matches are returned in +decreasing order of length. There is an option to stop the algorithm after the +first match (which is necessarily the shortest) is found. +.P +Note that all the matches that are found start at the same point in the +subject. If the pattern +.sp + cat(er(pillar)?)? +.sp +is matched against the string "the caterpillar catchment", the result will be +the three strings "caterpillar", "cater", and "cat" that start at the fifth +character of the subject. The algorithm does not automatically move on to find +matches that start at later positions. +.P +There are a number of features of PCRE regular expressions that are not +supported by the alternative matching algorithm. They are as follows: +.P +1. Because the algorithm finds all possible matches, the greedy or ungreedy +nature of repetition quantifiers is not relevant. Greedy and ungreedy +quantifiers are treated in exactly the same way. However, possessive +quantifiers can make a difference when what follows could also match what is +quantified, for example in a pattern like this: +.sp + ^a++\ew! +.sp +This pattern matches "aaab!" but not "aaa!", which would be matched by a +non-possessive quantifier. Similarly, if an atomic group is present, it is +matched as if it were a standalone pattern at the current point, and the +longest match is then "locked in" for the rest of the overall pattern. +.P +2. When dealing with multiple paths through the tree simultaneously, it is not +straightforward to keep track of captured substrings for the different matching +possibilities, and PCRE's implementation of this algorithm does not attempt to +do this. This means that no captured substrings are available. +.P +3. Because no substrings are captured, back references within the pattern are +not supported, and cause errors if encountered. +.P +4. For the same reason, conditional expressions that use a backreference as the +condition or test for a specific group recursion are not supported. +.P +5. Because many paths through the tree may be active, the \eK escape sequence, +which resets the start of the match when encountered (but may be on some paths +and not on others), is not supported. It causes an error if encountered. +.P +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) always matches a +single data unit, even in UTF-8, UTF-16 or UTF-32 modes, is not supported in +these modes, because the alternative algorithm moves through the subject string +one character (not data unit) at a time, for all active paths through the tree. +.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 +Using the alternative matching algorithm provides the following advantages: +.P +1. All possible matches (at a single point in the subject) are automatically +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. +.P +2. Because the alternative algorithm scans the subject string just once, and +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 +.\" +documentation gives details of partial matching and discusses multi-segment +matching. +. +. +.SH "DISADVANTAGES OF THE ALTERNATIVE ALGORITHM" +.rs +.sp +The alternative algorithm suffers from a number of disadvantages: +.P +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. +.P +2. Capturing parentheses and back references are not supported. +.P +3. Although atomic groups are supported, their use does not provide the +performance advantage that it does for the standard algorithm. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 08 January 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcrepartial.3 b/tools/pcre/doc/pcrepartial.3 new file mode 100644 index 00000000..d5cd74e2 --- /dev/null +++ b/tools/pcre/doc/pcrepartial.3 @@ -0,0 +1,445 @@ +.TH PCREPARTIAL 3 "24 June 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 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 +in the form \fIddmmmyy\fP, defined by this pattern: +.sp + ^\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed$ +.sp +If the application sees the user's keystrokes one by one, and can check that +what has been typed so far is potentially valid, it is able to raise an error +as soon as a mistake is made, by beeping and not reflecting the character that +has been typed, for example. This immediate feedback is likely to be a better +user interface than a check that is delayed until the entire string has been +entered. Partial matching can also be useful when the subject string is very +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 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 +If you want to use partial matching with just-in-time optimized code, you must +call \fBpcre_study()\fP, \fBpcre16_study()\fP or \fBpcre32_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 pcre[16|32]_exec()" +.rs +.sp +A partial match occurs during a call to \fBpcre_exec()\fP or +\fBpcre[16|32]_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 +assertions, or \eK, or begin with \eb or \eB, earlier characters have been +inspected while carrying out the match. For example: +.sp + /(?<=abc)123/ +.sp +This pattern matches "123", but only if it is preceded by "abc". If the subject +string is "xyzabc12", the offsets after a partial match are for the substring +"abc12", because all these characters are needed if another match is tried +with extra characters added to the subject. +.P +What happens when a partial match is identified depends on which of the two +partial matching options are set. +. +. +.SS "PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre[16|32]_exec()" +.rs +.sp +If PCRE_PARTIAL_SOFT is set when \fBpcre_exec()\fP or \fBpcre[16|32]_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 +potentially complete. For example, \ez, \eZ, and $ match at the end of the +subject, as normal, and for \eb and \eB the end of the subject is treated as a +non-alphanumeric. +.P +If there is more than one partial match, the first one that was found provides +the data that is returned. Consider this pattern: +.sp + /123\ew+X|dogY/ +.sp +If this is matched against the subject string "abc123dog", both +alternatives fail to match, but the end of the subject is reached during +matching, so PCRE_ERROR_PARTIAL is returned. The offsets are set to 3 and 9, +identifying "123dog" as the first partial match that was found. (In this +example, there are two partial matches, because "dog" on its own partially +matches the second alternative.) +. +. +.SS "PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre[16|32]_exec()" +.rs +.sp +If PCRE_PARTIAL_HARD is set for \fBpcre_exec()\fP or \fBpcre[16|32]_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. +. +. +.SS "Comparing hard and soft partial matching" +.rs +.sp +The difference between the two partial matching options can be illustrated by a +pattern such as: +.sp + /dog(sbody)?/ +.sp +This matches either "dog" or "dogsbody", greedily (that is, it prefers the +longer string if possible). If it is matched against the string "dog" with +PCRE_PARTIAL_SOFT, it yields a complete match for "dog". However, if +PCRE_PARTIAL_HARD is set, the result is PCRE_ERROR_PARTIAL. On the other hand, +if the pattern is made ungreedy the result is different: +.sp + /dog(sbody)??/ +.sp +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", because it will always find the +shorter match first. +. +. +.SH "PARTIAL MATCHING USING pcre_dfa_exec() OR pcre[16|32]_dfa_exec()" +.rs +.sp +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. +However, if PCRE_PARTIAL_HARD is set, a partial match takes precedence over any +complete matches. The portion of the string that was inspected when the longest +partial match was found is set as the first matching string, provided there are +at least two slots in the offsets vector. +.P +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 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" +.rs +.sp +If a pattern ends with one of sequences \eb or \eB, which test for word +boundaries, partial matching with PCRE_PARTIAL_SOFT can give counter-intuitive +results. Consider this pattern: +.sp + /\ebcat\eb/ +.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, 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" +.rs +.sp +For releases of PCRE prior to 8.00, because of the way certain internal +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 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 +conform to the restrictions, \fBpcre_exec()\fP returned the error code +PCRE_ERROR_BADPARTIAL (-13). This error code is no longer in use. The +PCRE_INFO_OKPARTIAL call to \fBpcre_fullinfo()\fP to find out if a compiled +pattern can be used for partial matching now always returns 1. +. +. +.SH "EXAMPLE OF PARTIAL MATCHING USING PCRETEST" +.rs +.sp +If the escape sequence \eP is present in a \fBpcretest\fP data line, the +PCRE_PARTIAL_SOFT option is used for the match. Here is a run of \fBpcretest\fP +that uses the date example quoted above: +.sp + re> /^\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed$/ + data> 25jun04\eP + 0: 25jun04 + 1: jun + data> 25dec3\eP + Partial match: 23dec3 + data> 3ju\eP + Partial match: 3ju + data> 3juj\eP + No match + data> j\eP + No match +.sp +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 +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() OR pcre[16|32]_dfa_exec()" +.rs +.sp +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 + Partial match: 23ja + data> n05\eR\eD + 0: n05 +.sp +The first call has "23ja" as the subject, and requests partial matching; 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. +.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 the DFA matching +functions. +. +. +.SH "MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre[16|32]_exec()" +.rs +.sp +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 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 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" +.rs +.sp +Certain types of pattern may give problems with multi-segment matching, +whichever matching function is used. +.P +1. If the pattern contains a test for the beginning of a line, you need to pass +the PCRE_NOTBOL option when the subject string for any call does start at the +beginning of a line. There is also a PCRE_NOTEOL option, but in practice when +doing multi-segment matching you should be using PCRE_PARTIAL_HARD, which +includes the effect of PCRE_NOTEOL. +.P +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 \fBpcre[16|32]_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 +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 +\eb or \eB. 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 possible. Consider again this \fBpcretest\fP example: +.sp + re> /dog(sbody)?/ + data> dogsb\eP + 0: dog + data> do\eP\eD + Partial match: do + data> gsb\eR\eP\eD + 0: g + data> dogsbody\eD + 0: dogsbody + 1: dog +.sp +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: +.sp + re> /dog(sbody)?/ + data> dogsb\eP\eP + Partial match: dogsb + data> do\eP\eD + Partial match: do + data> gsb\eR\eP\eP\eD + Partial match: gsb +.sp +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 +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 such as: +.sp + 1234|ABCD +.sp +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: +.sp + re> /1234|3789/ + data> ABC123\eP\eP + Partial match: 123 + data> 1237890 + 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 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 +the first buffer. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 24 June 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcrepattern.3 b/tools/pcre/doc/pcrepattern.3 new file mode 100644 index 00000000..c9c7b45d --- /dev/null +++ b/tools/pcre/doc/pcrepattern.3 @@ -0,0 +1,2983 @@ +.TH PCREPATTERN 3 "11 November 2012" "PCRE 8.32" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH "PCRE REGULAR EXPRESSION DETAILS" +.rs +.sp +The syntax and semantics of the regular expressions that are supported by PCRE +are described in detail below. There is a quick-reference syntax summary in the +.\" HREF +\fBpcresyntax\fP +.\" +page. PCRE tries to match Perl syntax and semantics as closely as it can. PCRE +also supports some alternative regular expression syntax (which does not +conflict with the Perl syntax) in order to provide some compatibility with +regular expressions in Python, .NET, and Oniguruma. +.P +Perl's regular expressions are described in its own documentation, and +regular expressions in general are covered in a number of books, some of which +have copious examples. Jeffrey Friedl's "Mastering Regular Expressions", +published by O'Reilly, covers regular expressions in great detail. This +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 strings in the original library, an +extra library that supports 16-bit and UTF-16 character strings, and a +third library that supports 32-bit and UTF-32 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, +PCRE_UTF16, or PCRE_UTF32 option, or the pattern must start with one of +these special sequences: +.sp + (*UTF8) + (*UTF16) + (*UTF32) + (*UTF) +.sp +(*UTF) is a generic sequence that can be used with any of the libraries. +Starting a pattern with such a sequence is equivalent to setting the relevant +option. This feature is not Perl-compatible. How setting a UTF mode affects +pattern matching is mentioned in several places below. There is also a summary +of features in the +.\" HREF +\fBpcreunicode\fP +.\" +page. +.P +Another special sequence that may appear at the start of a pattern or in +combination with (*UTF8), (*UTF16), (*UTF32) or (*UTF) is: +.sp + (*UCP) +.sp +This has the same effect as setting the PCRE_UCP option: it causes sequences +such as \ed and \ew to use Unicode properties to determine character types, +instead of recognizing only characters with codes less than 128 via a lookup +table. +.P +If a pattern starts with (*NO_START_OPT), it has the same effect as setting the +PCRE_NO_START_OPTIMIZE option either at compile or matching time. There are +also some more of these special sequences that are concerned with the handling +of newlines; they are described below. +.P +The remainder of this document discusses the patterns that are supported by +PCRE when one its main matching functions, \fBpcre_exec()\fP (8-bit) or +\fBpcre[16|32]_exec()\fP (16- or 32-bit), is used. PCRE also has alternative +matching functions, \fBpcre_dfa_exec()\fP and \fBpcre[16|32_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 +.\" +page. +. +. +.SH "EBCDIC CHARACTER CODES" +.rs +.sp +PCRE can be compiled to run in an environment that uses EBCDIC as its character +code rather than ASCII or Unicode (typically a mainframe system). In the +sections below, character code values are ASCII or Unicode; in an EBCDIC +environment these characters may have different code values, and there are no +code points greater than 255. +. +. +.\" HTML +.SH "NEWLINE CONVENTIONS" +.rs +.sp +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 +.\" HREF +\fBpcreapi\fP +.\" +page has +.\" HTML +.\" +further discussion +.\" +about newlines, and shows how to set the newline convention in the +\fIoptions\fP arguments for the compiling and matching functions. +.P +It is also possible to specify a newline convention by starting a pattern +string with one of the following five sequences: +.sp + (*CR) carriage return + (*LF) linefeed + (*CRLF) carriage return, followed by linefeed + (*ANYCRLF) any of the three above + (*ANY) all Unicode newline sequences +.sp +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 +changes the convention to CR. That pattern matches "a\enb" because LF is no +longer a newline. Note that these special settings, which are not +Perl-compatible, are recognized only at the very start of a pattern, and that +they must be in upper case. If more than one of them is present, the last one +is used. +.P +The newline convention affects where the circumflex and dollar assertions are +true. It also affects the interpretation of the dot metacharacter when +PCRE_DOTALL is not set, and the behaviour of \eN. However, it does not affect +what the \eR escape sequence matches. By default, this is any Unicode newline +sequence, for Perl compatibility. However, this can be changed; see the +description of \eR in the section entitled +.\" HTML +.\" +"Newline sequences" +.\" +below. A change of \eR setting can be combined with a change of newline +convention. +. +. +.SH "CHARACTERS AND METACHARACTERS" +.rs +.sp +A regular expression is a pattern that is matched against a subject string from +left to right. Most characters stand for themselves in a pattern, and match the +corresponding characters in the subject. As a trivial example, the pattern +.sp + The quick brown fox +.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 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 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 +\fImetacharacters\fP, which do not stand for themselves but instead are +interpreted in some special way. +.P +There are two different sets of metacharacters: those that are recognized +anywhere in the pattern except within square brackets, and those that are +recognized within square brackets. Outside square brackets, the metacharacters +are as follows: +.sp + \e general escape character with several uses + ^ assert start of string (or line, in multiline mode) + $ assert end of string (or line, in multiline mode) + . match any character except newline (by default) + [ start character class definition + | start of alternative branch + ( start subpattern + ) end subpattern + ? extends the meaning of ( + also 0 or 1 quantifier + also quantifier minimizer + * 0 or more quantifier + + 1 or more quantifier + also "possessive quantifier" + { start min/max quantifier +.sp +Part of a pattern that is in square brackets is called a "character class". In +a character class the only metacharacters are: +.sp + \e general escape character + ^ negate the class, but only if the first character + - indicates character range +.\" JOIN + [ POSIX character class (only if followed by POSIX + syntax) + ] terminates the character class +.sp +The following sections describe the use of each of the metacharacters. +. +. +.SH BACKSLASH +.rs +.sp +The backslash character has several uses. Firstly, if it is followed by a +character that is not a number or a letter, it takes away any special meaning +that character may have. This use of backslash as an escape character applies +both inside and outside character classes. +.P +For example, if you want to match a * character, you write \e* in the pattern. +This escaping action applies whether or not the following character would +otherwise be interpreted as a metacharacter, so it is always safe to precede a +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 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, 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 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 +that $ and @ are handled as literals in \eQ...\eE sequences in PCRE, whereas in +Perl, $ and @ cause variable interpolation. Note the following examples: +.sp + Pattern PCRE matches Perl matches +.sp +.\" JOIN + \eQabc$xyz\eE abc$xyz abc followed by the + contents of $xyz + \eQabc\e$xyz\eE abc\e$xyz abc\e$xyz + \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. 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 +.SS "Non-printing characters" +.rs +.sp +A second use of backslash provides a way of encoding non-printing characters +in patterns in a visible manner. There is no restriction on the appearance of +non-printing characters, apart from the binary zero that terminates a pattern, +but when a pattern is being prepared by text editing, it is often easier to use +one of the following escape sequences than the binary character it represents: +.sp + \ea alarm, that is, the BEL character (hex 07) + \ecx "control-x", where x is any ASCII character + \ee escape (hex 1B) + \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.. (non-JavaScript mode) + \euhhhh character with hex code hhhh (JavaScript mode only) +.sp +The precise effect of \ecx on ASCII characters 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 \ecA to \ecZ become hex 01 to hex 1A (A is 41, Z is 5A), +but \ec{ becomes hex 3B ({ is 7B), and \ec; becomes hex 7B (; is 3B). If the +data item (byte or 16-bit value) following \ec has a value greater than 127, a +compile-time error occurs. This locks out non-ASCII characters in all modes. +.P +The \ec facility was designed for use with ASCII characters, but with the +extension to Unicode it is even less useful than it once was. It is, however, +recognized when PCRE is compiled in EBCDIC mode, where data items are always +bytes. In this mode, all values are valid after \ec. If the next character is a +lower case letter, it is converted to upper case. Then the 0xc0 bits of the +byte are inverted. Thus \ecA becomes hex 01, as in ASCII (A is C1), but because +the EBCDIC letters are disjoint, \ecZ becomes hex 29 (Z is E9), and other +characters also generate different values. +.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 + 32-bit non-UTF mode less than 0x80000000 + 32-bit UTF-32 mode less than 0x10ffff and a valid codepoint +.sp +Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called +"surrogate" codepoints), and 0xffef. +.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 (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 +specifies two binary zeros followed by a BEL character (code value 7). Make +sure you supply two digits after the initial zero if the pattern character that +follows is itself an octal digit. +.P +The handling of a backslash followed by a digit other than 0 is complicated. +Outside a character class, PCRE reads it and any following digits as a decimal +number. If the number is less than 10, or if there have been at least that many +previous capturing left parentheses in the expression, the entire sequence is +taken as a \fIback reference\fP. A description of how this works is given +.\" HTML +.\" +later, +.\" +following the discussion of +.\" HTML +.\" +parenthesized subpatterns. +.\" +.P +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. 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 an ASCII space +.\" JOIN + \e40 is the same, provided there are fewer than 40 + previous capturing subpatterns + \e7 is always a back reference +.\" JOIN + \e11 might be a back reference, or another way of + writing a tab + \e011 is always a tab + \e0113 is a tab followed by the character "3" +.\" JOIN + \e113 might be a back reference, otherwise the + character with octal code 113 +.\" JOIN + \e377 might be a back reference, otherwise + the value 255 (decimal) +.\" JOIN + \e81 is either a back reference, or a binary zero + followed by the two characters "8" and "1" +.sp +Note that octal values of 100 or greater must not be introduced by a leading +zero, because no more than three octal digits are ever read. +.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, \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" +.rs +.sp +The sequence \eg followed by an unsigned or a negative number, optionally +enclosed in braces, is an absolute or relative back reference. A named back +reference can be coded as \eg{name}. Back references are discussed +.\" HTML +.\" +later, +.\" +following the discussion of +.\" HTML +.\" +parenthesized subpatterns. +.\" +. +. +.SS "Absolute and relative subroutine calls" +.rs +.sp +For compatibility with Oniguruma, the non-Perl syntax \eg followed by a name or +a number enclosed either in angle brackets or single quotes, is an alternative +syntax for referencing a subpattern as a "subroutine". Details are discussed +.\" HTML +.\" +later. +.\" +Note that \eg{...} (Perl syntax) and \eg<...> (Oniguruma syntax) are \fInot\fP +synonymous. The former is a back reference; the latter is a +.\" HTML +.\" +subroutine +.\" +call. +. +. +.\" HTML +.SS "Generic character types" +.rs +.sp +Another use of backslash is for specifying generic character types: +.sp + \ed any decimal digit + \eD any character that is not a decimal digit + \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 +There is also the single sequence \eN, which matches a non-newline character. +This is the same as +.\" HTML +.\" +the "." metacharacter +.\" +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 +one, of each pair. The sequences can appear both inside and outside character +classes. They each match one character of the appropriate type. If the current +matching point is at the end of the subject string, all of them fail, because +there is no character to match. +.P +For compatibility with Perl, \es does not match the VT character (code 11). +This makes it different from the the POSIX "space" class. The \es characters +are HT (9), LF (10), FF (12), CR (13), and space (32). If "use locale;" is +included in a Perl script, \es may match the VT character. In PCRE, it never +does. +.P +A "word" character is an underscore or any character that is a letter or digit. +By default, the definition of letters and digits is controlled by PCRE's +low-valued character tables, and may vary if locale-specific matching is taking +place (see +.\" HTML +.\" +"Locale support" +.\" +in the +.\" HREF +\fBpcreapi\fP +.\" +page). For example, in a French locale such as "fr_FR" in Unix-like systems, +or "french" in Windows, some character codes greater than 128 are used for +accented letters, and these are then matched by \ew. The use of locales with +Unicode is discouraged. +.P +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 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: +.sp + \ed any character that \ep{Nd} matches (decimal digit) + \es any character that \ep{Z} matches, plus HT, LF, FF, CR + \ew any character that \ep{L} or \ep{N} matches, plus underscore +.sp +The upper case escapes match the inverse sets of characters. Note that \ed +matches only decimal digits, whereas \ew matches any Unicode digit, as well as +any Unicode letter, and underscore. Note also that PCRE_UCP affects \eb, and +\eB because they are defined in terms of \ew and \eW. Matching these sequences +is noticeably slower when PCRE_UCP is set. +.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, +whether or not PCRE_UCP is set. The horizontal space characters are: +.sp + U+0009 Horizontal tab (HT) + U+0020 Space + U+00A0 Non-break space + U+1680 Ogham space mark + U+180E Mongolian vowel separator + U+2000 En quad + U+2001 Em quad + U+2002 En space + U+2003 Em space + U+2004 Three-per-em space + U+2005 Four-per-em space + U+2006 Six-per-em space + U+2007 Figure space + U+2008 Punctuation space + U+2009 Thin space + U+200A Hair space + U+202F Narrow no-break space + U+205F Medium mathematical space + U+3000 Ideographic space +.sp +The vertical space characters are: +.sp + U+000A Linefeed (LF) + U+000B Vertical tab (VT) + U+000C Form feed (FF) + U+000D Carriage return (CR) + U+0085 Next line (NEL) + 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 +.SS "Newline sequences" +.rs +.sp +Outside a character class, by default, the escape sequence \eR matches any +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 +This is an example of an "atomic group", details of which are given +.\" HTML +.\" +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 (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 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. +.P +It is possible to restrict \eR to match only CR, LF, or CRLF (instead of the +complete set of Unicode line endings) by setting the option PCRE_BSR_ANYCRLF +either at compile time or when the pattern is matched. (BSR is an abbrevation +for "backslash R".) This can be made the default when PCRE is built; if this is +the case, the other behaviour can be requested via the PCRE_BSR_UNICODE option. +It is also possible to specify these settings by starting a pattern string with +one of the following sequences: +.sp + (*BSR_ANYCRLF) CR, LF, or CRLF only + (*BSR_UNICODE) any Unicode newline sequence +.sp +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), (*UTF16), (*UTF32), (*UTF) 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 +.SS Unicode character properties +.rs +.sp +When PCRE is built with Unicode character property support, three additional +escape sequences that match characters with specific properties 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: +.sp + \ep{\fIxx\fP} a character with the \fIxx\fP property + \eP{\fIxx\fP} a character without the \fIxx\fP property + \eX a Unicode extended grapheme cluster +.sp +The property names represented by \fIxx\fP above are limited to the Unicode +script names, the general category properties, "Any", which matches any +character (including newline), and some special PCRE properties (described +in the +.\" HTML +.\" +next section). +.\" +Other Perl properties such as "InMusicalSymbols" are not currently supported by +PCRE. Note that \eP{Any} does not match any characters, so always causes a +match failure. +.P +Sets of Unicode characters are defined as belonging to certain scripts. A +character from one of these sets can be matched using a script name. For +example: +.sp + \ep{Greek} + \eP{Han} +.sp +Those that are not part of an identified script are lumped together as +"Common". The current list of scripts is: +.P +Arabic, +Armenian, +Avestan, +Balinese, +Bamum, +Batak, +Bengali, +Bopomofo, +Brahmi, +Braille, +Buginese, +Buhid, +Canadian_Aboriginal, +Carian, +Chakma, +Cham, +Cherokee, +Common, +Coptic, +Cuneiform, +Cypriot, +Cyrillic, +Deseret, +Devanagari, +Egyptian_Hieroglyphs, +Ethiopic, +Georgian, +Glagolitic, +Gothic, +Greek, +Gujarati, +Gurmukhi, +Han, +Hangul, +Hanunoo, +Hebrew, +Hiragana, +Imperial_Aramaic, +Inherited, +Inscriptional_Pahlavi, +Inscriptional_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, +Samaritan, +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. +.P +Each character has exactly one Unicode general category property, specified by +a two-letter abbreviation. For compatibility with Perl, negation can be +specified by including a circumflex between the opening brace and the property +name. For example, \ep{^Lu} is the same as \eP{Lu}. +.P +If only one letter is specified with \ep or \eP, it includes all the general +category properties that start with that letter. In this case, in the absence +of negation, the curly brackets in the escape sequence are optional; these two +examples have the same effect: +.sp + \ep{L} + \epL +.sp +The following general category property codes are supported: +.sp + C Other + Cc Control + Cf Format + Cn Unassigned + Co Private use + Cs Surrogate +.sp + L Letter + Ll Lower case letter + Lm Modifier letter + Lo Other letter + Lt Title case letter + Lu Upper case letter +.sp + M Mark + Mc Spacing mark + Me Enclosing mark + Mn Non-spacing mark +.sp + N Number + Nd Decimal number + Nl Letter number + No Other number +.sp + P Punctuation + Pc Connector punctuation + Pd Dash punctuation + Pe Close punctuation + Pf Final punctuation + Pi Initial punctuation + Po Other punctuation + Ps Open punctuation +.sp + S Symbol + Sc Currency symbol + Sk Modifier symbol + Sm Mathematical symbol + So Other symbol +.sp + Z Separator + Zl Line separator + Zp Paragraph separator + Zs Space separator +.sp +The special property L& is also supported: it matches a character that has +the Lu, Ll, or Lt property, in other words, a letter that is not classified as +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 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, PCRE_NO_UTF16_CHECK and +PCRE_NO_UTF32_CHECK in the +.\" HREF +\fBpcreapi\fP +.\" +page). Perl does not support the Cs property. +.P +The long synonyms for property names that Perl supports (such as \ep{Letter}) +are not supported by PCRE, nor is it permitted to prefix any of these +properties with "Is". +.P +No character that is in the Unicode table has the Cn (unassigned) property. +Instead, this property is assumed for any code point that is not in the +Unicode table. +.P +Specifying caseless matching does not affect these escape sequences. For +example, \ep{Lu} always matches only upper case letters. +.P +Matching characters by Unicode property is not fast, because PCRE has to do a +multistage table lookup in order to find a character's property. 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 or by starting the pattern with (*UCP). +. +. +.SS Extended grapheme clusters +.rs +.sp +The \eX escape matches any number of Unicode characters that form an "extended +grapheme cluster", and treats the sequence as an atomic group +.\" HTML +.\" +(see below). +.\" +Up to and including release 8.31, PCRE matched an earlier, simpler definition +that was equivalent to +.sp + (?>\ePM\epM*) +.sp +That is, it matched a character without the "mark" property, followed by zero +or more characters with the "mark" property. Characters with the "mark" +property are typically non-spacing accents that affect the preceding character. +.P +This simple definition was extended in Unicode to include more complicated +kinds of composite character by giving each character a grapheme breaking +property, and creating rules that use these properties to define the boundaries +of extended grapheme clusters. In releases of PCRE later than 8.31, \eX matches +one of these clusters. +.P +\eX always matches at least one character. Then it decides whether to add +additional characters according to the following rules for ending a cluster: +.P +1. End at the end of the subject string. +.P +2. Do not end between CR and LF; otherwise end after any control character. +.P +3. Do not break Hangul (a Korean script) syllable sequences. Hangul characters +are of five types: L, V, T, LV, and LVT. An L character may be followed by an +L, V, LV, or LVT character; an LV or V character may be followed by a V or T +character; an LVT or T character may be follwed only by a T character. +.P +4. Do not end before extending characters or spacing marks. Characters with +the "mark" property always have the "extend" grapheme breaking property. +.P +5. Do not end after prepend characters. +.P +6. Otherwise, end the cluster. +. +. +.\" HTML +.SS PCRE's additional properties +.rs +.sp +As well as the standard Unicode properties described above, PCRE supports four +more that make it possible to convert traditional escape sequences such as \ew +and \es and POSIX character classes to use Unicode properties. PCRE uses these +non-standard, non-Perl properties internally when PCRE_UCP is set. They are: +.sp + Xan Any alphanumeric character + Xps Any POSIX space character + Xsp Any Perl space character + 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, 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. +. +. +.\" HTML +.SS "Resetting the match start" +.rs +.sp +The escape sequence \eK causes any previously matched characters not to be +included in the final matched sequence. For example, the pattern: +.sp + foo\eKbar +.sp +matches "foobar", but reports that it has matched "bar". This feature is +similar to a lookbehind assertion +.\" HTML +.\" +(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 \eK does +not interfere with the setting of +.\" HTML +.\" +captured substrings. +.\" +For example, when the pattern +.sp + (foo)\eKbar +.sp +matches "foobar", the first substring is still set to "foo". +.P +Perl documents that the use of \eK within assertions is "not well defined". In +PCRE, \eK is acted upon when it occurs inside positive assertions, but is +ignored in negative assertions. +. +. +.\" HTML +.SS "Simple assertions" +.rs +.sp +The final use of backslash is for certain simple assertions. An assertion +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 +.\" HTML +.\" +below. +.\" +The backslashed assertions are: +.sp + \eb matches at a word boundary + \eB matches when not at a word boundary + \eA matches at the start of the subject + \eZ matches at the end of the subject + also matches before a newline at the end of the subject + \ez matches only at the end of the subject + \eG matches at the first matching position in the subject +.sp +Inside a character class, \eb 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 character (for example, \eB +matches the letter B). However, if the PCRE_EXTRA option is set, an "invalid +escape sequence" error is generated instead. +.P +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 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 +determines which it is. For example, the fragment \eba matches "a" at the start +of a word. +.P +The \eA, \eZ, and \ez 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 assertions 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 \fIstartoffset\fP +argument of \fBpcre_exec()\fP is non-zero, indicating that matching is to start +at a point other than the beginning of the subject, \eA can never match. The +difference between \eZ and \ez is that \eZ matches before a newline at the end +of the string as well as at the very end, whereas \ez matches only at the end. +.P +The \eG assertion is true only when the current matching position is at the +start point of the match, as specified by the \fIstartoffset\fP argument of +\fBpcre_exec()\fP. It differs from \eA when the value of \fIstartoffset\fP is +non-zero. By calling \fBpcre_exec()\fP multiple times with appropriate +arguments, you can mimic Perl's /g option, and it is in this kind of +implementation where \eG can be useful. +.P +Note, however, that PCRE's interpretation of \eG, 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 at a time, it cannot +reproduce this behaviour. +.P +If all the alternatives of a pattern begin with \eG, the expression is anchored +to the starting match position, and the "anchored" flag is set in the compiled +regular expression. +. +. +.SH "CIRCUMFLEX AND DOLLAR" +.rs +.sp +The circumflex and dollar metacharacters are zero-width assertions. That is, +they test for a particular condition being true without consuming any +characters from the subject string. +.P +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 \fIstartoffset\fP argument of +\fBpcre_exec()\fP is non-zero, circumflex can never match if the PCRE_MULTILINE +option is unset. Inside a character class, circumflex has an entirely different +meaning +.\" HTML +.\" +(see below). +.\" +.P +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 subject, it is said to be an +"anchored" pattern. (There are also other constructs that can cause a pattern +to be anchored.) +.P +The dollar character is an assertion that is true only if the current matching +point is at the end of the subject string, or immediately before a newline at +the end of the string (by default). Note, however, that it does not actually +match the newline. Dollar need not be the last character of the pattern if a +number of alternatives are involved, but it should be the last item in any +branch in which it appears. Dollar has no special meaning in a character class. +.P +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 \eZ assertion. +.P +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 not indicate newlines. +.P +For example, the pattern /^abc$/ matches the subject string "def\enabc" (where +\en 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 \fIstartoffset\fP argument of \fBpcre_exec()\fP is non-zero. The +PCRE_DOLLAR_ENDONLY option is ignored if PCRE_MULTILINE is set. +.P +Note that the sequences \eA, \eZ, and \ez can be used to match the start and +end of the subject in both modes, and if all branches of a pattern start with +\eA it is always anchored, whether or not PCRE_MULTILINE is set. +. +. +.\" HTML +.SH "FULL STOP (PERIOD, DOT) AND \eN" +.rs +.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. +.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 +if it is immediately followed by LF, but otherwise it matches all characters +(including isolated CRs and LFs). When any Unicode line endings are being +recognized, dot does not match CR or LF or any of the other line ending +characters. +.P +The behaviour of dot with regard to newlines can be changed. If the PCRE_DOTALL +option is set, a dot matches any one character, without exception. If the +two-character sequence CRLF is present in the subject string, it takes two dots +to match it. +.P +The handling of dot is entirely independent of the handling of circumflex and +dollar, the only relationship being that they both involve newlines. Dot has no +special meaning in a character class. +.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. Perl also uses \eN to match characters by +name; PCRE does not support this. +. +. +.SH "MATCHING A SINGLE DATA UNIT" +.rs +.sp +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; in the 32-bit library it is +a 32-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, PCRE_NO_UTF16_CHECK or +PCRE_NO_UTF32_CHECK option is used). +.P +PCRE does not allow \eC to appear in lookbehind assertions +.\" HTML +.\" +(described below) +.\" +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 +.SH "SQUARE BRACKETS AND CHARACTER CLASSES" +.rs +.sp +An opening square bracket introduces a character class, terminated by a closing +square bracket. A closing square bracket on its own is not special 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 present) or escaped with a backslash. +.P +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 +[^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 consumes a character from the subject +string, and therefore it fails if the current pointer is at the end of the +string. +.P +In UTF-8 (UTF-16, UTF-32) mode, characters with values greater than 255 (0xffff) +can be included in a class as a literal string of data units, 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 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. +.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 +whatever setting of the PCRE_DOTALL and PCRE_MULTILINE options is used. A class +such as [^a] always matches one of these characters. +.P +The minus (hyphen) character can be used to specify a range of characters 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. +.P +It is not possible to have the literal character "]" as the end character 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-\e]46] is interpreted 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. +.P +Ranges operate in the collating sequence of character values. They can also be +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 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 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 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 +.\" +"Generic character types" +.\" +above. The escape sequence \eb has a different meaning inside a character +class; it matches the backspace character. 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. +.P +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 [^\eW_] matches any letter or digit, but not underscore, +whereas [\ew] 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 ...". +.P +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. +. +. +.SH "POSIX CHARACTER CLASSES" +.rs +.sp +Perl supports the POSIX notation for character classes. This uses names +enclosed by [: and :] within the enclosing square brackets. PCRE also supports +this notation. For example, +.sp + [01[:alpha:]%] +.sp +matches "0", "1", any alphabetic character, or "%". The supported class names +are: +.sp + alnum letters and digits + alpha letters + ascii character codes 0 - 127 + blank space or tab only + cntrl control characters + digit decimal digits (same as \ed) + graph printing characters, excluding space + lower lower case letters + print printing characters, including space + punct printing characters, excluding letters and digits and space + space white space (not quite the same as \es) + upper upper case letters + word "word" characters (same as \ew) + xdigit hexadecimal digits +.sp +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 \es, which does not include VT (for Perl +compatibility). +.P +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, +.sp + [12[:^digit:]] +.sp +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. +.P +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 +by other sequences, as follows: +.sp + [:alnum:] becomes \ep{Xan} + [:alpha:] becomes \ep{L} + [:blank:] becomes \eh + [:digit:] becomes \ep{Nd} + [:lower:] becomes \ep{Ll} + [:space:] becomes \ep{Xps} + [:upper:] becomes \ep{Lu} + [:word:] becomes \ep{Xwd} +.sp +Negated versions, such as [:^alpha:] use \eP instead of \ep. The other POSIX +classes are unchanged, and match only characters with code points less than +128. +. +. +.SH "VERTICAL BAR" +.rs +.sp +Vertical bar characters are used to separate alternative patterns. For example, +the pattern +.sp + gilbert|sullivan +.sp +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 +.\" HTML +.\" +(defined below), +.\" +"succeeds" means matching the rest of the main pattern as well as the +alternative in the subpattern. +. +. +.SH "INTERNAL OPTION SETTING" +.rs +.sp +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 +.sp + i for PCRE_CASELESS + m for PCRE_MULTILINE + s for PCRE_DOTALL + x for PCRE_EXTENDED +.sp +For example, (?im) sets caseless, multiline matching. It is also possible to +unset these options by preceding the letter with a hyphen, and a combined +setting and unsetting such as (?im-sx), which sets PCRE_CASELESS 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. +.P +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. +.P +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 therefore show up in data +extracted by the \fBpcre_fullinfo()\fP function). +.P +An option change within a subpattern (see below for a description of +subpatterns) affects only that part of the subpattern that follows it, so +.sp + (a(?i)b)c +.sp +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 example, +.sp + (a(?i)b|c) +.sp +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. +.P +\fBNote:\fP 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 +.\" HTML +.\" +"Newline sequences" +.\" +above. There are also the (*UTF8), (*UTF16),(*UTF32), 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, PCRE_UTF32 and the PCRE_UCP +options, respectively. The (*UTF) sequence is a generic version that can be +used with any of the libraries. +. +. +.\" HTML +.SH SUBPATTERNS +.rs +.sp +Subpatterns are delimited by parentheses (round brackets), which can be nested. +Turning part of a pattern into a subpattern does two things: +.sp +1. It localizes a set of alternatives. For example, the pattern +.sp + cat(aract|erpillar|) +.sp +matches "cataract", "caterpillar", or "cat". Without the parentheses, it would +match "cataract", "erpillar" or an empty string. +.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 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 +the captured substrings are "red king", "red", and "king", and are numbered 1, +2, and 3, respectively. +.P +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 capturing, 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 +.sp + the ((?:red|white) (king|queen)) +.sp +the captured substrings are "white queen" and "queen", and are numbered 1 and +2. The maximum number of capturing subpatterns is 65535. +.P +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 +.sp + (?i:saturday|sunday) + (?:(?i)saturday|sunday) +.sp +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 "Saturday". +. +. +.\" HTML +.SH "DUPLICATE SUBPATTERN NUMBERS" +.rs +.sp +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, consider this +pattern: +.sp + (?|(Sat)ur|(Sun))day +.sp +Because the two alternatives are inside a (?| group, both sets of capturing +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, parentheses 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 following example is taken from the Perl documentation. The +numbers underneath show in which buffer the captured content will be stored. +.sp + # before ---------------branch-reset----------- after + / ( a ) (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x + # 1 2 2 3 2 3 4 +.sp +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": +.sp + /(?|(abc)|(def))\e1/ +.sp +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 +If a +.\" HTML +.\" +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 number have matched. +.P +An alternative approach to using this "branch reset" feature is to use +duplicate named subpatterns, as described in the next section. +. +. +.SH "NAMED SUBPATTERNS" +.rs +.sp +Identifying capturing parentheses by number is simple, but it can be very hard +to keep track of the numbers in complicated regular expressions. Furthermore, +if an expression is modified, the numbers may change. To help with this +difficulty, PCRE supports the naming of subpatterns. 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 syntax. Perl allows identically numbered subpatterns to +have different names, but PCRE does not. +.P +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 +.\" HTML +.\" +back references, +.\" +.\" HTML +.\" +recursion, +.\" +and +.\" HTML +.\" +conditions, +.\" +can be made by name as well as by number. +.P +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. +.P +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.) Duplicate 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: +.sp + (?Mon|Fri|Sun)(?:day)?| + (?Tue)(?:sday)?| + (?Wed)(?:nesday)?| + (?Thu)(?:rsday)?| + (?Sat)(?:urday)? +.sp +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.) +.P +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. +.P +If you make a back reference to a non-unique named subpattern from elsewhere in +the pattern, the one that corresponds to the first occurrence of the name is +used. In the absence of duplicate numbers (see the previous section) this is +the one with the lowest number. If you use a named reference in a condition +test (see the +.\" +.\" HTML +.\" +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 +.\" HREF +\fBpcreapi\fP +.\" +documentation. +.P +\fBWarning:\fP You cannot use different names to distinguish between two +subpatterns with the same number because PCRE uses only the numbers when +matching. For this reason, an error is given at compile time if different 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. +. +. +.SH REPETITION +.rs +.sp +Repetition is specified by quantifiers, which can follow any of the following +items: +.sp + a literal data character + the dot metacharacter + the \eC escape sequence + 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 (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), +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: +.sp + z{2,4} +.sp +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 +.sp + [aeiou]{3,} +.sp +matches at least 3 successive vowels, but may match many more, while +.sp + \ed{8} +.sp +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 example, {,6} is not a +quantifier, but a literal string of four characters. +.P +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 grapheme clusters, 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 +subpatterns that are referenced as +.\" HTML +.\" +subroutines +.\" +from elsewhere in the pattern (but see also the section entitled +.\" HTML +.\" +"Defining subpatterns for use by reference only" +.\" +below). Items other than subpatterns that have a {0} quantifier are omitted +from the compiled pattern. +.P +For convenience, the three most common quantifiers have single-character +abbreviations: +.sp + * is equivalent to {0,} + + is equivalent to {1,} + ? is equivalent to {0,1} +.sp +It is possible to construct infinite loops by following a subpattern that can +match no characters with a quantifier that has no upper limit, for example: +.sp + (a?)* +.sp +Earlier versions of Perl and PCRE used to give an error at compile time for +such patterns. However, because there are cases where this can be useful, such +patterns are now accepted, but if any repetition of the subpattern does in fact +match no characters, the loop is forcibly broken. +.P +By default, the quantifiers are "greedy", that is, they match as much as +possible (up to the maximum number of permitted times), without causing the +rest of the pattern to fail. The classic example of where this gives problems +is in trying to match comments in C programs. These appear between /* and */ +and within the comment, individual * and / characters may appear. An attempt to +match C comments by applying the pattern +.sp + /\e*.*\e*/ +.sp +to the string +.sp + /* first comment */ not comment /* second comment */ +.sp +fails, because it matches the entire string owing to the greediness of the .* +item. +.P +However, if a quantifier is followed by a question mark, it ceases to be +greedy, and instead matches the minimum number of times possible, so the +pattern +.sp + /\e*.*?\e*/ +.sp +does the right thing with the C comments. The meaning of the various +quantifiers is not otherwise changed, just the preferred number of matches. +Do not confuse this use of question mark with its use as a quantifier in its +own right. Because it has two uses, it can sometimes appear doubled, as in +.sp + \ed??\ed +.sp +which matches one digit by preference, but can match two if that is the only +way the rest of the pattern matches. +.P +If the PCRE_UNGREEDY option is set (an option that is not available in Perl), +the quantifiers are not greedy by default, but individual ones can be made +greedy by following them with a question mark. In other words, it inverts the +default behaviour. +.P +When a parenthesized subpattern is quantified with a minimum repeat count that +is greater than 1 or with a limited maximum, more memory is required for the +compiled pattern, in proportion to the size of the minimum or maximum. +.P +If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equivalent +to Perl's /s) is set, thus allowing the dot to match newlines, the pattern is +implicitly anchored, because whatever follows will be tried against every +character position in the subject string, so there is no point in retrying the +overall match at any position after the first. PCRE normally treats such a +pattern as though it were preceded by \eA. +.P +In cases where it is known that the subject string contains no newlines, it is +worth setting PCRE_DOTALL in order to obtain this optimization, or +alternatively using ^ to indicate anchoring explicitly. +.P +However, there are some cases where the optimization cannot be used. When .* +is inside capturing parentheses that are the subject of a back reference +elsewhere in the pattern, a match at the start may fail where a later one +succeeds. Consider, for example: +.sp + (.*)abc\e1 +.sp +If the subject is "xyz123abc123" the match point is the fourth character. For +this reason, such a pattern is not implicitly anchored. +.P +Another case where implicit anchoring is not applied is when the leading .* is +inside an atomic group. Once again, a match at the start may fail where a later +one succeeds. Consider this pattern: +.sp + (?>.*?a)b +.sp +It matches "ab" in the subject "aab". The use of the backtracking control verbs +(*PRUNE) and (*SKIP) also disable this optimization. +.P +When a capturing subpattern is repeated, the value captured is the substring +that matched the final iteration. For example, after +.sp + (tweedle[dume]{3}\es*)+ +.sp +has matched "tweedledum tweedledee" the value of the captured substring is +"tweedledee". However, if there are nested capturing subpatterns, the +corresponding captured values may have been set in previous iterations. For +example, after +.sp + /(a|(b))+/ +.sp +matches "aba" the value of the second captured substring is "b". +. +. +.\" HTML +.SH "ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS" +.rs +.sp +With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy") +repetition, failure of what follows normally causes the repeated item to be +re-evaluated to see if a different number of repeats allows the rest of the +pattern to match. Sometimes it is useful to prevent this, either to change the +nature of the match, or to cause it fail earlier than it otherwise might, when +the author of the pattern knows there is no point in carrying on. +.P +Consider, for example, the pattern \ed+foo when applied to the subject line +.sp + 123456bar +.sp +After matching all 6 digits and then failing to match "foo", the normal +action of the matcher is to try again with only 5 digits matching the \ed+ +item, and then with 4, and so on, before ultimately failing. "Atomic grouping" +(a term taken from Jeffrey Friedl's book) provides the means for specifying +that once a subpattern has matched, it is not to be re-evaluated in this way. +.P +If we use atomic grouping for the previous example, the matcher gives up +immediately on failing to match "foo" the first time. The notation is a kind of +special parenthesis, starting with (?> as in this example: +.sp + (?>\ed+)foo +.sp +This kind of parenthesis "locks up" the part of the pattern it contains once +it has matched, and a failure further into the pattern is prevented from +backtracking into it. Backtracking past it to previous items, however, works as +normal. +.P +An alternative description is that a subpattern of this type matches the string +of characters that an identical standalone pattern would match, if anchored at +the current point in the subject string. +.P +Atomic grouping subpatterns are not capturing subpatterns. Simple cases such as +the above example can be thought of as a maximizing repeat that must swallow +everything it can. So, while both \ed+ and \ed+? are prepared to adjust the +number of digits they match in order to make the rest of the pattern match, +(?>\ed+) can only match an entire sequence of digits. +.P +Atomic groups in general can of course contain arbitrarily complicated +subpatterns, and can be nested. However, when the subpattern for an atomic +group is just a single repeated item, as in the example above, a simpler +notation, called a "possessive quantifier" can be used. This consists of an +additional + character following a quantifier. Using this notation, the +previous example can be rewritten as +.sp + \ed++foo +.sp +Note that a possessive quantifier can be used with an entire group, for +example: +.sp + (abc|xyz){2,3}+ +.sp +Possessive quantifiers are always greedy; the setting of the PCRE_UNGREEDY +option is ignored. They are a convenient notation for the simpler forms of +atomic group. However, there is no difference in the meaning of a possessive +quantifier and the equivalent atomic group, though there may be a performance +difference; possessive quantifiers should be slightly faster. +.P +The possessive quantifier syntax is an extension to the Perl 5.8 syntax. +Jeffrey Friedl originated the idea (and the name) in the first edition of his +book. Mike McCloskey liked it, so implemented it when he built Sun's Java +package, and PCRE copied it from there. It ultimately found its way into Perl +at release 5.10. +.P +PCRE has an optimization that automatically "possessifies" certain simple +pattern constructs. For example, the sequence A+B is treated as A++B because +there is no point in backtracking into a sequence of A's when B must follow. +.P +When a pattern contains an unlimited repeat inside a subpattern that can itself +be repeated an unlimited number of times, the use of an atomic group is the +only way to avoid some failing matches taking a very long time indeed. The +pattern +.sp + (\eD+|<\ed+>)*[!?] +.sp +matches an unlimited number of substrings that either consist of non-digits, or +digits enclosed in <>, followed by either ! or ?. When it matches, it runs +quickly. However, if it is applied to +.sp + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +.sp +it takes a long time before reporting failure. This is because the string can +be divided between the internal \eD+ repeat and the external * repeat in a +large number of ways, and all have to be tried. (The example uses [!?] rather +than a single character at the end, because both PCRE and Perl have an +optimization that allows for fast failure when a single character is used. They +remember the last single character that is required for a match, and fail early +if it is not present in the string.) If the pattern is changed so that it uses +an atomic group, like this: +.sp + ((?>\eD+)|<\ed+>)*[!?] +.sp +sequences of non-digits cannot be broken, and failure happens quickly. +. +. +.\" HTML +.SH "BACK REFERENCES" +.rs +.sp +Outside a character class, a backslash followed by a digit greater than 0 (and +possibly further digits) is a back reference to a capturing subpattern earlier +(that is, to its left) in the pattern, provided there have been that many +previous capturing left parentheses. +.P +However, if the decimal number following the backslash is less than 10, it is +always taken as a back reference, and causes an error only if there are not +that many capturing left parentheses in the entire pattern. In other words, the +parentheses that are referenced need not be to the left of the reference for +numbers less than 10. A "forward back reference" of this type can make sense +when a repetition is involved and the subpattern to the right has participated +in an earlier iteration. +.P +It is not possible to have a numerical "forward back reference" to a subpattern +whose number is 10 or more using this syntax because a sequence such as \e50 is +interpreted as a character defined in octal. See the subsection entitled +"Non-printing characters" +.\" HTML +.\" +above +.\" +for further details of the handling of digits following a backslash. There is +no such problem when named parentheses are used. A back reference to any +subpattern is possible using named parentheses (see below). +.P +Another way of avoiding the ambiguity inherent in the use of digits following a +backslash is to use the \eg escape sequence. This escape must be followed by an +unsigned number or a negative number, optionally enclosed in braces. These +examples are all identical: +.sp + (ring), \e1 + (ring), \eg1 + (ring), \eg{1} +.sp +An unsigned number specifies an absolute reference without the ambiguity that +is present in the older syntax. It is also useful when literal digits follow +the reference. A negative number is a relative reference. Consider this +example: +.sp + (abc(def)ghi)\eg{-1} +.sp +The sequence \eg{-1} is a reference to the most recently started capturing +subpattern before \eg, that is, is it equivalent to \e2 in this example. +Similarly, \eg{-2} would be equivalent to \e1. The use of relative references +can be helpful in long patterns, and also in patterns that are created by +joining together fragments that contain references within themselves. +.P +A back reference matches whatever actually matched the capturing subpattern in +the current subject string, rather than anything matching the subpattern +itself (see +.\" HTML +.\" +"Subpatterns as subroutines" +.\" +below for a way of doing that). So the pattern +.sp + (sens|respons)e and \e1ibility +.sp +matches "sense and sensibility" and "response and responsibility", but not +"sense and responsibility". If caseful matching is in force at the time of the +back reference, the case of letters is relevant. For example, +.sp + ((?i)rah)\es+\e1 +.sp +matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original +capturing subpattern is matched caselessly. +.P +There are several different ways of writing back references to named +subpatterns. The .NET syntax \ek{name} and the Perl syntax \ek or +\ek'name' are supported, as is the Python syntax (?P=name). Perl 5.10's unified +back reference syntax, in which \eg can be used for both numeric and named +references, is also supported. We could rewrite the above example in any of +the following ways: +.sp + (?(?i)rah)\es+\ek + (?'p1'(?i)rah)\es+\ek{p1} + (?P(?i)rah)\es+(?P=p1) + (?(?i)rah)\es+\eg{p1} +.sp +A subpattern that is referenced by name may appear in the pattern before or +after the reference. +.P +There may be more than one back reference to the same subpattern. If a +subpattern has not actually been used in a particular match, any back +references to it always fail by default. For example, the pattern +.sp + (a|(bc))\e2 +.sp +always fails if it starts to match "a" rather than "bc". However, if the +PCRE_JAVASCRIPT_COMPAT option is set at compile time, a back reference to an +unset value matches an empty string. +.P +Because there may be many capturing parentheses in a pattern, all digits +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 +white space. Otherwise, the \eg{ syntax or an empty comment (see +.\" HTML +.\" +"Comments" +.\" +below) can be used. +. +.SS "Recursive back references" +.rs +.sp +A back reference that occurs inside the parentheses to which it refers fails +when the subpattern is first used, so, for example, (a\e1) never matches. +However, such references can be useful inside repeated subpatterns. For +example, the pattern +.sp + (a|b\e1)+ +.sp +matches any number of "a"s and also "aba", "ababbaa" etc. At each iteration of +the subpattern, the back reference matches the character string corresponding +to the previous iteration. In order for this to work, the pattern must be such +that the first iteration does not need to match the back reference. This can be +done using alternation, as in the example above, or by a quantifier with a +minimum of zero. +.P +Back references of this type cause the group that they reference to be treated +as an +.\" HTML +.\" +atomic group. +.\" +Once the whole group has been matched, a subsequent matching failure cannot +cause backtracking into the middle of the group. +. +. +.\" HTML +.SH ASSERTIONS +.rs +.sp +An assertion is a test on the characters following or preceding the current +matching point that does not actually consume any characters. The simple +assertions coded as \eb, \eB, \eA, \eG, \eZ, \ez, ^ and $ are described +.\" HTML +.\" +above. +.\" +.P +More complicated assertions are coded as subpatterns. There are two kinds: +those that look ahead of the current position in the subject string, and those +that look behind it. An assertion subpattern is matched in the normal way, +except that it does not cause the current matching position to be changed. +.P +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" +.rs +.sp +Lookahead assertions start with (?= for positive assertions and (?! for +negative assertions. For example, +.sp + \ew+(?=;) +.sp +matches a word followed by a semicolon, but does not include the semicolon in +the match, and +.sp + foo(?!bar) +.sp +matches any occurrence of "foo" that is not followed by "bar". Note that the +apparently similar pattern +.sp + (?!foo)bar +.sp +does not find an occurrence of "bar" that is preceded by something other than +"foo"; it finds any occurrence of "bar" whatsoever, because the assertion +(?!foo) is always true when the next three characters are "bar". A +lookbehind assertion is needed to achieve the other effect. +.P +If you want to force a matching failure at some point in a pattern, the most +convenient way to do it is with (?!) because an empty string always matches, so +an assertion that requires there not to be an empty string must always fail. +The backtracking control verb (*FAIL) or (*F) is a synonym for (?!). +. +. +.\" HTML +.SS "Lookbehind assertions" +.rs +.sp +Lookbehind assertions start with (?<= for positive assertions and (? +.\" +(see above) +.\" +can be used instead of a lookbehind assertion to get round the fixed-length +restriction. +.P +The implementation of lookbehind assertions is, for each alternative, to +temporarily move the current position back by the fixed length and then try to +match. If there are insufficient characters before the current position, the +assertion fails. +.P +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 +.\" +"Subroutine" +.\" +calls (see below) such as (?2) or (?&X) are permitted in lookbehinds, as long +as the subpattern matches a fixed-length string. +.\" HTML +.\" +Recursion, +.\" +however, is not supported. +.P +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 +.sp + abcd$ +.sp +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 pattern is specified as +.sp + ^.*abcd$ +.sp +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, so we are no better off. However, +if the pattern is written as +.sp + ^.*+(?<=abcd) +.sp +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. +. +. +.SS "Using multiple assertions" +.rs +.sp +Several assertions (of any sort) may occur in succession. For example, +.sp + (?<=\ed{3})(? +.SH "CONDITIONAL SUBPATTERNS" +.rs +.sp +It is possible to cause the matching process to obey a subpattern +conditionally or to choose between two alternative subpatterns, depending on +the result of an assertion, or whether a specific capturing subpattern has +already been matched. The two possible forms of conditional subpattern are: +.sp + (?(condition)yes-pattern) + (?(condition)yes-pattern|no-pattern) +.sp +If the condition is satisfied, the yes-pattern is used; otherwise the +no-pattern (if present) is used. If there are more than two alternatives in the +subpattern, a compile-time error occurs. Each of the two alternatives may +itself contain nested subpatterns of any form, including conditional +subpatterns; the restriction to two alternatives applies only at the level of +the condition. This pattern fragment is an example where the alternatives are +complex: +.sp + (?(1) (A|B|C) | (D | (?(2)E|F) | E) ) +.sp +.P +There are four kinds of condition: references to subpatterns, references to +recursion, a pseudo-condition called DEFINE, and assertions. +. +.SS "Checking for a used subpattern by number" +.rs +.sp +If the text between the parentheses consists of a sequence of digits, the +condition is true if a capturing subpattern of that number has previously +matched. If there is more than one capturing subpattern with the same number +(see the earlier +.\" +.\" HTML +.\" +section about duplicate subpattern numbers), +.\" +the condition is true if any of them have matched. An alternative notation is +to precede the digits with a plus or minus sign. In this case, the subpattern +number is relative rather than absolute. The most recently opened parentheses +can be referenced by (?(-1), the next most recent by (?(-2), and so on. Inside +loops it can also make sense to refer to subsequent groups. The next +parentheses to be opened can be referenced as (?(+1), and so on. (The value +zero in any of these forms is not used; it provokes a compile-time error.) +.P +Consider the following pattern, which contains non-significant white space to +make it more readable (assume the PCRE_EXTENDED option) and to divide it into +three parts for ease of discussion: +.sp + ( \e( )? [^()]+ (?(1) \e) ) +.sp +The first part matches an optional opening parenthesis, and if that +character is present, sets it as the first captured substring. The second part +matches one or more characters that are not parentheses. The third part is a +conditional subpattern that tests whether or not the first set of parentheses +matched. If they did, that is, if subject started with an opening parenthesis, +the condition is true, and so the yes-pattern is executed and a closing +parenthesis is required. Otherwise, since no-pattern is not present, the +subpattern matches nothing. In other words, this pattern matches a sequence of +non-parentheses, optionally enclosed in parentheses. +.P +If you were embedding this pattern in a larger one, you could use a relative +reference: +.sp + ...other stuff... ( \e( )? [^()]+ (?(-1) \e) ) ... +.sp +This makes the fragment independent of the parentheses in the larger pattern. +. +.SS "Checking for a used subpattern by name" +.rs +.sp +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 syntax, 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 number, which must be greater than zero. Using subpattern +names that consist entirely of digits is not recommended. +.P +Rewriting the above example to use a named subpattern gives this: +.sp + (? \e( )? [^()]+ (?() \e) ) +.sp +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. +. +.SS "Checking for pattern recursion" +.rs +.sp +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 or any +subpattern has been made. If digits or a name preceded by ampersand follow the +letter R, for example: +.sp + (?(R3)...) or (?(R&name)...) +.sp +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 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. +.P +At "top level", all these recursion test conditions are false. +.\" HTML +.\" +The syntax for recursive patterns +.\" +is described below. +. +.\" HTML +.SS "Defining subpatterns for use by reference only" +.rs +.sp +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 referenced from elsewhere. (The use of +.\" HTML +.\" +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): +.sp + (?(DEFINE) (? 2[0-4]\ed | 25[0-5] | 1\ed\ed | [1-9]?\ed) ) + \eb (?&byte) (\e.(?&byte)){3} \eb +.sp +The first part of the pattern is a DEFINE group inside which a another group +named "byte" is defined. This matches an individual component of an IPv4 +address (a number less than 256). When matching takes place, this part of the +pattern is skipped because DEFINE acts like a false condition. The rest of the +pattern uses references to the named group to match the four dot-separated +components of an IPv4 address, insisting on a word boundary at each end. +. +.SS "Assertion conditions" +.rs +.sp +If the condition is not in any of the above formats, it must be an assertion. +This may be a positive or negative lookahead or lookbehind assertion. Consider +this pattern, again containing non-significant white space, and with the two +alternatives on the second line: +.sp + (?(?=[^a-z]*[a-z]) + \ed{2}-[a-z]{3}-\ed{2} | \ed{2}-\ed{2}-\ed{2} ) +.sp +The condition is a positive lookahead assertion that matches an optional +sequence of non-letters followed by a letter. In other words, it tests for the +presence of at least one letter in the subject. If a letter is found, the +subject is matched against the first alternative; otherwise it is matched +against the second. This pattern matches strings in one of the two forms +dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits. +. +. +.\" HTML +.SH COMMENTS +.rs +.sp +There are two ways of including comments in patterns that are processed by +PCRE. In both cases, the start of the comment must not be in a character class, +nor in the middle of any other sequence of related characters such as (?: or a +subpattern name or number. The characters that make up a comment play no part +in the pattern matching. +.P +The sequence (?# marks the start of a comment that continues up to the next +closing parenthesis. Nested parentheses are not permitted. If the PCRE_EXTENDED +option is set, an unescaped # character also introduces a comment, which in +this case continues to immediately after the next newline character or +character sequence in the pattern. Which characters are interpreted as newlines +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 +.\" +"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: +.sp + abc #comment \en still comment +.sp +On encountering the # character, \fBpcre_compile()\fP skips along, looking for +a newline in the pattern. The sequence \en is still literal at this stage, so +it does not terminate the comment. Only an actual character with the code value +0x0a (the default newline) does so. +. +. +.\" HTML +.SH "RECURSIVE PATTERNS" +.rs +.sp +Consider the problem of matching a string in parentheses, allowing for +unlimited nested parentheses. Without the use of recursion, the best that can +be done is to use a pattern that matches up to some fixed depth of nesting. It +is not possible to handle an arbitrary nesting depth. +.P +For some time, Perl has provided a facility that allows regular expressions to +recurse (amongst other things). It does this by interpolating Perl code in the +expression at run time, and the code can refer to the expression itself. A Perl +pattern using code interpolation to solve the parentheses problem can be +created like this: +.sp + $re = qr{\e( (?: (?>[^()]+) | (?p{$re}) )* \e)}x; +.sp +The (?p{...}) item interpolates Perl code at run time, and in this case refers +recursively to the pattern in which it appears. +.P +Obviously, PCRE cannot support the interpolation of Perl code. Instead, it +supports special syntax for recursion of the entire pattern, and also for +individual subpattern recursion. After its introduction in PCRE and Python, +this kind of recursion was subsequently introduced 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 subroutine call of the subpattern of the +given number, provided that it occurs inside that subpattern. (If not, it is a +.\" HTML +.\" +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. +.P +This PCRE pattern solves the nested parentheses problem (assume the +PCRE_EXTENDED option is set so that white space is ignored): +.sp + \e( ( [^()]++ | (?R) )* \e) +.sp +First it matches an opening parenthesis. Then it matches any number of +substrings which can either be a sequence of non-parentheses, or a recursive +match of the pattern itself (that is, a correctly parenthesized substring). +Finally there is a closing parenthesis. Note the use of a possessive quantifier +to avoid backtracking into sequences of non-parentheses. +.P +If this were part of a larger pattern, you would not want to recurse the entire +pattern, so instead you could use this: +.sp + ( \e( ( [^()]++ | (?1) )* \e) ) +.sp +We have put the pattern into parentheses, and caused the recursion to refer to +them instead of the whole pattern. +.P +In a larger pattern, keeping track of parenthesis numbers can be tricky. This +is made easier by the use of relative references. Instead of (?1) in the +pattern above you can write (?-2) to refer to the second most recently opened +parentheses preceding the recursion. In other words, a negative number counts +capturing parentheses leftwards from the point at which it is encountered. +.P +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 +.\" HTML +.\" +non-recursive subroutine +.\" +calls, as described in the next section. +.P +An alternative approach is to use named parentheses instead. The Perl syntax +for this is (?&name); PCRE's earlier syntax (?P>name) is also supported. We +could rewrite the above example as follows: +.sp + (? \e( ( [^()]++ | (?&pn) )* \e) ) +.sp +If there is more than one subpattern with the same name, the earliest one is +used. +.P +This particular example pattern that we have been looking at contains nested +unlimited repeats, and so the use of a possessive quantifier for matching +strings of non-parentheses is important when applying the pattern to strings +that do not match. For example, when this pattern is applied to +.sp + (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa() +.sp +it yields "no match" quickly. However, if a possessive quantifier is not used, +the match runs for a very long time indeed because there are so many different +ways the + and * repeats can carve up the subject, and all have to be tested +before failure can be reported. +.P +At the end of a match, the values of capturing parentheses are those from +the outermost level. If you want to obtain intermediate values, a callout +function can be used (see below and the +.\" HREF +\fBpcrecallout\fP +.\" +documentation). If the pattern above is matched against +.sp + (ab(cd)ef) +.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 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 +\fBpcre_malloc\fP, freeing it via \fBpcre_free\fP afterwards. If no memory can +be obtained, the match fails with the PCRE_ERROR_NOMEMORY error. +.P +Do not confuse the (?R) item with the condition (R), which tests for recursion. +Consider this pattern, which matches text in angle brackets, allowing for +arbitrary nesting. Only digits are allowed in nested brackets (that is, when +recursing), whereas any characters are permitted at the outer level. +.sp + < (?: (?(R) \ed++ | [^<>]*+) | (?R)) * > +.sp +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. +. +. +.\" HTML +.SS "Differences in recursion processing between PCRE and Perl" +.rs +.sp +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 +The idea is that it either matches a single character, or two identical +characters surrounding a sub-palindrome. In Perl, this pattern works; in PCRE +it does not if the pattern is longer than three characters. Consider the +subject string "abcba": +.P +At the top level, the first character is matched, but as it is not at the end +of the string, the first alternative fails; the second alternative is taken +and the recursion kicks in. The recursive call to subpattern 1 successfully +matches the next character ("b"). (Note that the beginning and end of line +tests are not part of the recursion). +.P +Back at the top level, the next character ("c") is compared with what +subpattern 2 matched, which was "a". This fails. Because the recursion is +treated as an atomic group, there are now no backtracking points, and so the +entire match fails. (Perl is able, at this point, to re-enter the recursion and +try the second alternative.) However, if the pattern is written with the +alternatives in the other order, things are different: +.sp + ^((.)(?1)\e2|.)$ +.sp +This time, the recursing alternative is tried first, and continues to recurse +until it runs out of characters, at which point the recursion fails. But this +time we do have another alternative to try at the higher level. That is the big +difference: in the previous case the remaining alternative is at a deeper +recursion level, which PCRE cannot use. +.P +To change the pattern so that it matches all palindromic strings, not just +those with an odd number of characters, it is tempting to change the pattern to +this: +.sp + ^((.)(?1)\e2|.?)$ +.sp +Again, this works in Perl, but not in PCRE, and for the same reason. When a +deeper recursion has matched a single character, it cannot be entered again in +order to match an empty string. The solution is to separate the two cases, and +write out the odd and even cases as alternatives at the higher level: +.sp + ^(?:((.)(?1)\e2|)|((.)(?3)\e4|.)) +.sp +If you want to match typical palindromic phrases, the pattern has to ignore all +non-word characters, which can be done like this: +.sp + ^\eW*+(?:((.)\eW*+(?1)\eW*+\e2|)|((.)\eW*+(?3)\eW*+\e4|\eW*+.\eW*+))\eW*+$ +.sp +If run with the PCRE_CASELESS option, this pattern matches phrases such as "A +man, a plan, a canal: Panama!" and it works well in both PCRE and Perl. Note +the use of the possessive quantifier *+ to avoid backtracking into sequences of +non-word characters. Without this, PCRE takes a great deal longer (ten times or +more) to match typical phrases, and Perl takes so long that you think it has +gone into a loop. +.P +\fBWARNING\fP: The palindrome-matching patterns above work only if the subject +string does not start with a palindrome that is shorter than the entire string. +For example, although "abcba" is correctly matched, if the subject is "ababa", +PCRE finds the palindrome "aba" at the start, then fails at top level because +the end of the string does not follow. Once again, it cannot jump back into the +recursion to try other 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 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: +.sp + (...(absolute)...)...(?2)... + (...(relative)...)...(?-1)... + (...(?+1)...(relative)... +.sp +An earlier example pointed out that the pattern +.sp + (sens|respons)e and \e1ibility +.sp +matches "sense and sensibility" and "response and responsibility", but not +"sense and responsibility". If instead the pattern +.sp + (sens|respons)e and (?1)ibility +.sp +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 +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 +It matches "abcabc". It does not match "abcABC" because the change of +processing option does not affect the called subpattern. +. +. +.\" HTML +.SH "ONIGURUMA SUBROUTINE SYNTAX" +.rs +.sp +For compatibility with Oniguruma, the non-Perl syntax \eg followed by a name or +a number enclosed either in angle brackets or single quotes, is an alternative +syntax for referencing a subpattern as a subroutine, possibly recursively. Here +are two of the examples used above, rewritten using this syntax: +.sp + (? \e( ( (?>[^()]+) | \eg )* \e) ) + (sens|respons)e and \eg'1'ibility +.sp +PCRE supports an extension to Oniguruma: if a number is preceded by a +plus or a minus sign it is taken as a relative reference. For example: +.sp + (abc)(?i:\eg<-1>) +.sp +Note that \eg{...} (Perl syntax) and \eg<...> (Oniguruma syntax) are \fInot\fP +synonymous. The former is a back reference; the latter is a subroutine call. +. +. +.SH CALLOUTS +.rs +.sp +Perl has a feature whereby using the sequence (?{...}) causes arbitrary Perl +code to be obeyed in the middle of matching a regular expression. This makes it +possible, amongst other things, to extract different substrings that match the +same pair of parentheses when there is a repetition. +.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 +(8-bit library) or \fIpcre[16|32]_callout\fP (16-bit or 32-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 +can put a number less than 256 after the letter C. The default value is zero. +For example, this pattern has two callout points: +.sp + (?C1)abc(?C2)def +.sp +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, 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 +.\" +documentation. +. +. +.\" HTML +.SH "BACKTRACKING CONTROL" +.rs +.sp +Perl 5.10 introduced a number of "Special Backtracking Control Verbs", which +are described in the Perl documentation as "experimental and subject to change +or removal in a future version of Perl". It goes on to say: "Their usage in +production code should be noted to avoid problems during upgrades." The same +remarks apply to the PCRE features described in this section. +.P +Since these verbs are specifically related to backtracking, most of them can be +used only when the pattern is to be matched using one of the traditional +matching functions, which use a backtracking algorithm. With the exception of +(*FAIL), which behaves like a failing negative assertion, they cause an error +if encountered by a DFA matching 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. A name is any sequence of +characters that does not include a closing parenthesis. The maximum length of +name is 255 in the 8-bit library and 65535 in the 16-bit and 32-bit library. +If the name is empty, that is, if the 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 +present. When one of these optimizations suppresses the running of a match, any +included backtracking verbs will not, of course, be processed. You can suppress +the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option +when calling \fBpcre_compile()\fP or \fBpcre_exec()\fP, or by starting the +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" +.rs +.sp +The following verbs act as soon as they are encountered. They may not be +followed by a name. +.sp + (*ACCEPT) +.sp +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: +.sp + A((?:A|B(*ACCEPT)|C)D) +.sp +This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is captured by +the outer parentheses. +.sp + (*FAIL) or (*F) +.sp +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 pattern: +.sp + a+(?C)(*FAIL) +.sp +A match with the string "aaaa" always fails, but the callout is taken before +each backtrack happens (in this example, 10 times). +. +. +.SS "Recording which path was taken" +.rs +.sp +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). +.sp + (*MARK:NAME) or (*:NAME) +.sp +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) on the matching +path is passed back to the caller as described in the section entitled +.\" HTML +.\" +"Extra data for \fBpcre_exec()\fP" +.\" +in the +.\" HREF +\fBpcreapi\fP +.\" +documentation. Here is an example of \fBpcretest\fP output, where the /K +modifier requests the retrieval and outputting of (*MARK) data: +.sp + re> /X(*MARK:A)Y|X(*MARK:B)Z/K + data> XY + 0: XY + MK: A + XZ + 0: XZ + MK: B +.sp +The (*MARK) name is tagged with "MK:" in this output, and in this example it +indicates which of the two alternatives matched. This is a more efficient way +of obtaining this information than putting each alternative in its own +capturing parentheses. +.P +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 + re> /X(*MARK:A)Y|X(*MARK:B)Z/K + data> XP + No match, mark = B +.sp +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" +.rs +.sp +The following verbs do nothing when they are encountered. Matching continues +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 backtracking 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.) +.P +These verbs differ in exactly what kind of failure occurs when backtracking +reaches them. +.sp + (*COMMIT) +.sp +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, \fBpcre_exec()\fP is committed to +finding a match at the current starting point, or not at all. For example: +.sp + a+(*COMMIT)b +.sp +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) forces a +match failure. +.P +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 +\fBpcretest\fP example: +.sp + re> /(*COMMIT)abc/ + data> xyzabc + 0: abc + xyzabc\eY + No match +.sp +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 \eY escape in the second subject, the match +starts at "x" and so the (*COMMIT) causes it to fail without trying any other +starting points. +.sp + (*PRUNE) or (*PRUNE:NAME) +.sp +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 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). In an +anchored pattern (*PRUNE) has the same effect as (*COMMIT). +.sp + (*SKIP) +.sp +This verb, when given without a name, is like (*PRUNE), except that if the +pattern is unanchored, the "bumpalong" advance is not to the next character, +but to the position in the subject where (*SKIP) was encountered. (*SKIP) +signifies that whatever text was matched leading up to it cannot be part of a +successful match. Consider: +.sp + a+(*SKIP)b +.sp +If the subject is "aaaac...", after the first match attempt fails (starting at +the first character in the string), the starting point skips on to start the +next attempt at "c". Note that a possessive quantifer does not have the same +effect as this example; although it would suppress backtracking during the +first match attempt, the second attempt would start at the second character +instead of skipping on to "c". +.sp + (*SKIP:NAME) +.sp +When (*SKIP) has an associated name, its behaviour is modified. If the +following pattern fails to match, the previous path through the pattern is +searched for the most recent (*MARK) that has the same name. If one is found, +the "bumpalong" advance is to the subject position that corresponds to that +(*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a +matching name is found, the (*SKIP) is ignored. +.sp + (*THEN) or (*THEN:NAME) +.sp +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 +second alternative and tries COND2, without backtracking into COND1. The +behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN). +If (*THEN) is not inside an alternation, it acts like (*PRUNE). +.P +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 alternative (that is, D) does not happen because (*COMMIT) +overrides. +. +. +.SH "SEE ALSO" +.rs +.sp +\fBpcreapi\fP(3), \fBpcrecallout\fP(3), \fBpcrematching\fP(3), +\fBpcresyntax\fP(3), \fBpcre\fP(3), \fBpcre16(3)\fP, \fBpcre32(3)\fP. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 11 November 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcreperform.3 b/tools/pcre/doc/pcreperform.3 new file mode 100644 index 00000000..fb2aa959 --- /dev/null +++ b/tools/pcre/doc/pcreperform.3 @@ -0,0 +1,177 @@ +.TH PCREPERFORM 3 "09 January 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH "PCRE PERFORMANCE" +.rs +.sp +Two aspects of performance are discussed below: memory usage and processing +time. The way you express your pattern as a regular expression can affect both +of them. +. +.SH "COMPILED PATTERN MEMORY USAGE" +.rs +.sp +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 +.sp + (abc|def){2,4} +.sp +is compiled as if it were +.sp + (abc|def)(abc|def)((abc|def)(abc|def)?)? +.sp +(Technical aside: It is done this way so that backtrack points within each of +the repetitions can be independently maintained.) +.P +For regular expressions whose quantifiers use only small numbers, this is not +usually a problem. However, if the numbers are large, and particularly if such +repetitions are nested, the memory usage can become an embarrassment. For +example, the very simple pattern +.sp + ((ab){1,1000}c){1,3} +.sp +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 +.\" +"subroutine" +.\" +facility. Re-writing the above pattern as +.sp + ((ab)(?2){0,999}c)(?1){0,2} +.sp +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 +.\" HTML +.\" +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. +. +. +.SH "STACK USAGE AT RUN TIME" +.rs +.sp +When \fBpcre_exec()\fP or \fBpcre[16|32]_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 +.\" +documentation discusses this issue in detail. +. +. +.SH "PROCESSING TIME" +.rs +.sp +Certain items in regular expression patterns are processed more efficiently +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 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 observations about PCRE. +.P +Using Unicode character properties (the \ep, \eP, and \eX escapes) is slow, +because PCRE has to use a multi-stage table lookup 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. +.P +By default, the escape sequences \eb, \ed, \es, and \ew, 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 \ed, 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 +\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 +pattern is implicitly anchored by PCRE, since it can match only at the start of +a subject string. However, if PCRE_DOTALL is not set, PCRE cannot make this +optimization, because the . metacharacter does not then match a newline, and if +the subject string contains newlines, the pattern may match from the character +immediately following one of them instead of from the very start. For example, +the pattern +.sp + .*second +.sp +matches the subject "first\enand second" (where \en stands for a newline +character), with the match starting at the seventh character. In order to do +this, PCRE has to retry the match starting after every newline in the subject. +.P +If you are using such a pattern with subject strings that do not contain +newlines, the best performance is obtained by setting PCRE_DOTALL, or starting +the pattern with ^.* or ^.*? to indicate explicit anchoring. That saves PCRE +from having to scan along the subject looking for a newline to restart at. +.P +Beware of patterns that contain nested indefinite repeats. These can take a +long time to run when applied to a string that does not match. Consider the +pattern fragment +.sp + ^(a+)* +.sp +This can match "aaaa" in 16 different ways, and this number increases very +rapidly as the string gets longer. (The * repeat can match 0, 1, 2, 3, or 4 +times, and for each of those cases other than 0 or 4, the + repeats can match +different numbers of times.) When the remainder of the pattern is such that the +entire match is going to fail, PCRE has in principle to try every possible +variation, and this can take an extremely long time, even for relatively short +strings. +.P +An optimization catches some of the more simple cases such as +.sp + (a+)*b +.sp +where a literal character follows. Before embarking on the standard matching +procedure, PCRE checks that there is a "b" later in the subject string, and if +there is not, it fails the match immediately. However, when there is no +following literal this optimization cannot be used. You can see the difference +by comparing the behaviour of +.sp + (a+)*\ed +.sp +with the pattern above. The former gives a failure almost instantly when +applied to a whole line of "a" characters, whereas the latter takes an +appreciable time with strings longer than about 20 characters. +.P +In many cases, the solution to this kind of performance issue is to use an +atomic group or a possessive quantifier. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 25 August 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcreposix.3 b/tools/pcre/doc/pcreposix.3 new file mode 100644 index 00000000..b25a8919 --- /dev/null +++ b/tools/pcre/doc/pcreposix.3 @@ -0,0 +1,270 @@ +.TH PCREPOSIX 3 "09 January 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions. +.SH "SYNOPSIS OF POSIX API" +.rs +.sp +.B #include +.PP +.SM +.B int regcomp(regex_t *\fIpreg\fP, const char *\fIpattern\fP, +.ti +5n +.B int \fIcflags\fP); +.PP +.B int regexec(regex_t *\fIpreg\fP, const char *\fIstring\fP, +.ti +5n +.B size_t \fInmatch\fP, regmatch_t \fIpmatch\fP[], int \fIeflags\fP); +.PP +.B size_t regerror(int \fIerrcode\fP, const regex_t *\fIpreg\fP, +.ti +5n +.B char *\fIerrbuf\fP, size_t \fIerrbuf_size\fP); +.PP +.B void regfree(regex_t *\fIpreg\fP); +. +.SH DESCRIPTION +.rs +.sp +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. There is no POSIX-style wrapper for PCRE's 16-bit +and 32-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 +header file, and on Unix systems the library itself is called +\fBpcreposix.a\fP, so can be accessed by adding \fB-lpcreposix\fP to the +command for linking an application that uses them. Because the POSIX functions +call the native ones, it is also necessary to add \fB-lpcre\fP. +.P +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. +.P +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. +.P +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 expressions 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. +.P +The header for these functions is supplied as \fBpcreposix.h\fP to avoid any +potential clash with other POSIX libraries. It can, of course, be renamed or +aliased as \fBregex.h\fP, which is the "correct" name. It provides two +structure types, \fIregex_t\fP for compiled internal forms, and +\fIregmatch_t\fP for returning captured substrings. It also defines some +constants whose names start with "REG_"; these are used for setting options and +identifying error codes. +. +. +.SH "COMPILING A PATTERN" +.rs +.sp +The function \fBregcomp()\fP 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 \fIpattern\fP. The \fIpreg\fP argument is a pointer +to a \fBregex_t\fP structure that is used as a base for storing information +about the compiled regular expression. +.P +The argument \fIcflags\fP is either zero, or contains one or more of the bits +defined by the following macros: +.sp + REG_DOTALL +.sp +The PCRE_DOTALL option is set when the regular expression is passed for +compilation to the native function. Note that REG_DOTALL is not part of the +POSIX standard. +.sp + REG_ICASE +.sp +The PCRE_CASELESS option is set when the regular expression is passed for +compilation to the native function. +.sp + REG_NEWLINE +.sp +The PCRE_MULTILINE option is set when the regular expression is passed for +compilation to the native function. Note that this does \fInot\fP mimic the +defined POSIX behaviour for REG_NEWLINE (see the following section). +.sp + REG_NOSUB +.sp +The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is passed +for compilation to the native function. In addition, when a pattern that is +compiled with this flag is passed to \fBregexec()\fP for matching, the +\fInmatch\fP and \fIpmatch\fP arguments are ignored, and no captured strings +are returned. +.sp + REG_UCP +.sp +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 \ed, \ew, etc., instead of just recognizing ASCII values. Note +that REG_UTF8 is not part of the POSIX standard. +.sp + REG_UNGREEDY +.sp +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. +.sp + REG_UTF8 +.sp +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. +.P +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 +\fIsome\fP 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). +.P +The yield of \fBregcomp()\fP is zero on success, and non-zero otherwise. The +\fIpreg\fP structure is filled in on success, and one member of the structure +is public: \fIre_nsub\fP contains the number of capturing subpatterns in +the regular expression. Various error codes are defined in the header file. +.P +NOTE: If the yield of \fBregcomp()\fP is non-zero, you must not attempt to +use the contents of the \fIpreg\fP structure. If, for example, you pass it to +\fBregexec()\fP, the result is undefined and your program is likely to crash. +. +. +.SH "MATCHING NEWLINE CHARACTERS" +.rs +.sp +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 PCRE: +.sp + Default Change with +.sp + . matches newline no PCRE_DOTALL + newline matches [^a] yes not changeable + $ matches \en at end yes PCRE_DOLLARENDONLY + $ matches \en in middle no PCRE_MULTILINE + ^ matches \en in middle no PCRE_MULTILINE +.sp +This is the equivalent table for POSIX: +.sp + Default Change with +.sp + . matches newline yes REG_NEWLINE + newline matches [^a] yes REG_NEWLINE + $ matches \en at end no REG_NEWLINE + $ matches \en in middle no REG_NEWLINE + ^ matches \en in middle no REG_NEWLINE +.sp +PCRE's behaviour is the same as Perl's, except that there is no equivalent for +PCRE_DOLLAR_ENDONLY in Perl. In both PCRE and Perl, there is no way to stop +newline from matching [^a]. +.P +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. +. +. +.SH "MATCHING A PATTERN" +.rs +.sp +The function \fBregexec()\fP is called to match a compiled pattern \fIpreg\fP +against a given \fIstring\fP, which is by default terminated by a zero byte +(but see REG_STARTEND below), subject to the options in \fIeflags\fP. These can +be: +.sp + REG_NOTBOL +.sp +The PCRE_NOTBOL option is set when calling the underlying PCRE matching +function. +.sp + REG_NOTEMPTY +.sp +The PCRE_NOTEMPTY option is set when calling the underlying PCRE matching +function. Note that REG_NOTEMPTY is not part of the POSIX standard. However, +setting this option can give more POSIX-like behaviour in some situations. +.sp + REG_NOTEOL +.sp +The PCRE_NOTEOL option is set when calling the underlying PCRE matching +function. +.sp + REG_STARTEND +.sp +The string is considered to start at \fIstring\fP + \fIpmatch[0].rm_so\fP and +to have a terminating NUL located at \fIstring\fP + \fIpmatch[0].rm_eo\fP +(there need not actually be a NUL at that location), regardless of the value of +\fInmatch\fP. 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 \fIrm_so\fP does +not imply REG_NOTBOL; REG_STARTEND affects only the location of the string, not +how it is matched. +.P +If the pattern was compiled with the REG_NOSUB flag, no data about any matched +strings is returned. The \fInmatch\fP and \fIpmatch\fP arguments of +\fBregexec()\fP are ignored. +.P +If the value of \fInmatch\fP is zero, or if the value \fIpmatch\fP is NULL, +no data about any matched strings is returned. +.P +Otherwise,the portion of the string that was matched, and also any captured +substrings, are returned via the \fIpmatch\fP argument, which points to an +array of \fInmatch\fP structures of type \fIregmatch_t\fP, containing the +members \fIrm_so\fP and \fIrm_eo\fP. 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 \fIstring\fP 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. +.P +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. +. +. +.SH "ERROR MESSAGES" +.rs +.sp +The \fBregerror()\fP function maps a non-zero errorcode from either +\fBregcomp()\fP or \fBregexec()\fP to a printable message. If \fIpreg\fP is not +NULL, the error should have arisen from the use of that structure. A message +terminated by a binary zero is placed in \fIerrbuf\fP. The length of the +message, including the zero, is limited to \fIerrbuf_size\fP. The yield of the +function is the size of buffer needed to hold the whole message. +. +. +.SH MEMORY USAGE +.rs +.sp +Compiling a regular expression causes memory to be allocated and associated +with the \fIpreg\fP structure. The function \fBregfree()\fP frees all such +memory, after which \fIpreg\fP may no longer be used as a compiled expression. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 09 January 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcreprecompile.3 b/tools/pcre/doc/pcreprecompile.3 new file mode 100644 index 00000000..39eb82b0 --- /dev/null +++ b/tools/pcre/doc/pcreprecompile.3 @@ -0,0 +1,151 @@ +.TH PCREPRECOMPILE 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH "SAVING AND RE-USING PRECOMPILED PCRE PATTERNS" +.rs +.sp +If you are running an application that uses a large number of regular +expression patterns, it may be useful to store them in a precompiled form +instead of having to compile them every time the application is run. +If you are not using any private character tables (see the +.\" HREF +\fBpcre_maketables()\fP +.\" +documentation), this is relatively straightforward. 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. +.P +If you save compiled patterns to a file, you can copy them to a different host +and run them there. If the two hosts have different endianness (byte order), +you should run the \fBpcre[16|32]_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[16|32]_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|32]_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; + pcre *re; +.sp + re = pcre_compile("my pattern", 0, &error, &erroroffset, NULL); + if (re == NULL) { ... handle errors ... } + rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); + if (rc < 0) { ... handle errors ... } + rc = fwrite(re, 1, size, fd); + if (rc != size) { ... handle errors ... } +.sp +In this example, the bytes that comprise the compiled pattern are copied +exactly. Note that this is binary data that may contain any of the 256 possible +byte values. On systems that make a distinction between binary and non-binary +data, be sure that the file is opened for binary output. +.P +If you want to write more than one pattern to a file, you will have to devise a +way of separating them. For binary data, preceding each pattern with its length +is probably the most straightforward approach. Another possibility is to write +out the data in hexadecimal instead of binary, one pattern to a line. +.P +Saving compiled patterns in a file is only one possible way of storing them for +later use. They could equally well be saved in a database, or in the memory of +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 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|32]_study()\fP returns a pointer to a +\fBpcre[16|32]_extra\fP data block. Its format is defined in the +.\" HTML +.\" +section on matching a pattern +.\" +in the +.\" HREF +\fBpcreapi\fP +.\" +documentation. The \fIstudy_data\fP field points to the binary study data, and +this is what you must save (not the \fBpcre[16|32]_extra\fP block itself). The +length of the study data can be obtained by calling \fBpcre[16|32]_fullinfo()\fP +with an argument of PCRE_INFO_STUDYSIZE. Remember to check that +\fBpcre[16|32]_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, called \fBpcre[16|32]_pattern_to_host_byte_order()\fP if necessary, +you pass its pointer to \fBpcre[16|32]_exec()\fP or \fBpcre[16|32]_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[16|32]_compile()\fP), you +must now pass a similar pointer to \fBpcre[16|32]_exec()\fP or +\fBpcre[16|32]_dfa_exec()\fP, because the value saved with the compiled pattern +will obviously be nonsense. A field in a \fBpcre[16|32]_extra()\fP block is used +to pass this data, as described in the +.\" HTML +.\" +section on matching a pattern +.\" +in the +.\" HREF +\fBpcreapi\fP +.\" +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 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[16|32]_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[16|32]_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" +.rs +.sp +In general, it is safest to recompile all saved patterns when you update to a +new PCRE release, though not all updates actually require this. +. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 24 June 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcresample.3 b/tools/pcre/doc/pcresample.3 new file mode 100644 index 00000000..d7fe7ec5 --- /dev/null +++ b/tools/pcre/doc/pcresample.3 @@ -0,0 +1,99 @@ +.TH PCRESAMPLE 3 "10 January 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH "PCRE SAMPLE PROGRAM" +.rs +.sp +A simple, complete demonstration program, to get you started with using PCRE, +is supplied in the file \fIpcredemo.c\fP in the PCRE distribution. A listing of +this program is given in the +.\" HREF +\fBpcredemo\fP +.\" +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 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 +string. The logic is a little bit tricky because of the possibility of matching +an empty string. Comments in the code explain what is going on. +.P +If PCRE is installed in the standard include and library directories for your +operating system, you should be able to compile the demonstration program using +this command: +.sp + gcc -o pcredemo pcredemo.c -lpcre +.sp +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 +\fI/usr/local\fP, you can compile the demonstration program using a command +like this: +.sp +.\" JOINSH + gcc -o pcredemo -I/usr/local/include pcredemo.c \e + -L/usr/local/lib -lpcre +.sp +In a Windows environment, if you want to statically link the program against a +non-dll \fBpcre.a\fP file, you must uncomment the line that defines PCRE_STATIC +before including \fBpcre.h\fP, because otherwise the \fBpcre_malloc()\fP and +\fBpcre_free()\fP exported functions will be declared +\fB__declspec(dllimport)\fP, with unwanted results. +.P +Once you have compiled and linked the demonstration program, you can run simple +tests like this: +.sp + ./pcredemo 'cat|dog' 'the cat sat on the mat' + ./pcredemo -g 'cat|dog' 'the dog sat on the cat' +.sp +Note that there is a much more comprehensive test program, called +.\" HREF +\fBpcretest\fP, +.\" +which supports many more facilities for testing regular expressions and both +PCRE libraries. The +.\" HREF +\fBpcredemo\fP +.\" +program is provided as a simple coding example. +.P +If you try to run +.\" HREF +\fBpcredemo\fP +.\" +when PCRE is not installed in the standard library directory, you may get an +error like this on some operating systems (e.g. Solaris): +.sp + ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or directory +.sp +This is caused by the way shared library support works on those systems. You +need to add +.sp + -R/usr/local/lib +.sp +(for example) to the compile command to get round this problem. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 10 January 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcrestack.3 b/tools/pcre/doc/pcrestack.3 new file mode 100644 index 00000000..798f0bca --- /dev/null +++ b/tools/pcre/doc/pcrestack.3 @@ -0,0 +1,215 @@ +.TH PCRESTACK 3 "24 June 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH "PCRE DISCUSSION OF STACK USAGE" +.rs +.sp +When you call \fBpcre[16|32]_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 +different numbers of a's. Furthermore, in a number of cases where the result of +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 above comments apply when \fBpcre[16|32]_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|32]_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|32]_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|32]_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|32]_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[16|32]_dfa_exec()\fP; they are +relevant only for \fBpcre[16|32]_exec()\fP without the JIT optimization. +. +. +.SS "Reducing \fBpcre[16|32]_exec()\fP's stack usage" +.rs +.sp +Each time that \fBmatch()\fP is actually called recursively, it uses memory +from the process stack. For certain kinds of pattern and data, very large +amounts of stack may be needed, despite the recognition of "tail recursion". +You can often reduce the amount of recursion, and therefore the amount of stack +used, by modifying the pattern that is being matched. Consider, for example, +this pattern: +.sp + ([^<]|<(?!inet))+ +.sp +It matches from wherever it starts until it encounters " +.\" +section on extra data for \fBpcre[16|32]_exec()\fP +.\" +in the +.\" HREF +\fBpcreapi\fP +.\" +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. +.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[16|32]_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 +In Unix-like environments, there is not often a problem with the stack unless +very long strings are involved, though the default limit on stack size varies +from system to system. Values from 8Mb to 64Mb are common. You can find your +default limit by running the command: +.sp + ulimit -s +.sp +Unfortunately, the effect of running out of stack is often SIGSEGV, though +sometimes a more explicit error message is given. You can normally increase the +limit on stack size by code such as this: +.sp + struct rlimit rlim; + getrlimit(RLIMIT_STACK, &rlim); + rlim.rlim_cur = 100*1024*1024; + setrlimit(RLIMIT_STACK, &rlim); +.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[16|32]_exec()\fP. +. +. +.SS "Changing stack size in Mac OS X" +.rs +.sp +Using \fBsetrlimit()\fP, as described above, should also work on Mac OS X. It +is also possible to set a stack size when linking a program. There is a +discussion about stack sizes in Mac OS X at this web site: +.\" HTML +.\" +http://developer.apple.com/qa/qa2005/qa1419.html. +.\" +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 24 June 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcresyntax.3 b/tools/pcre/doc/pcresyntax.3 new file mode 100644 index 00000000..868f427d --- /dev/null +++ b/tools/pcre/doc/pcresyntax.3 @@ -0,0 +1,496 @@ +.TH PCRESYNTAX 3 "11 November 2012" "PCRE 8.32" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH "PCRE REGULAR EXPRESSION SYNTAX SUMMARY" +.rs +.sp +The full syntax and semantics of the regular expressions that are supported by +PCRE are described in the +.\" HREF +\fBpcrepattern\fP +.\" +documentation. This document contains a quick-reference summary of the syntax. +. +. +.SH "QUOTING" +.rs +.sp + \ex where x is non-alphanumeric is a literal x + \eQ...\eE treat enclosed characters as literal +. +. +.SH "CHARACTERS" +.rs +.sp + \ea alarm, that is, the BEL character (hex 07) + \ecx "control-x", where x is any ASCII character + \ee escape (hex 1B) + \ef form feed (hex 0C) + \en newline (hex 0A) + \er carriage return (hex 0D) + \et tab (hex 09) + \eddd character with octal code ddd, or backreference + \exhh character with hex code hh + \ex{hhh..} character with hex code hhh.. +. +. +.SH "CHARACTER TYPES" +.rs +.sp + . any character except newline; + in dotall mode, any character whatsoever + \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 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 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 a Unicode extended grapheme cluster +.sp +In PCRE, by default, \ed, \eD, \es, \eS, \ew, and \eW recognize only ASCII +characters, even in a UTF mode. However, this can be changed by setting the +PCRE_UCP option. +. +. +.SH "GENERAL CATEGORY PROPERTIES FOR \ep and \eP" +.rs +.sp + C Other + Cc Control + Cf Format + Cn Unassigned + Co Private use + Cs Surrogate +.sp + L Letter + Ll Lower case letter + Lm Modifier letter + Lo Other letter + Lt Title case letter + Lu Upper case letter + L& Ll, Lu, or Lt +.sp + M Mark + Mc Spacing mark + Me Enclosing mark + Mn Non-spacing mark +.sp + N Number + Nd Decimal number + Nl Letter number + No Other number +.sp + P Punctuation + Pc Connector punctuation + Pd Dash punctuation + Pe Close punctuation + Pf Final punctuation + Pi Initial punctuation + Po Other punctuation + Ps Open punctuation +.sp + S Symbol + Sc Currency symbol + Sk Modifier symbol + Sm Mathematical symbol + So Other symbol +.sp + Z Separator + Zl Line separator + Zp Paragraph separator + Zs Space separator +. +. +.SH "PCRE SPECIAL CATEGORY PROPERTIES FOR \ep and \eP" +.rs +.sp + Xan Alphanumeric: union of properties L and N + Xps POSIX space: property Z or tab, NL, VT, FF, CR + Xsp Perl space: property Z or tab, NL, FF, CR + Xwd Perl word: property Xan or underscore +. +. +.SH "SCRIPT NAMES FOR \ep AND \eP" +.rs +.sp +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, +Hiragana, +Imperial_Aramaic, +Inherited, +Inscriptional_Pahlavi, +Inscriptional_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, +Samaritan, +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. +. +. +.SH "CHARACTER CLASSES" +.rs +.sp + [...] positive character class + [^...] negative character class + [x-y] range (can be used for hex characters) + [[:xxx:]] positive POSIX named set + [[:^xxx:]] negative POSIX named set +.sp + alnum alphanumeric + alpha alphabetic + ascii 0-127 + blank space or tab + cntrl control character + digit decimal digit + graph printing, excluding space + lower lower case letter + print printing, including space + punct printing, excluding alphanumeric + space white space + upper upper case letter + word same as \ew + xdigit hexadecimal digit +.sp +In PCRE, POSIX character set names recognize only ASCII characters by default, +but some of them use Unicode properties if PCRE_UCP is set. You can use +\eQ...\eE inside a character class. +. +. +.SH "QUANTIFIERS" +.rs +.sp + ? 0 or 1, greedy + ?+ 0 or 1, possessive + ?? 0 or 1, lazy + * 0 or more, greedy + *+ 0 or more, possessive + *? 0 or more, lazy + + 1 or more, greedy + ++ 1 or more, possessive + +? 1 or more, lazy + {n} exactly n + {n,m} at least n, no more than m, greedy + {n,m}+ at least n, no more than m, possessive + {n,m}? at least n, no more than m, lazy + {n,} n or more, greedy + {n,}+ n or more, possessive + {n,}? n or more, lazy +. +. +.SH "ANCHORS AND SIMPLE ASSERTIONS" +.rs +.sp + \eb word boundary + \eB not a word boundary + ^ start of subject + also after internal newline in multiline mode + \eA start of subject + $ end of subject + also before newline at end of subject + also before internal newline in multiline mode + \eZ end of subject + also before newline at end of subject + \ez end of subject + \eG first matching position in subject +. +. +.SH "MATCH POINT RESET" +.rs +.sp + \eK reset start of match +. +. +.SH "ALTERNATION" +.rs +.sp + expr|expr|expr... +. +. +.SH "CAPTURING" +.rs +.sp + (...) capturing group + (?...) named capturing group (Perl) + (?'name'...) named capturing group (Perl) + (?P...) named capturing group (Python) + (?:...) non-capturing group + (?|...) non-capturing group; reset group numbers for + capturing groups in each alternative +. +. +.SH "ATOMIC GROUPS" +.rs +.sp + (?>...) atomic, non-capturing group +. +. +. +. +.SH "COMMENT" +.rs +.sp + (?#....) comment (not nestable) +. +. +.SH "OPTION SETTING" +.rs +.sp + (?i) caseless + (?J) allow duplicate names + (?m) multiline + (?s) single line (dotall) + (?U) default ungreedy (lazy) + (?x) extended (ignore white space) + (?-...) unset option(s) +.sp +The following are recognized only at the start of a pattern or after one of the +newline-setting options with similar syntax: +.sp + (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE) + (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8) + (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16) + (*UTF32) set UTF-32 mode: 32-bit library (PCRE_UTF32) + (*UTF) set appropriate UTF mode for the library in use + (*UCP) set PCRE_UCP (use Unicode properties for \ed etc) +. +. +.SH "LOOKAHEAD AND LOOKBEHIND ASSERTIONS" +.rs +.sp + (?=...) positive look ahead + (?!...) negative look ahead + (?<=...) positive look behind + (? reference by name (Perl) + \ek'name' reference by name (Perl) + \eg{name} reference by name (Perl) + \ek{name} reference by name (.NET) + (?P=name) reference by name (Python) +. +. +.SH "SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)" +.rs +.sp + (?R) recurse whole pattern + (?n) call subpattern by absolute number + (?+n) call subpattern by relative number + (?-n) call subpattern by relative number + (?&name) call subpattern by name (Perl) + (?P>name) call subpattern by name (Python) + \eg call subpattern by name (Oniguruma) + \eg'name' call subpattern by name (Oniguruma) + \eg call subpattern by absolute number (Oniguruma) + \eg'n' call subpattern by absolute number (Oniguruma) + \eg<+n> call subpattern by relative number (PCRE extension) + \eg'+n' call subpattern by relative number (PCRE extension) + \eg<-n> call subpattern by relative number (PCRE extension) + \eg'-n' call subpattern by relative number (PCRE extension) +. +. +.SH "CONDITIONAL PATTERNS" +.rs +.sp + (?(condition)yes-pattern) + (?(condition)yes-pattern|no-pattern) +.sp + (?(n)... absolute reference condition + (?(+n)... relative reference condition + (?(-n)... relative reference condition + (?()... named reference condition (Perl) + (?('name')... named reference condition (Perl) + (?(name)... named reference condition (PCRE) + (?(R)... overall recursion condition + (?(Rn)... specific group recursion condition + (?(R&name)... specific recursion condition + (?(DEFINE)... define subpattern for reference + (?(assert)... assertion condition +. +. +.SH "BACKTRACKING CONTROL" +.rs +.sp +The following act immediately they are reached: +.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 +afterwards. Those that advance the start-of-match point do so only if the +pattern is not anchored. +.sp + (*COMMIT) overall failure, no advance of starting point + (*PRUNE) advance to next starting character + (*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_...), (*UTF8), (*UTF16), (*UTF32) or (*UCP) option. +.sp + (*CR) carriage return only + (*LF) linefeed only + (*CRLF) carriage return followed by linefeed + (*ANYCRLF) all three of the above + (*ANY) any Unicode newline sequence +. +. +.SH "WHAT \eR MATCHES" +.rs +.sp +These are recognized only at the very start of the pattern or after a +(*...) 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 +. +. +.SH "CALLOUTS" +.rs +.sp + (?C) callout + (?Cn) callout with data n +. +. +.SH "SEE ALSO" +.rs +.sp +\fBpcrepattern\fP(3), \fBpcreapi\fP(3), \fBpcrecallout\fP(3), +\fBpcrematching\fP(3), \fBpcre\fP(3). +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 11 November 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/pcretest.1 b/tools/pcre/doc/pcretest.1 new file mode 100644 index 00000000..41ef6ac2 --- /dev/null +++ b/tools/pcre/doc/pcretest.1 @@ -0,0 +1,1079 @@ +.TH PCRETEST 1 "10 September 2012" "PCRE 8.32" +.SH NAME +pcretest - a program for testing Perl-compatible regular expressions. +.SH SYNOPSIS +.rs +.sp +.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 +expressions. This document describes the features of the test program; for +details of the regular expressions themselves, see the +.\" HREF +\fBpcrepattern\fP +.\" +documentation. For details of the PCRE library function calls and their +options, see the +.\" HREF +\fBpcreapi\fP +.\" +, +.\" HREF +\fBpcre16\fP +and +.\" HREF +\fBpcre32\fP +.\" +documentation. +.P +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. +.P +As PCRE has evolved, it has acquired many different features, and as a result, +\fBpcretest\fP now has rather a lot of obscure options for testing every +possible feature. Some of these options are specifically designed for use in +conjunction with the test script and data files that are distributed as part of +PCRE, and are unlikely to be of use otherwise. They are all documented here, +but without much justification. +. +. +.SH "PCRE's 8-BIT, 16-BIT AND 32-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. From release 8.32, a third +library can be built, supporting character strings encoded in 32-bit units. +The \fBpcretest\fP program can be +used to test all three libraries. However, it is itself still an 8-bit program, +reading 8-bit input and writing 8-bit output. When testing the 16-bit or 32-bit +library, the patterns and data strings are converted to 16- or 32-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|32]_xx\fP below +mean "\fBpcre_xx\fP when using the 8-bit library or \fBpcre16_xx\fP when using +the 16-bit library". +. +. +.SH "COMMAND LINE OPTIONS" +.rs +.TP 10 +\fB-8\fP +If both the 8-bit library has been built, this option causes the 8-bit library +to be used (which is the default); if the 8-bit library has not been built, +this option causes an error. +.TP 10 +\fB-16\fP +If both the 8-bit or the 32-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 or the 32-bit +library has been built, this option causes an error. +.TP 10 +\fB-32\fP +If both the 8-bit or the 16-bit, and the 32-bit libraries have been built, this +option causes the 32-bit library to be used. If only the 32-bit library has been +built, this is the default (so has no effect). If only the 8-bit or the 16-bit +library has been built, this option causes an error. +.TP 10 +\fB-b\fP +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. 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 + ebcdic-nl the code for LF (= NL) in an EBCDIC environment: + 0x15 or 0x25 + 0 if used in an ASCII environment + 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 + ebcdic compiled for an EBCDIC environment + jit just-in-time support is available + pcre16 the 16-bit library was built + pcre32 the 32-bit library was built + pcre8 the 8-bit library was built + ucp Unicode property support is available + utf UTF-8 and/or UTF-16 and/or UTF-32 support is available +.TP 10 +\fB-d\fP +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[16|32]_dfa_exec()\fP, to be used instead +of the standard \fBpcre[16|32]_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 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[16|32]_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. 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[16|32]_exec()\fP or \fBpcre[16|32]_dfa_exec()\fP to be \fIosize\fP. The +default value is 45, which is enough for 14 capturing subexpressions for +\fBpcre[16|32]_exec()\fP or 22 different matches for +\fBpcre[16|32]_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 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. 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 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|32]_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. +.sp +Note that there are pattern options that can override \fB-s\fP, either +specifying no studying at all, or suppressing JIT compilation. +.sp +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 +\fB-t\fP, because you will then get the size output a zillion times, and the +timing will be distorted. You can control the number of iterations that are +used for timing by following \fB-t\fP with a number (as a separate item on the +command line). For example, "-t 1000" would iterate 1000 times. The default is +to iterate 500000 times. +.TP 10 +\fB-tm\fP +This is like \fB-t\fP except that it times only the matching phase, not the +compile or study phases. +. +. +.SH DESCRIPTION +.rs +.sp +If \fBpcretest\fP 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 +that file and writes to stdout. Otherwise, it reads from stdin and writes to +stdout, and prompts for each line of input, using "re>" to prompt for regular +expressions, and "data>" to prompt for data lines. +.P +When \fBpcretest\fP is built, a configuration option can specify that it should +be linked with the \fBlibreadline\fP library. When this is done, if the input +is from a terminal, it is read using the \fBreadline()\fP function. This +provides line-editing and history facilities. The output from the \fB-help\fP +option states whether or not \fBreadline()\fP will be used. +.P +The program handles any number of sets of input on a single input file. Each +set starts with a regular expression, and continues with any number of data +lines to be matched against the pattern. +.P +Each data line is matched separately and independently. If you want to do +multi-line matches, you have to use the \en escape sequence (or \er or \er\en, +etc., depending on the newline setting) in a single line of input to encode the +newline sequences. There is no limit on the length of data lines; the input +buffer is automatically extended if it is too small. +.P +An empty line signals the end of the data lines, at which point a new regular +expression is read. The regular expressions are given enclosed in any +non-alphanumeric delimiters other than backslash, for example: +.sp + /(a|bc)x+yz/ +.sp +White space before the initial delimiter is ignored. A regular expression may +be continued over several input lines, in which case the newline characters are +included within it. It is possible to include the delimiter within the pattern +by escaping it, for example +.sp + /abc\e/def/ +.sp +If you do so, the escape and the delimiter form part of the pattern, but since +delimiters are always non-alphanumeric, this does not affect its interpretation. +If the terminating delimiter is immediately followed by a backslash, for +example, +.sp + /abc/\e +.sp +then a backslash is added to the end of the pattern. This is done to provide a +way of testing the error condition that arises if a pattern finishes with a +backslash, because +.sp + /abc\e/ +.sp +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. +. +. +.SH "PATTERN MODIFIERS" +.rs +.sp +A pattern may be followed by any number of modifiers, which are mostly single +characters, though some of these can be qualified by further 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. White space may appear +between the final pattern delimiter and the first modifier, and between the +modifiers themselves. For reference, here is a complete list of modifiers. They +fall into several groups that are described in detail in the following +sections. +.sp + \fB/8\fP set UTF mode + \fB/?\fP disable UTF validity check + \fB/+\fP show remainder of subject after match + \fB/=\fP show all captures (not just those that are set) +.sp + \fB/A\fP set PCRE_ANCHORED + \fB/B\fP show compiled code + \fB/C\fP set PCRE_AUTO_CALLOUT + \fB/D\fP same as \fB/B\fP plus \fB/I\fP + \fB/E\fP set PCRE_DOLLAR_ENDONLY + \fB/F\fP flip byte order in compiled pattern + \fB/f\fP set PCRE_FIRSTLINE + \fB/G\fP find all matches (shorten string) + \fB/g\fP find all matches (use startoffset) + \fB/I\fP show information about pattern + \fB/i\fP set PCRE_CASELESS + \fB/J\fP set PCRE_DUPNAMES + \fB/K\fP show backtracking control names + \fB/L\fP set locale + \fB/M\fP show compiled memory size + \fB/m\fP set PCRE_MULTILINE + \fB/N\fP set PCRE_NO_AUTO_CAPTURE + \fB/P\fP use the POSIX wrapper + \fB/S\fP study the pattern after compilation + \fB/s\fP set PCRE_DOTALL + \fB/T\fP select character tables + \fB/U\fP set PCRE_UNGREEDY + \fB/W\fP set PCRE_UCP + \fB/X\fP set PCRE_EXTRA + \fB/x\fP set PCRE_EXTENDED + \fB/Y\fP set PCRE_NO_START_OPTIMIZE + \fB/Z\fP don't show lengths in \fB/B\fP output +.sp + \fB/\fP set PCRE_NEWLINE_ANY + \fB/\fP set PCRE_NEWLINE_ANYCRLF + \fB/\fP set PCRE_NEWLINE_CR + \fB/\fP set PCRE_NEWLINE_CRLF + \fB/\fP set PCRE_NEWLINE_LF + \fB/\fP set PCRE_BSR_ANYCRLF + \fB/\fP set PCRE_BSR_UNICODE + \fB/\fP set PCRE_JAVASCRIPT_COMPAT +.sp +. +. +.SS "Perl-compatible modifiers" +.rs +.sp +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[16|32]_compile()\fP is called. These four modifier letters have the same +effect as they do in Perl. For example: +.sp + /caseless/i +.sp +. +. +.SS "Modifiers for other PCRE options" +.rs +.sp +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 ) 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/8\fP PCRE_UTF32 ) when using the 32-bit + \fB/?\fP PCRE_NO_UTF32_CHECK ) library +.sp + \fB/A\fP PCRE_ANCHORED + \fB/C\fP PCRE_AUTO_CALLOUT + \fB/E\fP PCRE_DOLLAR_ENDONLY + \fB/f\fP PCRE_FIRSTLINE + \fB/J\fP PCRE_DUPNAMES + \fB/N\fP PCRE_NO_AUTO_CAPTURE + \fB/U\fP PCRE_UNGREEDY + \fB/W\fP PCRE_UCP + \fB/X\fP PCRE_EXTRA + \fB/Y\fP PCRE_NO_START_OPTIMIZE + \fB/\fP PCRE_NEWLINE_ANY + \fB/\fP PCRE_NEWLINE_ANYCRLF + \fB/\fP PCRE_NEWLINE_CR + \fB/\fP PCRE_NEWLINE_CRLF + \fB/\fP PCRE_NEWLINE_LF + \fB/\fP PCRE_BSR_ANYCRLF + \fB/\fP PCRE_BSR_UNICODE + \fB/\fP PCRE_JAVASCRIPT_COMPAT +.sp +The modifiers that are enclosed in angle brackets are literal strings 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: +.sp + /^abc/m +.sp +As well as turning on the PCRE_UTF8/16/32 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 +.\" +documentation. +. +. +.SS "Finding all matches in a string" +.rs +.sp +Searching for all possible matches within each subject string can be requested +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[16|32]_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[16|32]_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 +using the \fB/g\fP modifier or the \fBsplit()\fP function. 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. +. +. +.SS "Other modifiers" +.rs +.sp +There are yet more modifiers for controlling the way \fBpcretest\fP +operates. +.P +The \fB/+\fP modifier requests that as well as outputting the substring that +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|32]_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 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 +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[16|32]_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[16|32]_exec()\fP. It causes +\fBpcretest\fP to create a \fBpcre[16|32]_extra\fP block if one has not already +been created by a call to \fBpcre[16|32]_study()\fP, and to set the +PCRE_EXTRA_MARK flag and the \fBmark\fP field within it, every time that +\fBpcre[16|32]_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, +.sp + /pattern/Lfr_FR +.sp +For this reason, it must be the last modifier. The given locale is set, +\fBpcre[16|32]_maketables()\fP is called to build a set of character tables for +the locale, and this is then passed to \fBpcre[16|32]_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|32]\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 +The \fB/S\fP modifier causes \fBpcre[16|32]_study()\fP to be called after the +expression has been compiled, and the results used when the expression is +matched. There are a number of qualifying characters that may follow \fB/S\fP. +They may appear in any order. +.P +If \fBS\fP is followed by an exclamation mark, \fBpcre[16|32]_study()\fP is called +with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a +\fBpcre_extra\fP block, even when studying discovers no useful information. +.P +If \fB/S\fP is followed by a second S character, 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 followed by a + character, the call to +\fBpcre[16|32]_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|32]_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 +Finally, if \fB/S\fP is followed by a minus character, JIT compilation is +suppressed, even if it was requested externally by the \fB-s\fP command line +option. This makes it possible to specify that JIT is never to be used for +certain patterns. +.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[16|32]_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 + pcre_chartables.c.dist + 1 a set of tables defining ISO 8859 characters +.sp +In table 1, some characters whose codes are greater than 128 are identified as +letters, digits, spaces, etc. +. +. +.SS "Using the POSIX wrapper API" +.rs +.sp +The \fB/P\fP modifier causes \fBpcretest\fP to call PCRE via the POSIX wrapper +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 + /N REG_NOSUB + /s REG_DOTALL ) + /U REG_UNGREEDY ) These options are not part of + /W REG_UCP ) the POSIX standard + /8 REG_UTF8 ) +.sp +The \fB/+\fP modifier works as described above. All other modifiers are +ignored. +. +. +.SH "DATA LINES" +.rs +.sp +Before each data line is passed to \fBpcre[16|32]_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: +.sp + \ea alarm (BEL, \ex07) + \eb backspace (\ex08) + \ee escape (\ex27) + \ef form feed (\ex0c) + \en newline (\ex0a) +.\" JOIN + \eqdd set the PCRE_MATCH_LIMIT limit to dd + (any number of digits) + \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 or 16-bit or 32-bit mode + \exhh hexadecimal byte (up to 2 hex digits) + \ex{hh...} hexadecimal character (any number of hex digits) +.\" JOIN + \eA pass the PCRE_ANCHORED option to \fBpcre[16|32]_exec()\fP + or \fBpcre[16|32]_dfa_exec()\fP +.\" JOIN + \eB pass the PCRE_NOTBOL option to \fBpcre[16|32]_exec()\fP + or \fBpcre[16|32]_dfa_exec()\fP +.\" JOIN + \eCdd call pcre[16|32]_copy_substring() for substring dd + after a successful match (number less than 32) +.\" JOIN + \eCname call pcre[16|32]_copy_named_substring() for substring + "name" after a successful match (name termin- + ated by next non alphanumeric character) +.\" JOIN + \eC+ show the current captured substrings at callout + time + \eC- do not supply a callout function +.\" JOIN + \eC!n return 1 instead of 0 when callout number n is + reached +.\" JOIN + \eC!n!m return 1 instead of 0 when callout number n is + reached for the nth time +.\" 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[16|32]_dfa_exec()\fP match function + \eF only shortest match for \fBpcre[16|32]_dfa_exec()\fP +.\" JOIN + \eGdd call pcre[16|32]_get_substring() for substring dd + after a successful match (number less than 32) +.\" JOIN + \eGname call pcre[16|32]_get_named_substring() for substring + "name" after a successful match (name termin- + ated by next non-alphanumeric character) +.\" JOIN + \eJdd set up a JIT stack of dd kilobytes maximum (any + number of digits) +.\" JOIN + \eL call pcre[16|32]_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[16|32]_exec()\fP + or \fBpcre[16|32]_dfa_exec()\fP; if used twice, pass the + PCRE_NOTEMPTY_ATSTART option +.\" JOIN + \eOdd set the size of the output vector passed to + \fBpcre[16|32]_exec()\fP to dd (any number of digits) +.\" JOIN + \eP pass the PCRE_PARTIAL_SOFT option to \fBpcre[16|32]_exec()\fP + or \fBpcre[16|32]_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[16|32]_dfa_exec()\fP + \eS output details of memory get/free calls during matching +.\" JOIN + \eY pass the PCRE_NO_START_OPTIMIZE option to \fBpcre[16|32]_exec()\fP + or \fBpcre[16|32]_dfa_exec()\fP +.\" JOIN + \eZ pass the PCRE_NOTEOL option to \fBpcre[16|32]_exec()\fP + or \fBpcre[16|32]_dfa_exec()\fP +.\" JOIN + \e? pass the PCRE_NO_UTF[8|16|32]_CHECK option to + \fBpcre[16|32]_exec()\fP or \fBpcre[16|32]_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[16|32]_exec()\fP or \fBpcre[16|32]_dfa_exec()\fP +.\" JOIN + \e pass the PCRE_NEWLINE_CR option to \fBpcre[16|32]_exec()\fP + or \fBpcre[16|32]_dfa_exec()\fP +.\" JOIN + \e pass the PCRE_NEWLINE_LF option to \fBpcre[16|32]_exec()\fP + or \fBpcre[16|32]_dfa_exec()\fP +.\" JOIN + \e pass the PCRE_NEWLINE_CRLF option to \fBpcre[16|32]_exec()\fP + or \fBpcre[16|32]_dfa_exec()\fP +.\" JOIN + \e pass the PCRE_NEWLINE_ANYCRLF option to \fBpcre[16|32]_exec()\fP + or \fBpcre[16|32]_dfa_exec()\fP +.\" JOIN + \e pass the PCRE_NEWLINE_ANY option to \fBpcre[16|32]_exec()\fP + or \fBpcre[16|32]_dfa_exec()\fP +.sp +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 +In UTF-32 mode, all 4- to 8-digit \ex{...} values are accepted. This makes it +possible to construct invalid UTF-32 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. +.P +A backslash followed by anything else just escapes the anything else. If +the very last character is a backslash, it is ignored. This gives a way of +passing an empty line as data, since a real empty line terminates the data +input. +.P +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|32]_exec()\fP several times, +with different values in the \fImatch_limit\fP and \fImatch_limit_recursion\fP +fields of the \fBpcre[16|32]_extra\fP data structure, until it finds the minimum +numbers for each parameter that allow \fBpcre[16|32]_exec()\fP to complete without +error. Because this is testing a specific feature of the normal interpretive +\fBpcre[16|32]_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[16|32]_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. +. +. +.SH "THE ALTERNATIVE MATCHING FUNCTION" +.rs +.sp +By default, \fBpcretest\fP uses the standard PCRE matching function, +\fBpcre[16|32]_exec()\fP to match each data line. PCRE also supports an +alternative matching function, \fBpcre[16|32]_dfa_test()\fP, which operates in a +different way, and has some restrictions. The differences between the two +functions are described in the +.\" HREF +\fBpcrematching\fP +.\" +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 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. +. +. +.SH "DEFAULT OUTPUT FROM PCRETEST" +.rs +.sp +This section describes the output when the normal matching function, +\fBpcre[16|32]_exec()\fP, is being used. +.P +When a match succeeds, \fBpcretest\fP outputs the list of captured substrings +that \fBpcre[16|32]_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[16|32]_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 8.13 2011-04-30 +.sp + re> /^abc(\ed+)/ + data> abc123 + 0: abc123 + 1: 123 + data> xyz + No match +.sp +Unset capturing substrings that are not followed by one that is set are not +returned by \fBpcre[16|32]_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 + 0: a + 1: a + data> b + 0: b + 1: + 2: b +.sp +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 + 0: cat + 0+ aract +.sp +If the pattern has the \fB/g\fP or \fB/G\fP modifier, the results of successive +matching attempts are output in sequence, like this: +.sp + re> /\eBi(\ew\ew)/g + data> Mississippi + 0: iss + 1: ss + 0: iss + 1: ss + 0: ipp + 1: pp +.sp +"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 +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 +parentheses after each string for \fB\eC\fP and \fB\eG\fP. +.P +Note that whereas patterns can be continued over several lines (a plain ">" +prompt is used for continuations), data lines may not. However newlines can be +included in data by means of the \en escape (or \er, \er\en, etc., depending on +the newline sequence setting). +. +. +. +.SH "OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION" +.rs +.sp +When the alternative matching function, \fBpcre[16|32]_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: +.sp + re> /(tang|tangerine|tan)/ + data> yellow tangerine\eD + 0: tangerine + 1: tang + 2: tan +.sp +(Using the normal matching function on this data finds only "tang".) The +longest matching string is always given first (and numbered zero). After a +PCRE_ERROR_PARTIAL return, the output is "Partial match:", followed by the +partially matching substring. (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.) +.P +If \fB/g\fP is present on the pattern, the search for further matches resumes +at the end of the longest match. For example: +.sp + re> /(tang|tangerine|tan)/g + data> yellow tangerine and tangy sultana\eD + 0: tangerine + 1: tang + 2: tan + 0: tang + 1: tan + 0: tan +.sp +Since the matching function does not support substring capture, the escape +sequences that are concerned with captured substrings are not relevant. +. +. +.SH "RESTARTING AFTER A PARTIAL MATCH" +.rs +.sp +When the alternative matching function has given the PCRE_ERROR_PARTIAL return, +indicating that the subject partially matched the pattern, you can restart the +match with additional subject data by means of the \eR escape sequence. For +example: +.sp + re> /^\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed$/ + data> 23ja\eP\eD + Partial match: 23ja + data> n05\eR\eD + 0: n05 +.sp +For further information about partial matching, see the +.\" HREF +\fBpcrepartial\fP +.\" +documentation. +. +. +.SH CALLOUTS +.rs +.sp +If the pattern contains any callout requests, \fBpcretest\fP'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: +.sp + --->pqrabcdef + 0 ^ ^ \ed +.sp +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 +callout number, the offset in the pattern, preceded by a plus, is output. For +example: +.sp + re> /\ed?[A-E]\e*/C + data> E* + --->E* + +0 ^ \ed? + +3 ^ [A-E] + +8 ^^ \e* + +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 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 +the +.\" HREF +\fBpcrecallout\fP +.\" +documentation. +. +. +. +.SH "NON-PRINTING CHARACTERS" +.rs +.sp +When \fBpcretest\fP 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. +.P +When \fBpcretest\fP 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 \fB/L\fP modifier). In this case, the \fBisprint()\fP +function to distinguish printing and non-printing characters. +. +. +. +.SH "SAVING AND RELOADING COMPILED PATTERNS" +.rs +.sp +The facilities described in this section are not available when the POSIX +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 +compiled pattern to a file, by following the modifiers with > and a file name. +For example: +.sp + /pattern/im >/some/file +.sp +See the +.\" HREF +\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 +written as four bytes in big-endian order (most significant byte first). If +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 +(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 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> " to prompt for regular expressions, and "data>" to prompt for data + lines. + + When pcretest is built, a configuration option can specify that it + should be linked with the libreadline library. When this is done, if + the input is from a terminal, it is read using the readline() function. + This provides line-editing and history facilities. The output from the + -help option states whether or not readline() will be used. + + The program handles any number of sets of input on a single input file. + Each set starts with a regular expression, and continues with any num- + ber of data lines to be matched against the pattern. + + Each data line is matched separately and independently. If you want to + do multi-line matches, you have to use the \n escape sequence (or \r or + \r\n, etc., depending on the newline setting) in a single line of input + to encode the newline sequences. There is no limit on the length of + data lines; the input buffer is automatically extended if it is too + small. + + An empty line signals the end of the data lines, at which point a new + regular expression is read. The regular expressions are given enclosed + in any non-alphanumeric delimiters other than backslash, for example: + + /(a|bc)x+yz/ + + White space before the initial delimiter is ignored. A regular expres- + sion may be continued over several input lines, in which case the new- + line characters are included within it. It is possible to include the + delimiter within the pattern by escaping it, for example + + /abc\/def/ + + If you do so, the escape and the delimiter form part of the pattern, + but since delimiters are always non-alphanumeric, this does not affect + its interpretation. If the terminating delimiter is immediately fol- + lowed by a backslash, for example, + + /abc/\ + + then a backslash is added to the end of the pattern. This is done to + provide a way of testing the error condition that arises if a pattern + finishes with a backslash, because + + /abc\/ + + 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 + + A pattern may be followed by any number of modifiers, which are mostly + single characters, though some of these can be qualified by further + 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 modi- + fiers. White space may appear between the final pattern delimiter and + the first modifier, and between the modifiers themselves. For refer- + ence, here is a complete list of modifiers. They fall into several + groups that are described in detail in the following sections. + + /8 set UTF mode + /? disable UTF validity check + /+ show remainder of subject after match + /= show all captures (not just those that are set) + + /A set PCRE_ANCHORED + /B show compiled code + /C set PCRE_AUTO_CALLOUT + /D same as /B plus /I + /E set PCRE_DOLLAR_ENDONLY + /F flip byte order in compiled pattern + /f set PCRE_FIRSTLINE + /G find all matches (shorten string) + /g find all matches (use startoffset) + /I show information about pattern + /i set PCRE_CASELESS + /J set PCRE_DUPNAMES + /K show backtracking control names + /L set locale + /M show compiled memory size + /m set PCRE_MULTILINE + /N set PCRE_NO_AUTO_CAPTURE + /P use the POSIX wrapper + /S study the pattern after compilation + /s set PCRE_DOTALL + /T select character tables + /U set PCRE_UNGREEDY + /W set PCRE_UCP + /X set PCRE_EXTRA + /x set PCRE_EXTENDED + /Y set PCRE_NO_START_OPTIMIZE + /Z don't show lengths in /B output + + / set PCRE_NEWLINE_ANY + / set PCRE_NEWLINE_ANYCRLF + / set PCRE_NEWLINE_CR + / set PCRE_NEWLINE_CRLF + / set PCRE_NEWLINE_LF + / set PCRE_BSR_ANYCRLF + / set PCRE_BSR_UNICODE + / set PCRE_JAVASCRIPT_COMPAT + + + Perl-compatible modifiers + + The /i, /m, /s, and /x modifiers set the PCRE_CASELESS, PCRE_MULTILINE, + PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when + pcre[16|32]_compile() is called. These four modifier letters have the + same effect as they do in Perl. For example: + + /caseless/i + + + Modifiers for other PCRE options + + The following table shows additional modifiers for setting PCRE com- + pile-time options that do not correspond to anything in Perl: + + /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 + + /8 PCRE_UTF32 ) when using the 32-bit + /? PCRE_NO_UTF32_CHECK ) library + + /A PCRE_ANCHORED + /C PCRE_AUTO_CALLOUT + /E PCRE_DOLLAR_ENDONLY + /f PCRE_FIRSTLINE + /J PCRE_DUPNAMES + /N PCRE_NO_AUTO_CAPTURE + /U PCRE_UNGREEDY + /W PCRE_UCP + /X PCRE_EXTRA + /Y PCRE_NO_START_OPTIMIZE + / PCRE_NEWLINE_ANY + / PCRE_NEWLINE_ANYCRLF + / PCRE_NEWLINE_CR + / PCRE_NEWLINE_CRLF + / PCRE_NEWLINE_LF + / PCRE_BSR_ANYCRLF + / PCRE_BSR_UNICODE + / PCRE_JAVASCRIPT_COMPAT + + The modifiers that are enclosed in angle brackets are literal strings + 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/32 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 out- + put 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 + 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[16|32]_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[16|32]_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 + 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. 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|32]_exec()). Values in the offsets vector cor- + responding to higher numbers should be set to -1, and these are output + as "". This modifier gives a way of checking that this is hap- + pening. + + The /B modifier is a debugging feature. It requests that pcretest out- + 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 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[16|32]_fullinfo() after com- + piling a pattern. If the pattern is studied, the results of that are + also output. + + The /K modifier requests pcretest to show names from backtracking con- + trol verbs that are returned from calls to pcre[16|32]_exec(). It + causes pcretest to create a pcre[16|32]_extra block if one has not + already been created by a call to pcre[16|32]_study(), and to set the + PCRE_EXTRA_MARK flag and the mark field within it, every time that + pcre[16|32]_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, + + /pattern/Lfr_FR + + For this reason, it must be the last modifier. The given locale is set, + pcre[16|32]_maketables() is called to build a set of character tables + for the locale, and this is then passed to pcre[16|32]_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|32] 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. + + The /S modifier causes pcre[16|32]_study() to be called after the + expression has been compiled, and the results used when the expression + is matched. There are a number of qualifying characters that may follow + /S. They may appear in any order. + + If S is followed by an exclamation mark, pcre[16|32]_study() is called + with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a + pcre_extra block, even when studying discovers no useful information. + + If /S is followed by a second S character, 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 followed by a + character, the call to + pcre[16|32]_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|32]_exec() is run, except when incompatible run- + time options are specified. For more details, see the pcrejit documen- + tation. See also the \J escape sequence below for a way of setting the + size of the JIT stack. + + Finally, if /S is followed by a minus character, JIT compilation is + suppressed, even if it was requested externally by the -s command line + option. This makes it possible to specify that JIT is never to be used + for certain patterns. + + 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[16|32]_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 + 1 a set of tables defining ISO 8859 characters + + In table 1, some characters whose codes are greater than 128 are iden- + tified as letters, digits, spaces, etc. + + Using the POSIX wrapper API + + The /P modifier causes pcretest to call PCRE via the POSIX wrapper 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() func- + tion: + + /i REG_ICASE + /m REG_NEWLINE + /N REG_NOSUB + /s REG_DOTALL ) + /U REG_UNGREEDY ) These options are not part of + /W REG_UCP ) the POSIX standard + /8 REG_UTF8 ) + + The /+ modifier works as described above. All other modifiers are + ignored. + + +DATA LINES + + Before each data line is passed to pcre[16|32]_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: + + \a alarm (BEL, \x07) + \b backspace (\x08) + \e escape (\x27) + \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 or 16-bit or 32-bit mode + \xhh hexadecimal byte (up to 2 hex digits) + \x{hh...} hexadecimal character (any number of hex digits) + \A pass the PCRE_ANCHORED option to pcre[16|32]_exec() + or pcre[16|32]_dfa_exec() + \B pass the PCRE_NOTBOL option to pcre[16|32]_exec() + or pcre[16|32]_dfa_exec() + \Cdd call pcre[16|32]_copy_substring() for substring dd + after a successful match (number less than 32) + \Cname call pcre[16|32]_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[16|32]_dfa_exec() match function + \F only shortest match for pcre[16|32]_dfa_exec() + \Gdd call pcre[16|32]_get_substring() for substring dd + after a successful match (number less than 32) + \Gname call pcre[16|32]_get_named_substring() for substring + "name" after a successful match (name termin- + ated by next non-alphanumeric character) + \Jdd set up a JIT stack of dd kilobytes maximum (any + number of digits) + \L call pcre[16|32]_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[16|32]_exec() + or pcre[16|32]_dfa_exec(); if used twice, pass the + PCRE_NOTEMPTY_ATSTART option + \Odd set the size of the output vector passed to + pcre[16|32]_exec() to dd (any number of digits) + \P pass the PCRE_PARTIAL_SOFT option to pcre[16|32]_exec() + or pcre[16|32]_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[16|32]_dfa_exec() + \S output details of memory get/free calls during matching + \Y pass the PCRE_NO_START_OPTIMIZE option to + pcre[16|32]_exec() + or pcre[16|32]_dfa_exec() + \Z pass the PCRE_NOTEOL option to pcre[16|32]_exec() + or pcre[16|32]_dfa_exec() + \? pass the PCRE_NO_UTF[8|16|32]_CHECK option to + pcre[16|32]_exec() or pcre[16|32]_dfa_exec() + \>dd start the match at offset dd (optional "-"; then + any number of digits); this sets the startoffset + argument for pcre[16|32]_exec() or + pcre[16|32]_dfa_exec() + \ pass the PCRE_NEWLINE_CR option to pcre[16|32]_exec() + or pcre[16|32]_dfa_exec() + \ pass the PCRE_NEWLINE_LF option to pcre[16|32]_exec() + or pcre[16|32]_dfa_exec() + \ pass the PCRE_NEWLINE_CRLF option to pcre[16|32]_exec() + or pcre[16|32]_dfa_exec() + \ pass the PCRE_NEWLINE_ANYCRLF option to pcre[16|32]_exec() + or pcre[16|32]_dfa_exec() + \ pass the PCRE_NEWLINE_ANY option to pcre[16|32]_exec() + or pcre[16|32]_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. + + In UTF-32 mode, all 4- to 8-digit \x{...} values are accepted. This + makes it possible to construct invalid UTF-32 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 + any data line. + + A backslash followed by anything else just escapes the anything else. + If the very last character is a backslash, it is ignored. This gives a + way of passing an empty line as data, since a real empty line termi- + nates the data input. + + 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|32]_exec() several times, with + different values in the match_limit and match_limit_recursion fields of + the pcre[16|32]_extra data structure, until it finds the minimum num- + bers for each parameter that allow pcre[16|32]_exec() to complete with- + out error. Because this is testing a specific feature of the normal + interpretive pcre[16|32]_exec() execution, the use of any JIT optimiza- + tion 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[16|32]_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 ALTERNATIVE MATCHING FUNCTION + + By default, pcretest uses the standard PCRE matching function, + pcre[16|32]_exec() to match each data line. PCRE also supports an + alternative matching function, pcre[16|32]_dfa_test(), which operates + in a different 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 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 + + This section describes the output when the normal matching function, + pcre[16|32]_exec(), is being used. + + When a match succeeds, pcretest outputs the list of captured substrings + that pcre[16|32]_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|32]_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 8.13 2011-04-30 + + re> /^abc(\d+)/ + data> abc123 + 0: abc123 + 1: 123 + data> xyz + No match + + Unset capturing substrings that are not followed by one that is set are + not returned by pcre[16|32]_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 + 0: a + 1: a + data> b + 0: b + 1: + 2: b + + 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 + matching attempts are output in sequence, like this: + + re> /\Bi(\w\w)/g + data> Mississippi + 0: iss + 1: ss + 0: iss + 1: ss + 0: ipp + 1: pp + + "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 + 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- + 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, + etc., depending on the newline sequence setting). + + +OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION + + When the alternative matching function, pcre[16|32]_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 + 0: tangerine + 1: tang + 2: tan + + (Using the normal matching function on this data finds only "tang".) + The longest matching string is always given first (and numbered zero). + After a PCRE_ERROR_PARTIAL return, the output is "Partial match:", fol- + lowed by the partially matching substring. (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 asser- + tion, \K, \b, or \B was involved.) + + If /g is present on the pattern, the search for further matches resumes + at the end of the longest match. For example: + + re> /(tang|tangerine|tan)/g + data> yellow tangerine and tangy sultana\D + 0: tangerine + 1: tang + 2: tan + 0: tang + 1: tan + 0: tan + + 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 + + When the alternative matching function has given the PCRE_ERROR_PARTIAL + return, indicating that the subject partially matched the pattern, you + can restart the match with additional subject data by means of the \R + escape sequence. For example: + + re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/ + data> 23ja\P\D + Partial match: 23ja + data> n05\R\D + 0: n05 + + For further information about partial matching, see the pcrepartial + documentation. + + +CALLOUTS + + If the pattern contains any callout requests, pcretest's callout func- + 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: + + --->pqrabcdef + 0 ^ ^ \d + + 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 + the callout number, the offset in the pattern, preceded by a plus, is + output. For example: + + re> /\d?[A-E]\*/C + data> E* + --->E* + +0 ^ \d? + +3 ^ [A-E] + +8 ^^ \* + +10 ^ ^ + 0: E* + + 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 + 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 + 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 + 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 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 + file name. For example: + + /pattern/im >/some/file + + 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 + optional study data, each written as four bytes in big-endian order + (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 (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> +.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 the surrogate area and the non-characters. +.P +Characters in the "Surrogate Area" of Unicode are reserved for use by UTF-16, +where they are used in pairs to encode codepoints with values greater than +0xFFFF. The code points that are encoded by UTF-16 pairs are available +independently in the UTF-8 and UTF-32 encodings. (In other words, the whole +surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8 and +UTF-32.) +.P +Also excluded are the "Non-Character" code points, which are U+FDD0 to U+FDEF +and the last two code points in each plane, U+??FFFE and U+??FFFF. +.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. +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 +Note that passing PCRE_NO_UTF8_CHECK to \fBpcre_compile()\fP just disables the +check for the pattern; it does not also apply to subject strings. If you want +to disable the check for a subject string you must pass this option to +\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. +.P +If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, the result +is undefined and your program may crash. +. +. +.\" 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 +Excluded are the "Non-Character" code points, which are U+FDD0 to U+FDEF +and the last two code points in each plane, U+??FFFE and U+??FFFF. +.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. +However, if an invalid string is passed, the result is undefined. +. +. +.\" HTML +.SS "Validity of UTF-32 strings" +.rs +.sp +When you set the PCRE_UTF32 flag, the strings of 32-bit data units that are +passed as patterns and subjects are (by default) checked for validity on entry +to the relevant functions. This check allows only values in the range U+0 +to U+10FFFF, excluding the surrogate area U+D800 to U+DFFF, and the +"Non-Character" code points, which are U+FDD0 to U+FDEF and the last two +characters in each plane, U+??FFFE and U+??FFFF. +.P +If an invalid UTF-32 string is passed to PCRE, an error return is given. At +compile time, the only additional information is the offset to the first data +unit of the failing character. The run-time functions \fBpcre32_exec()\fP and +\fBpcre32_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_UTF32_CHECK flag at compile time or at run time, PCRE assumes that +the pattern or subject it is given (respectively) contains only valid UTF-32 +sequences. In this case, it does not diagnose an invalid UTF-32 string. +However, if an invalid string is passed, the result is undefined. +. +. +.SS "General comments about UTF modes" +.rs +.sp +1. Codepoints less than 256 can be specified in patterns 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, or a single 32-bit data unit in +UTF-32 mode, but its use can lead to some strange effects because it breaks up +multi-unit characters (see the description of \eC in the +.\" HREF +\fBpcrepattern\fP +.\" +documentation). The use of \eC is not supported in the alternative matching +function \fBpcre[16|32]_dfa_exec()\fP, nor is it supported in UTF mode by the +JIT optimization of \fBpcre[16|32]_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. A few Unicode +characters such as Greek sigma have more than two codepoints that are +case-equivalent. Up to and including PCRE release 8.31, only one-to-one case +mappings were supported, but later releases (with Unicode property support) do +treat as case-equivalent all versions of characters such as Greek sigma. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 11 November 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff --git a/tools/pcre/doc/perltest.txt b/tools/pcre/doc/perltest.txt new file mode 100644 index 00000000..bb1a52a4 --- /dev/null +++ b/tools/pcre/doc/perltest.txt @@ -0,0 +1,42 @@ +The perltest program +-------------------- + +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 certain +other pcretest modifiers that are either handled or ignored: + + /+ 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; 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 certain features of PCRE. Some of these files also contain +malformed regular expressions, in order to check that PCRE diagnoses them +correctly. + +Philip Hazel +January 2012 diff --git a/tools/pcre/install-sh b/tools/pcre/install-sh new file mode 100644 index 00000000..a9244eb0 --- /dev/null +++ b/tools/pcre/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/tools/pcre/libpcre.pc.in b/tools/pcre/libpcre.pc.in new file mode 100644 index 00000000..1f26b32b --- /dev/null +++ b/tools/pcre/libpcre.pc.in @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libpcre +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 --git a/tools/pcre/libpcre16.pc.in b/tools/pcre/libpcre16.pc.in new file mode 100644 index 00000000..f589b757 --- /dev/null +++ b/tools/pcre/libpcre16.pc.in @@ -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 --git a/tools/pcre/libpcre32.pc.in b/tools/pcre/libpcre32.pc.in new file mode 100644 index 00000000..65821056 --- /dev/null +++ b/tools/pcre/libpcre32.pc.in @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libpcre32 +Description: PCRE - Perl compatible regular expressions C library with 32 bit character support +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lpcre32 +Cflags: -I${includedir} @PCRE_STATIC_CFLAG@ diff --git a/tools/pcre/libpcrecpp.pc.in b/tools/pcre/libpcrecpp.pc.in new file mode 100644 index 00000000..ef006fe4 --- /dev/null +++ b/tools/pcre/libpcrecpp.pc.in @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libpcrecpp +Description: PCRECPP - C++ wrapper for PCRE +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lpcre -lpcrecpp +Cflags: -I${includedir} @PCRE_STATIC_CFLAG@ diff --git a/tools/pcre/libpcreposix.pc.in b/tools/pcre/libpcreposix.pc.in new file mode 100644 index 00000000..c6c0b0c6 --- /dev/null +++ b/tools/pcre/libpcreposix.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libpcreposix +Description: PCREPosix - Posix compatible interface to libpcre +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lpcreposix +Cflags: -I${includedir} @PCRE_STATIC_CFLAG@ +Requires.private: libpcre diff --git a/tools/pcre/ltmain.sh b/tools/pcre/ltmain.sh new file mode 100644 index 00000000..3061e3c5 --- /dev/null +++ b/tools/pcre/ltmain.sh @@ -0,0 +1,9636 @@ + +# libtool (GNU libtool) 2.4 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010 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. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $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.4 +TIMESTAMP="" +package_revision=1.3293 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${EGREP="grep -E"} +: ${FGREP="grep -F"} +: ${GREP="grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="sed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +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: +# 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 () +{ + # 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 + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# 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. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $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: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + 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 + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# 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=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# 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. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# 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 + + +# 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 + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --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 +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --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: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # 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*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $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 + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # 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 + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + 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 +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# 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. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# 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 () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # 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_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # 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_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + 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 + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + 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 opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + 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" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + 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. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + 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 "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 "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + 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" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#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. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + 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 + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + 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 || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # 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 + 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 /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $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 +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + 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 "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \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" +#define SHELL_SPACE_CHARS " \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" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ fputs ("/' -e 's/$/\\n", f);/' + + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </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 | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + 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 + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_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 + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_apped perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + 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" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # 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. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # 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 + 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 + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + 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\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $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" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + 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..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # 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 + 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 + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + 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 + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + 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 + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + 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. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + 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}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $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 + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + 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" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + 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..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + 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" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + 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 + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +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 \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/tools/pcre/m4/ax_pthread.m4 b/tools/pcre/m4/ax_pthread.m4 new file mode 100644 index 00000000..d90de34d --- /dev/null +++ b/tools/pcre/m4/ax_pthread.m4 @@ -0,0 +1,309 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 18 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) + AC_MSG_RESULT($ax_pthread_ok) + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($ax_pthread_ok) + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $attr; return attr /* ; */])], + [attr_name=$attr; break], + []) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + flag="-mt -D_REENTRANT" + fi + ;; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + ax_cv_PTHREAD_PRIO_INHERIT, [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], + AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/tools/pcre/m4/libtool.m4 b/tools/pcre/m4/libtool.m4 new file mode 100644 index 00000000..2ed159cd --- /dev/null +++ b/tools/pcre/m4/libtool.m4 @@ -0,0 +1,7844 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# 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. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +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 +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # 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 '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _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 +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 + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +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 && \ + 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 + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _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], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _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], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* 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)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + 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}`~ + 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~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + 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 + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + # Handle Gentoo/FreeBSD as it was Linux + case $host_vendor in + gentoo) + version_type=linux ;; + *) + version_type=freebsd-$objformat ;; + esac + + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + linux) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + need_lib_prefix=no + need_version=no + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +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 + +_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"]) +_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 + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +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 +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +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'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + 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 + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + 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 + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + 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_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + 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], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_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 + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + 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). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + 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++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | 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). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | 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']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _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) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _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_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. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_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. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +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 +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +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. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + 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 +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + 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 + _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' + # 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 $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _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 + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _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 + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _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' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _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 + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _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 + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _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. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + 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*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _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 + ;; + + hpux9*) + if test "$GCC" = yes; then + _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 + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _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 + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _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 $pic_flag ${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}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _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. + # 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' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + 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}-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(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + 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} $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 \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -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)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _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 $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"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $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 -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], + [[If ld is used when linking, flag to hardcode $libdir into a binary + during linking. This must work even if $libdir does not exist]]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [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 +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +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 + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # 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 + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # 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 $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' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _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 + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _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. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + 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) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${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' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _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 + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _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 $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 $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _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 $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 + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -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)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _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 $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 + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $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 -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + 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 $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 $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 + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -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 -G -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 + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _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 +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# 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)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_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 + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + 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 ${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. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _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. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # 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]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # 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 + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +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" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# 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]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +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 +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + 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 +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _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=: +]) + + +# _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##*/}"]) + + _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}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${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_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _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"]) + + # 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 + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _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 + ;; + *-*-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 +]) +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 diff --git a/tools/pcre/m4/ltoptions.m4 b/tools/pcre/m4/ltoptions.m4 new file mode 100644 index 00000000..17cfd51c --- /dev/null +++ b/tools/pcre/m4/ltoptions.m4 @@ -0,0 +1,369 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# 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 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/tools/pcre/m4/ltsugar.m4 b/tools/pcre/m4/ltsugar.m4 new file mode 100644 index 00000000..9000a057 --- /dev/null +++ b/tools/pcre/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# 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 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/tools/pcre/m4/ltversion.m4 b/tools/pcre/m4/ltversion.m4 new file mode 100644 index 00000000..9c7b5d41 --- /dev/null +++ b/tools/pcre/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# 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. + +# @configure_input@ + +# serial 3293 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4]) +m4_define([LT_PACKAGE_REVISION], [1.3293]) + +AC_DEFUN([LTVERSION_VERSION], +[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) +]) diff --git a/tools/pcre/m4/lt~obsolete.m4 b/tools/pcre/m4/lt~obsolete.m4 new file mode 100644 index 00000000..c573da90 --- /dev/null +++ b/tools/pcre/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# 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 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/tools/pcre/m4/pcre_visibility.m4 b/tools/pcre/m4/pcre_visibility.m4 new file mode 100644 index 00000000..31f5deb9 --- /dev/null +++ b/tools/pcre/m4/pcre_visibility.m4 @@ -0,0 +1,89 @@ +# visibility.m4 serial 4 (gettext-0.18.2) +dnl Copyright (C) 2005, 2008, 2010-2011 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Tests whether the compiler supports the command-line option +dnl -fvisibility=hidden and the function and variable attributes +dnl __attribute__((__visibility__("hidden"))) and +dnl __attribute__((__visibility__("default"))). +dnl Does *not* test for __visibility__("protected") - which has tricky +dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on +dnl MacOS X. +dnl Does *not* test for __visibility__("internal") - which has processor +dnl dependent semantics. +dnl Does *not* test for #pragma GCC visibility push(hidden) - which is +dnl "really only recommended for legacy code". +dnl Set the variable CFLAG_VISIBILITY. +dnl Defines and sets the variable HAVE_VISIBILITY. + +dnl Modified to fit with PCRE build environment by Cristian Rodríguez. + +AC_DEFUN([PCRE_VISIBILITY], +[ + AC_REQUIRE([AC_PROG_CC]) + VISIBILITY_CFLAGS= + VISIBILITY_CXXFLAGS= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + dnl First, check whether -Werror can be added to the command line, or + dnl whether it leads to an error because of some other option that the + dnl user has put into $CC $CFLAGS $CPPFLAGS. + AC_MSG_CHECKING([whether the -Werror option is usable]) + AC_CACHE_VAL([pcre_cv_cc_vis_werror], [ + pcre_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [pcre_cv_cc_vis_werror=yes], + [pcre_cv_cc_vis_werror=no]) + CFLAGS="$pcre_save_CFLAGS"]) + AC_MSG_RESULT([$pcre_cv_cc_vis_werror]) + dnl Now check whether visibility declarations are supported. + AC_MSG_CHECKING([for simple visibility declarations]) + AC_CACHE_VAL([pcre_cv_cc_visibility], [ + pcre_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + dnl We use the option -Werror and a function dummyfunc, because on some + dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning + dnl "visibility attribute not supported in this configuration; ignored" + dnl at the first function definition in every compilation unit, and we + dnl don't want to use the option in this case. + if test $pcre_cv_cc_vis_werror = yes; then + CFLAGS="$CFLAGS -Werror" + fi + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void); + void dummyfunc (void) {} + ]], + [[]])], + [pcre_cv_cc_visibility=yes], + [pcre_cv_cc_visibility=no]) + CFLAGS="$pcre_save_CFLAGS"]) + AC_MSG_RESULT([$pcre_cv_cc_visibility]) + if test $pcre_cv_cc_visibility = yes; then + VISIBILITY_CFLAGS="-fvisibility=hidden" + VISIBILITY_CXXFLAGS="-fvisibility=hidden -fvisibility-inlines-hidden" + HAVE_VISIBILITY=1 + AC_DEFINE(PCRE_EXP_DECL, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible]) + AC_DEFINE(PCRE_EXP_DEFN, [__attribute__ ((visibility ("default")))], [to make a symbol visible]) + AC_DEFINE(PCRE_EXP_DATA_DEFN, [__attribute__ ((visibility ("default")))], [to make a symbol visible]) + AC_DEFINE(PCREPOSIX_EXP_DECL, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible]) + AC_DEFINE(PCREPOSIX_EXP_DEFN, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible]) + AC_DEFINE(PCRECPP_EXP_DECL, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible]) + AC_DEFINE(PCRECPP_EXP_DEFN, [__attribute__ ((visibility ("default")))], [to make a symbol visible]) + fi + fi + AC_SUBST([VISIBILITY_CFLAGS]) + AC_SUBST([VISIBILITY_CXXFLAGS]) + AC_SUBST([HAVE_VISIBILITY]) + AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], + [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) +]) diff --git a/tools/pcre/makevp.bat b/tools/pcre/makevp.bat new file mode 100644 index 00000000..5f795487 --- /dev/null +++ b/tools/pcre/makevp.bat @@ -0,0 +1,66 @@ +:: AH 20-12-06 modified for new PCRE-7.0 and VP/BCC +:: PH 19-03-07 renamed !compile.txt and !linklib.txt as makevp-compile.txt and +:: makevp-linklib.txt +:: PH 26-03-07 re-renamed !compile.txt and !linklib.txt as makevp-c.txt and +:: makevp-l.txt +:: PH 29-03-07 hopefully the final rename to makevp_c and makevp_l +:: AH 27.08.08 updated for new PCRE-7.7 +:: required PCRE.H and CONFIG.H will be generated if not existing + +@echo off +echo. +echo Compiling PCRE with BORLAND C++ for VIRTUAL PASCAL +echo. + +REM This file was contributed by Alexander Tokarev for building PCRE for use +REM with Virtual Pascal. It has not been tested with the latest PCRE release. + +REM This file has been modified and extended to compile with newer PCRE releases +REM by Stefan Weber (Angels Holocaust). + +REM CHANGE THIS FOR YOUR BORLAND C++ COMPILER PATH +SET BORLAND=f:\bcc +REM location of the TASM binaries, if compiling with the -B BCC switch +SET TASM=f:\tasm + +SET PATH=%PATH%;%BORLAND%\bin;%TASM%\bin +SET PCRE_VER=77 +SET COMPILE_DEFAULTS=-DHAVE_CONFIG_H -DPCRE_STATIC -I%BORLAND%\include + +del pcre%PCRE_VER%.lib >nul 2>nul + +:: sh configure + +:: check for needed header files +if not exist pcre.h copy pcre.h.generic pcre.h +if not exist config.h copy config.h.generic config.h + +bcc32 -DDFTABLES %COMPILE_DEFAULTS% -L%BORLAND%\lib dftables.c +IF ERRORLEVEL 1 GOTO ERROR + +:: dftables > chartables.c +dftables pcre_chartables.c + +REM compile and link the PCRE library into lib: option -B for ASM compile works too +bcc32 -a4 -c -RT- -y- -v- -u- -R- -Q- -X -d -fp -ff -P- -O2 -Oc -Ov -3 -w-8004 -w-8064 -w-8065 -w-8012 -UDFTABLES -DVPCOMPAT %COMPILE_DEFAULTS% @makevp_c.txt +IF ERRORLEVEL 1 GOTO ERROR + +tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset *memcmp *strlen +IF ERRORLEVEL 1 GOTO ERROR +tlib pcre%PCRE_VER%.lib @makevp_l.txt +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj +memcmp.obj +strlen.obj +IF ERRORLEVEL 1 GOTO ERROR + +del *.obj *.tds *.bak >nul 2>nul + +echo --- +echo Now the library should be complete. Please check all messages above. +echo Don't care for warnings, it's OK. +goto END + +:ERROR +echo --- +echo Error while compiling PCRE. Aborting... +pause +goto END + +:END diff --git a/tools/pcre/makevp_c.txt b/tools/pcre/makevp_c.txt new file mode 100644 index 00000000..f721511e --- /dev/null +++ b/tools/pcre/makevp_c.txt @@ -0,0 +1,20 @@ +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_info.c +pcre_maketables.c +pcre_newline.c +pcre_ord2utf8.c +pcre_refcount.c +pcre_study.c +pcre_tables.c +pcre_ucd.c +pcre_valid_utf8.c +pcre_version.c +pcre_xclass.c diff --git a/tools/pcre/makevp_l.txt b/tools/pcre/makevp_l.txt new file mode 100644 index 00000000..4acb0031 --- /dev/null +++ b/tools/pcre/makevp_l.txt @@ -0,0 +1,20 @@ ++pcre_byte_order.obj & ++pcre_chartables.obj & ++pcre_compile.obj & ++pcre_config.obj & ++pcre_dfa_exec.obj & ++pcre_exec.obj & ++pcre_fullinfo.obj & ++pcre_get.obj & ++pcre_globals.obj & ++pcre_info.obj & ++pcre_maketables.obj & ++pcre_newline.obj & ++pcre_ord2utf8.obj & ++pcre_refcount.obj & ++pcre_study.obj & ++pcre_tables.obj & ++pcre_ucd.obj & ++pcre_valid_utf8.obj & ++pcre_version.obj & ++pcre_xclass.obj diff --git a/tools/pcre/missing b/tools/pcre/missing new file mode 100644 index 00000000..86a8fc31 --- /dev/null +++ b/tools/pcre/missing @@ -0,0 +1,331 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.13; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/tools/pcre/pcre-config.in b/tools/pcre/pcre-config.in new file mode 100644 index 00000000..ac06a332 --- /dev/null +++ b/tools/pcre/pcre-config.in @@ -0,0 +1,133 @@ +#!/bin/sh + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +exec_prefix_set=no + +cflags="[--cflags]" + +if test @enable_cpp@ = yes ; then + libs="[--libs-cpp]" +else + libs= +fi + +if test @enable_pcre16@ = yes ; then + libs="[--libs16] $libs" +fi + +if test @enable_pcre32@ = yes ; then + libs="[--libs32] $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 +fi + +libR= +case `uname -s` in + *SunOS*) + libR=" -R@libdir@" + ;; + *BSD*) + libR=" -Wl,-R@libdir@" + ;; +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]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + if test $exec_prefix_set = no ; then + exec_prefix=$optarg + fi + ;; + --prefix) + echo $prefix + ;; + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + ;; + --exec-prefix) + echo $exec_prefix + ;; + --version) + echo @PACKAGE_VERSION@ + ;; + --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) + if test @enable_pcre8@ = yes ; then + echo $libS$libR -lpcreposix -lpcre + else + echo "${usage}" 1>&2 + fi + ;; + --libs) + 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 + ;; + --libs32) + if test @enable_pcre32@ = yes ; then + echo $libS$libR -lpcre32 + else + echo "${usage}" 1>&2 + fi + ;; + --libs-cpp) + if test @enable_cpp@ = yes ; then + echo $libS$libR -lpcrecpp -lpcre + else + echo "${usage}" 1>&2 + fi + ;; + *) + echo "${usage}" 1>&2 + exit 1 + ;; + esac + shift +done diff --git a/tools/pcre/pcre.h.generic b/tools/pcre/pcre.h.generic new file mode 100644 index 00000000..a6aa4e93 --- /dev/null +++ b/tools/pcre/pcre.h.generic @@ -0,0 +1,653 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* This is the public header file for the PCRE library, to be #included by +applications that call the PCRE functions. + + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +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. +----------------------------------------------------------------------------- +*/ + +#ifndef _PCRE_H +#define _PCRE_H + +/* The current PCRE version information. */ + +#define PCRE_MAJOR 8 +#define PCRE_MINOR 32 +#define PCRE_PRERELEASE +#define PCRE_DATE 2012-11-30 + +/* 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 +export setting is defined in pcre_internal.h, which includes this file. So we +don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ + +#if defined(_WIN32) && !defined(PCRE_STATIC) +# ifndef PCRE_EXP_DECL +# define PCRE_EXP_DECL extern __declspec(dllimport) +# endif +# ifdef __cplusplus +# ifndef PCRECPP_EXP_DECL +# define PCRECPP_EXP_DECL extern __declspec(dllimport) +# endif +# ifndef PCRECPP_EXP_DEFN +# define PCRECPP_EXP_DEFN __declspec(dllimport) +# endif +# endif +#endif + +/* By default, we use the standard "extern" declarations. */ + +#ifndef PCRE_EXP_DECL +# ifdef __cplusplus +# define PCRE_EXP_DECL extern "C" +# else +# define PCRE_EXP_DECL extern +# endif +#endif + +#ifdef __cplusplus +# ifndef PCRECPP_EXP_DECL +# define PCRECPP_EXP_DECL extern +# endif +# ifndef PCRECPP_EXP_DEFN +# define PCRECPP_EXP_DEFN +# endif +#endif + +/* Have to include stdlib.h in order to ensure that size_t is defined; +it is needed here for malloc. */ + +#include + +/* Allow for C++ users */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Public options. Some are compile-time only, some are run-time only, and some +are both, so we keep them all distinct. However, almost all the bits in the +options word are now used. In the long run, we may have to re-use some of the +compile-time only bits for runtime options, or vice versa. Any of the +compile-time options may be inspected during studying (and therefore JIT +compiling). + +Some options for pcre_compile() change its behaviour but do not affect the +behaviour of the execution functions. Other options are passed through to the +execution functions and affect their behaviour, with or without affecting the +behaviour of pcre_compile(). + +Options that can be passed to pcre_compile() are tagged Cx below, with these +variants: + +C1 Affects compile only +C2 Does not affect compile; affects exec, dfa_exec +C3 Affects compile, exec, dfa_exec +C4 Affects compile, exec, dfa_exec, study +C5 Affects compile, exec, study + +Options that can be set for pcre_exec() and/or pcre_dfa_exec() are flagged with +E and D, respectively. They take precedence over C3, C4, and C5 settings passed +from pcre_compile(). Those that are compatible with JIT execution are flagged +with J. */ + +#define PCRE_CASELESS 0x00000001 /* C1 */ +#define PCRE_MULTILINE 0x00000002 /* C1 */ +#define PCRE_DOTALL 0x00000004 /* C1 */ +#define PCRE_EXTENDED 0x00000008 /* C1 */ +#define PCRE_ANCHORED 0x00000010 /* C4 E D */ +#define PCRE_DOLLAR_ENDONLY 0x00000020 /* C2 */ +#define PCRE_EXTRA 0x00000040 /* C1 */ +#define PCRE_NOTBOL 0x00000080 /* E D J */ +#define PCRE_NOTEOL 0x00000100 /* E D J */ +#define PCRE_UNGREEDY 0x00000200 /* C1 */ +#define PCRE_NOTEMPTY 0x00000400 /* E D J */ +#define PCRE_UTF8 0x00000800 /* C4 ) */ +#define PCRE_UTF16 0x00000800 /* C4 ) Synonyms */ +#define PCRE_UTF32 0x00000800 /* C4 ) */ +#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* C1 */ +#define PCRE_NO_UTF8_CHECK 0x00002000 /* C1 E D J ) */ +#define PCRE_NO_UTF16_CHECK 0x00002000 /* C1 E D J ) Synonyms */ +#define PCRE_NO_UTF32_CHECK 0x00002000 /* C1 E D J ) */ +#define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */ +#define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */ +#define PCRE_PARTIAL 0x00008000 /* E D J ) */ +#define PCRE_DFA_SHORTEST 0x00010000 /* D */ +#define PCRE_DFA_RESTART 0x00020000 /* D */ +#define PCRE_FIRSTLINE 0x00040000 /* C3 */ +#define PCRE_DUPNAMES 0x00080000 /* C1 */ +#define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */ +#define PCRE_NEWLINE_LF 0x00200000 /* C3 E D */ +#define PCRE_NEWLINE_CRLF 0x00300000 /* C3 E D */ +#define PCRE_NEWLINE_ANY 0x00400000 /* C3 E D */ +#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* C3 E D */ +#define PCRE_BSR_ANYCRLF 0x00800000 /* C3 E D */ +#define PCRE_BSR_UNICODE 0x01000000 /* C3 E D */ +#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* C5 */ +#define PCRE_NO_START_OPTIMIZE 0x04000000 /* C2 E D ) Synonyms */ +#define PCRE_NO_START_OPTIMISE 0x04000000 /* C2 E D ) */ +#define PCRE_PARTIAL_HARD 0x08000000 /* E D J */ +#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* E D J */ +#define PCRE_UCP 0x20000000 /* C3 */ + +/* 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) /* Same for 8/16/32 */ +#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16/32 */ +#define PCRE_ERROR_BADUTF32 (-10) /* Same for 8/16/32 */ +#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) +#define PCRE_ERROR_JIT_BADOPTION (-31) +#define PCRE_ERROR_BADLENGTH (-32) + +/* 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 +#define PCRE_UTF8_ERR22 22 + +/* 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 + +/* Specific error codes for UTF-32 validity checks */ + +#define PCRE_UTF32_ERR0 0 +#define PCRE_UTF32_ERR1 1 +#define PCRE_UTF32_ERR2 2 +#define PCRE_UTF32_ERR3 3 + +/* Request types for pcre_fullinfo() */ + +#define PCRE_INFO_OPTIONS 0 +#define PCRE_INFO_SIZE 1 +#define PCRE_INFO_CAPTURECOUNT 2 +#define PCRE_INFO_BACKREFMAX 3 +#define PCRE_INFO_FIRSTBYTE 4 +#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ +#define PCRE_INFO_FIRSTTABLE 5 +#define PCRE_INFO_LASTLITERAL 6 +#define PCRE_INFO_NAMEENTRYSIZE 7 +#define PCRE_INFO_NAMECOUNT 8 +#define PCRE_INFO_NAMETABLE 9 +#define PCRE_INFO_STUDYSIZE 10 +#define PCRE_INFO_DEFAULT_TABLES 11 +#define PCRE_INFO_OKPARTIAL 12 +#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 +#define PCRE_INFO_FIRSTCHARACTER 19 +#define PCRE_INFO_FIRSTCHARACTERFLAGS 20 +#define PCRE_INFO_REQUIREDCHAR 21 +#define PCRE_INFO_REQUIREDCHARFLAGS 22 + +/* Request types for pcre_config(). Do not re-arrange, in order to remain +compatible. */ + +#define PCRE_CONFIG_UTF8 0 +#define PCRE_CONFIG_NEWLINE 1 +#define PCRE_CONFIG_LINK_SIZE 2 +#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 +#define PCRE_CONFIG_MATCH_LIMIT 4 +#define PCRE_CONFIG_STACKRECURSE 5 +#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 +#define PCRE_CONFIG_UTF32 12 + +/* 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 +#define PCRE_STUDY_EXTRA_NEEDED 0x0008 + +/* Bit flags for the pcre[16|32]_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 +#define PCRE_EXTRA_MATCH_LIMIT 0x0002 +#define PCRE_EXTRA_CALLOUT_DATA 0x0004 +#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_pcre32; /* declaration; the definition is private */ +typedef struct real_pcre32 pcre32; + +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; + +struct real_pcre32_jit_stack; /* declaration; the definition is private */ +typedef struct real_pcre32_jit_stack pcre32_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 + +/* If PCRE is compiled with 32 bit character support, PCRE_UCHAR32 must contain +a 32 bit wide signed data type. Otherwise it can be a dummy data type since +pcre32 functions are not implemented. There is a check for this in pcre_internal.h. */ +#ifndef PCRE_UCHAR32 +#define PCRE_UCHAR32 unsigned int +#endif + +#ifndef PCRE_SPTR32 +#define PCRE_SPTR32 const PCRE_UCHAR32 * +#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 *. */ + +#ifndef PCRE_SPTR +#define PCRE_SPTR const char * +#endif + +/* The structure for passing additional data to pcre_exec(). This is defined in +such as way as to be extensible. Always add new fields at the end, in order to +remain compatible. */ + +typedef struct pcre_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() */ + 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; + +/* Same structure as above, but with 32 bit char pointers. */ + +typedef struct pcre32_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_UCHAR32 **mark; /* For passing back a mark pointer */ + void *executable_jit; /* Contains a pointer to a compiled jit code */ +} pcre32_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 +without modification. */ + +typedef struct pcre_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + PCRE_SPTR 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 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; + +/* Same structure as above, but with 32 bit char pointers. */ + +typedef struct pcre32_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + PCRE_SPTR32 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_UCHAR32 *mark; /* Pointer to current mark or NULL */ + /* ------------------------------------------------------------------ */ +} pcre32_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 +that is triggered by the (?) regex item. For Virtual Pascal, these definitions +have to take another form. */ + +#ifndef 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 *); + +PCRE_EXP_DECL void *(*pcre32_malloc)(size_t); +PCRE_EXP_DECL void (*pcre32_free)(void *); +PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t); +PCRE_EXP_DECL void (*pcre32_stack_free)(void *); +PCRE_EXP_DECL int (*pcre32_callout)(pcre32_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 *); + +PCRE_EXP_DECL void *pcre32_malloc(size_t); +PCRE_EXP_DECL void pcre32_free(void *); +PCRE_EXP_DECL void *pcre32_stack_malloc(size_t); +PCRE_EXP_DECL void pcre32_stack_free(void *); +PCRE_EXP_DECL int pcre32_callout(pcre32_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 *); +typedef pcre32_jit_stack *(*pcre32_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 pcre32 *pcre32_compile(PCRE_SPTR32, 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 pcre32 *pcre32_compile2(PCRE_SPTR32, 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 pcre32_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 pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16, + int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int); +PCRE_EXP_DECL int pcre32_copy_named_substring(const pcre32 *, PCRE_SPTR32, + int *, int, PCRE_SPTR32, PCRE_UCHAR32 *, 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 pcre32_copy_substring(PCRE_SPTR32, int *, int, int, + PCRE_UCHAR32 *, 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 pcre32_dfa_exec(const pcre32 *, const pcre32_extra *, + PCRE_SPTR32, 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 int pcre32_exec(const pcre32 *, const pcre32_extra *, + PCRE_SPTR32, int, int, int, int *, int); +PCRE_EXP_DECL int pcre_jit_exec(const pcre *, const pcre_extra *, + PCRE_SPTR, int, int, int, int *, int, + pcre_jit_stack *); +PCRE_EXP_DECL int pcre16_jit_exec(const pcre16 *, const pcre16_extra *, + PCRE_SPTR16, int, int, int, int *, int, + pcre16_jit_stack *); +PCRE_EXP_DECL int pcre32_jit_exec(const pcre32 *, const pcre32_extra *, + PCRE_SPTR32, int, int, int, int *, int, + pcre32_jit_stack *); +PCRE_EXP_DECL void pcre_free_substring(const char *); +PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16); +PCRE_EXP_DECL void pcre32_free_substring(PCRE_SPTR32); +PCRE_EXP_DECL void pcre_free_substring_list(const char **); +PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *); +PCRE_EXP_DECL void pcre32_free_substring_list(PCRE_SPTR32 *); +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 pcre32_fullinfo(const pcre32 *, const pcre32_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 pcre32_get_named_substring(const pcre32 *, PCRE_SPTR32, + int *, int, PCRE_SPTR32, PCRE_SPTR32 *); +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 pcre32_get_stringnumber(const pcre32 *, PCRE_SPTR32); +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 pcre32_get_stringtable_entries(const pcre32 *, PCRE_SPTR32, + PCRE_UCHAR32 **, PCRE_UCHAR32 **); +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 pcre32_get_substring(PCRE_SPTR32, int *, int, int, + PCRE_SPTR32 *); +PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, + const char ***); +PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int, + PCRE_SPTR16 **); +PCRE_EXP_DECL int pcre32_get_substring_list(PCRE_SPTR32, int *, int, + PCRE_SPTR32 **); +PCRE_EXP_DECL const unsigned char *pcre_maketables(void); +PCRE_EXP_DECL const unsigned char *pcre16_maketables(void); +PCRE_EXP_DECL const unsigned char *pcre32_maketables(void); +PCRE_EXP_DECL int pcre_refcount(pcre *, int); +PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int); +PCRE_EXP_DECL int pcre32_refcount(pcre32 *, 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 pcre32_extra *pcre32_study(const pcre32 *, int, const char **); +PCRE_EXP_DECL void pcre_free_study(pcre_extra *); +PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *); +PCRE_EXP_DECL void pcre32_free_study(pcre32_extra *); +PCRE_EXP_DECL const char *pcre_version(void); +PCRE_EXP_DECL const char *pcre16_version(void); +PCRE_EXP_DECL const char *pcre32_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 pcre32_pattern_to_host_byte_order(pcre32 *, pcre32_extra *, + const unsigned char *); +PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *, + PCRE_SPTR16, int, int *, int); +PCRE_EXP_DECL int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *, + PCRE_SPTR32, 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 pcre32_jit_stack *pcre32_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 pcre32_jit_stack_free(pcre32_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 *); +PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *, + pcre32_jit_callback, void *); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* End of pcre.h */ diff --git a/tools/pcre/pcre.h.in b/tools/pcre/pcre.h.in new file mode 100644 index 00000000..2376c9c3 --- /dev/null +++ b/tools/pcre/pcre.h.in @@ -0,0 +1,653 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* This is the public header file for the PCRE library, to be #included by +applications that call the PCRE functions. + + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +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. +----------------------------------------------------------------------------- +*/ + +#ifndef _PCRE_H +#define _PCRE_H + +/* The current PCRE version information. */ + +#define PCRE_MAJOR @PCRE_MAJOR@ +#define PCRE_MINOR @PCRE_MINOR@ +#define PCRE_PRERELEASE @PCRE_PRERELEASE@ +#define PCRE_DATE @PCRE_DATE@ + +/* 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 +export setting is defined in pcre_internal.h, which includes this file. So we +don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ + +#if defined(_WIN32) && !defined(PCRE_STATIC) +# ifndef PCRE_EXP_DECL +# define PCRE_EXP_DECL extern __declspec(dllimport) +# endif +# ifdef __cplusplus +# ifndef PCRECPP_EXP_DECL +# define PCRECPP_EXP_DECL extern __declspec(dllimport) +# endif +# ifndef PCRECPP_EXP_DEFN +# define PCRECPP_EXP_DEFN __declspec(dllimport) +# endif +# endif +#endif + +/* By default, we use the standard "extern" declarations. */ + +#ifndef PCRE_EXP_DECL +# ifdef __cplusplus +# define PCRE_EXP_DECL extern "C" +# else +# define PCRE_EXP_DECL extern +# endif +#endif + +#ifdef __cplusplus +# ifndef PCRECPP_EXP_DECL +# define PCRECPP_EXP_DECL extern +# endif +# ifndef PCRECPP_EXP_DEFN +# define PCRECPP_EXP_DEFN +# endif +#endif + +/* Have to include stdlib.h in order to ensure that size_t is defined; +it is needed here for malloc. */ + +#include + +/* Allow for C++ users */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Public options. Some are compile-time only, some are run-time only, and some +are both, so we keep them all distinct. However, almost all the bits in the +options word are now used. In the long run, we may have to re-use some of the +compile-time only bits for runtime options, or vice versa. Any of the +compile-time options may be inspected during studying (and therefore JIT +compiling). + +Some options for pcre_compile() change its behaviour but do not affect the +behaviour of the execution functions. Other options are passed through to the +execution functions and affect their behaviour, with or without affecting the +behaviour of pcre_compile(). + +Options that can be passed to pcre_compile() are tagged Cx below, with these +variants: + +C1 Affects compile only +C2 Does not affect compile; affects exec, dfa_exec +C3 Affects compile, exec, dfa_exec +C4 Affects compile, exec, dfa_exec, study +C5 Affects compile, exec, study + +Options that can be set for pcre_exec() and/or pcre_dfa_exec() are flagged with +E and D, respectively. They take precedence over C3, C4, and C5 settings passed +from pcre_compile(). Those that are compatible with JIT execution are flagged +with J. */ + +#define PCRE_CASELESS 0x00000001 /* C1 */ +#define PCRE_MULTILINE 0x00000002 /* C1 */ +#define PCRE_DOTALL 0x00000004 /* C1 */ +#define PCRE_EXTENDED 0x00000008 /* C1 */ +#define PCRE_ANCHORED 0x00000010 /* C4 E D */ +#define PCRE_DOLLAR_ENDONLY 0x00000020 /* C2 */ +#define PCRE_EXTRA 0x00000040 /* C1 */ +#define PCRE_NOTBOL 0x00000080 /* E D J */ +#define PCRE_NOTEOL 0x00000100 /* E D J */ +#define PCRE_UNGREEDY 0x00000200 /* C1 */ +#define PCRE_NOTEMPTY 0x00000400 /* E D J */ +#define PCRE_UTF8 0x00000800 /* C4 ) */ +#define PCRE_UTF16 0x00000800 /* C4 ) Synonyms */ +#define PCRE_UTF32 0x00000800 /* C4 ) */ +#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* C1 */ +#define PCRE_NO_UTF8_CHECK 0x00002000 /* C1 E D J ) */ +#define PCRE_NO_UTF16_CHECK 0x00002000 /* C1 E D J ) Synonyms */ +#define PCRE_NO_UTF32_CHECK 0x00002000 /* C1 E D J ) */ +#define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */ +#define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */ +#define PCRE_PARTIAL 0x00008000 /* E D J ) */ +#define PCRE_DFA_SHORTEST 0x00010000 /* D */ +#define PCRE_DFA_RESTART 0x00020000 /* D */ +#define PCRE_FIRSTLINE 0x00040000 /* C3 */ +#define PCRE_DUPNAMES 0x00080000 /* C1 */ +#define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */ +#define PCRE_NEWLINE_LF 0x00200000 /* C3 E D */ +#define PCRE_NEWLINE_CRLF 0x00300000 /* C3 E D */ +#define PCRE_NEWLINE_ANY 0x00400000 /* C3 E D */ +#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* C3 E D */ +#define PCRE_BSR_ANYCRLF 0x00800000 /* C3 E D */ +#define PCRE_BSR_UNICODE 0x01000000 /* C3 E D */ +#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* C5 */ +#define PCRE_NO_START_OPTIMIZE 0x04000000 /* C2 E D ) Synonyms */ +#define PCRE_NO_START_OPTIMISE 0x04000000 /* C2 E D ) */ +#define PCRE_PARTIAL_HARD 0x08000000 /* E D J */ +#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* E D J */ +#define PCRE_UCP 0x20000000 /* C3 */ + +/* 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) /* Same for 8/16/32 */ +#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16/32 */ +#define PCRE_ERROR_BADUTF32 (-10) /* Same for 8/16/32 */ +#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) +#define PCRE_ERROR_JIT_BADOPTION (-31) +#define PCRE_ERROR_BADLENGTH (-32) + +/* 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 +#define PCRE_UTF8_ERR22 22 + +/* 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 + +/* Specific error codes for UTF-32 validity checks */ + +#define PCRE_UTF32_ERR0 0 +#define PCRE_UTF32_ERR1 1 +#define PCRE_UTF32_ERR2 2 +#define PCRE_UTF32_ERR3 3 + +/* Request types for pcre_fullinfo() */ + +#define PCRE_INFO_OPTIONS 0 +#define PCRE_INFO_SIZE 1 +#define PCRE_INFO_CAPTURECOUNT 2 +#define PCRE_INFO_BACKREFMAX 3 +#define PCRE_INFO_FIRSTBYTE 4 +#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ +#define PCRE_INFO_FIRSTTABLE 5 +#define PCRE_INFO_LASTLITERAL 6 +#define PCRE_INFO_NAMEENTRYSIZE 7 +#define PCRE_INFO_NAMECOUNT 8 +#define PCRE_INFO_NAMETABLE 9 +#define PCRE_INFO_STUDYSIZE 10 +#define PCRE_INFO_DEFAULT_TABLES 11 +#define PCRE_INFO_OKPARTIAL 12 +#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 +#define PCRE_INFO_FIRSTCHARACTER 19 +#define PCRE_INFO_FIRSTCHARACTERFLAGS 20 +#define PCRE_INFO_REQUIREDCHAR 21 +#define PCRE_INFO_REQUIREDCHARFLAGS 22 + +/* Request types for pcre_config(). Do not re-arrange, in order to remain +compatible. */ + +#define PCRE_CONFIG_UTF8 0 +#define PCRE_CONFIG_NEWLINE 1 +#define PCRE_CONFIG_LINK_SIZE 2 +#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 +#define PCRE_CONFIG_MATCH_LIMIT 4 +#define PCRE_CONFIG_STACKRECURSE 5 +#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 +#define PCRE_CONFIG_UTF32 12 + +/* 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 +#define PCRE_STUDY_EXTRA_NEEDED 0x0008 + +/* Bit flags for the pcre[16|32]_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 +#define PCRE_EXTRA_MATCH_LIMIT 0x0002 +#define PCRE_EXTRA_CALLOUT_DATA 0x0004 +#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_pcre32; /* declaration; the definition is private */ +typedef struct real_pcre32 pcre32; + +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; + +struct real_pcre32_jit_stack; /* declaration; the definition is private */ +typedef struct real_pcre32_jit_stack pcre32_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 + +/* If PCRE is compiled with 32 bit character support, PCRE_UCHAR32 must contain +a 32 bit wide signed data type. Otherwise it can be a dummy data type since +pcre32 functions are not implemented. There is a check for this in pcre_internal.h. */ +#ifndef PCRE_UCHAR32 +#define PCRE_UCHAR32 unsigned int +#endif + +#ifndef PCRE_SPTR32 +#define PCRE_SPTR32 const PCRE_UCHAR32 * +#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 *. */ + +#ifndef PCRE_SPTR +#define PCRE_SPTR const char * +#endif + +/* The structure for passing additional data to pcre_exec(). This is defined in +such as way as to be extensible. Always add new fields at the end, in order to +remain compatible. */ + +typedef struct pcre_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() */ + 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; + +/* Same structure as above, but with 32 bit char pointers. */ + +typedef struct pcre32_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_UCHAR32 **mark; /* For passing back a mark pointer */ + void *executable_jit; /* Contains a pointer to a compiled jit code */ +} pcre32_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 +without modification. */ + +typedef struct pcre_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + PCRE_SPTR 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 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; + +/* Same structure as above, but with 32 bit char pointers. */ + +typedef struct pcre32_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + PCRE_SPTR32 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_UCHAR32 *mark; /* Pointer to current mark or NULL */ + /* ------------------------------------------------------------------ */ +} pcre32_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 +that is triggered by the (?) regex item. For Virtual Pascal, these definitions +have to take another form. */ + +#ifndef 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 *); + +PCRE_EXP_DECL void *(*pcre32_malloc)(size_t); +PCRE_EXP_DECL void (*pcre32_free)(void *); +PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t); +PCRE_EXP_DECL void (*pcre32_stack_free)(void *); +PCRE_EXP_DECL int (*pcre32_callout)(pcre32_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 *); + +PCRE_EXP_DECL void *pcre32_malloc(size_t); +PCRE_EXP_DECL void pcre32_free(void *); +PCRE_EXP_DECL void *pcre32_stack_malloc(size_t); +PCRE_EXP_DECL void pcre32_stack_free(void *); +PCRE_EXP_DECL int pcre32_callout(pcre32_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 *); +typedef pcre32_jit_stack *(*pcre32_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 pcre32 *pcre32_compile(PCRE_SPTR32, 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 pcre32 *pcre32_compile2(PCRE_SPTR32, 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 pcre32_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 pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16, + int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int); +PCRE_EXP_DECL int pcre32_copy_named_substring(const pcre32 *, PCRE_SPTR32, + int *, int, PCRE_SPTR32, PCRE_UCHAR32 *, 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 pcre32_copy_substring(PCRE_SPTR32, int *, int, int, + PCRE_UCHAR32 *, 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 pcre32_dfa_exec(const pcre32 *, const pcre32_extra *, + PCRE_SPTR32, 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 int pcre32_exec(const pcre32 *, const pcre32_extra *, + PCRE_SPTR32, int, int, int, int *, int); +PCRE_EXP_DECL int pcre_jit_exec(const pcre *, const pcre_extra *, + PCRE_SPTR, int, int, int, int *, int, + pcre_jit_stack *); +PCRE_EXP_DECL int pcre16_jit_exec(const pcre16 *, const pcre16_extra *, + PCRE_SPTR16, int, int, int, int *, int, + pcre16_jit_stack *); +PCRE_EXP_DECL int pcre32_jit_exec(const pcre32 *, const pcre32_extra *, + PCRE_SPTR32, int, int, int, int *, int, + pcre32_jit_stack *); +PCRE_EXP_DECL void pcre_free_substring(const char *); +PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16); +PCRE_EXP_DECL void pcre32_free_substring(PCRE_SPTR32); +PCRE_EXP_DECL void pcre_free_substring_list(const char **); +PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *); +PCRE_EXP_DECL void pcre32_free_substring_list(PCRE_SPTR32 *); +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 pcre32_fullinfo(const pcre32 *, const pcre32_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 pcre32_get_named_substring(const pcre32 *, PCRE_SPTR32, + int *, int, PCRE_SPTR32, PCRE_SPTR32 *); +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 pcre32_get_stringnumber(const pcre32 *, PCRE_SPTR32); +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 pcre32_get_stringtable_entries(const pcre32 *, PCRE_SPTR32, + PCRE_UCHAR32 **, PCRE_UCHAR32 **); +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 pcre32_get_substring(PCRE_SPTR32, int *, int, int, + PCRE_SPTR32 *); +PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, + const char ***); +PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int, + PCRE_SPTR16 **); +PCRE_EXP_DECL int pcre32_get_substring_list(PCRE_SPTR32, int *, int, + PCRE_SPTR32 **); +PCRE_EXP_DECL const unsigned char *pcre_maketables(void); +PCRE_EXP_DECL const unsigned char *pcre16_maketables(void); +PCRE_EXP_DECL const unsigned char *pcre32_maketables(void); +PCRE_EXP_DECL int pcre_refcount(pcre *, int); +PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int); +PCRE_EXP_DECL int pcre32_refcount(pcre32 *, 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 pcre32_extra *pcre32_study(const pcre32 *, int, const char **); +PCRE_EXP_DECL void pcre_free_study(pcre_extra *); +PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *); +PCRE_EXP_DECL void pcre32_free_study(pcre32_extra *); +PCRE_EXP_DECL const char *pcre_version(void); +PCRE_EXP_DECL const char *pcre16_version(void); +PCRE_EXP_DECL const char *pcre32_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 pcre32_pattern_to_host_byte_order(pcre32 *, pcre32_extra *, + const unsigned char *); +PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *, + PCRE_SPTR16, int, int *, int); +PCRE_EXP_DECL int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *, + PCRE_SPTR32, 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 pcre32_jit_stack *pcre32_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 pcre32_jit_stack_free(pcre32_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 *); +PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *, + pcre32_jit_callback, void *); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* End of pcre.h */ diff --git a/tools/pcre/pcre16_byte_order.c b/tools/pcre/pcre16_byte_order.c new file mode 100644 index 00000000..11d2973a --- /dev/null +++ b/tools/pcre/pcre16_byte_order.c @@ -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 --git a/tools/pcre/pcre16_chartables.c b/tools/pcre/pcre16_chartables.c new file mode 100644 index 00000000..7c0ff35f --- /dev/null +++ b/tools/pcre/pcre16_chartables.c @@ -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 --git a/tools/pcre/pcre16_compile.c b/tools/pcre/pcre16_compile.c new file mode 100644 index 00000000..e499b670 --- /dev/null +++ b/tools/pcre/pcre16_compile.c @@ -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 --git a/tools/pcre/pcre16_config.c b/tools/pcre/pcre16_config.c new file mode 100644 index 00000000..b5213876 --- /dev/null +++ b/tools/pcre/pcre16_config.c @@ -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 --git a/tools/pcre/pcre16_dfa_exec.c b/tools/pcre/pcre16_dfa_exec.c new file mode 100644 index 00000000..2ba740e9 --- /dev/null +++ b/tools/pcre/pcre16_dfa_exec.c @@ -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 --git a/tools/pcre/pcre16_exec.c b/tools/pcre/pcre16_exec.c new file mode 100644 index 00000000..7417b177 --- /dev/null +++ b/tools/pcre/pcre16_exec.c @@ -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 --git a/tools/pcre/pcre16_fullinfo.c b/tools/pcre/pcre16_fullinfo.c new file mode 100644 index 00000000..544dca6e --- /dev/null +++ b/tools/pcre/pcre16_fullinfo.c @@ -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 --git a/tools/pcre/pcre16_get.c b/tools/pcre/pcre16_get.c new file mode 100644 index 00000000..3ded08c6 --- /dev/null +++ b/tools/pcre/pcre16_get.c @@ -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 --git a/tools/pcre/pcre16_globals.c b/tools/pcre/pcre16_globals.c new file mode 100644 index 00000000..a136b3d8 --- /dev/null +++ b/tools/pcre/pcre16_globals.c @@ -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 --git a/tools/pcre/pcre16_jit_compile.c b/tools/pcre/pcre16_jit_compile.c new file mode 100644 index 00000000..ab0cacd7 --- /dev/null +++ b/tools/pcre/pcre16_jit_compile.c @@ -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 --git a/tools/pcre/pcre16_maketables.c b/tools/pcre/pcre16_maketables.c new file mode 100644 index 00000000..b1cd1c57 --- /dev/null +++ b/tools/pcre/pcre16_maketables.c @@ -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 --git a/tools/pcre/pcre16_newline.c b/tools/pcre/pcre16_newline.c new file mode 100644 index 00000000..7fe20140 --- /dev/null +++ b/tools/pcre/pcre16_newline.c @@ -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 --git a/tools/pcre/pcre16_ord2utf16.c b/tools/pcre/pcre16_ord2utf16.c new file mode 100644 index 00000000..8e2ce5ea --- /dev/null +++ b/tools/pcre/pcre16_ord2utf16.c @@ -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-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 +*/ + +unsigned int +PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer) +{ +#ifdef SUPPORT_UTF + +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 --git a/tools/pcre/pcre16_printint.c b/tools/pcre/pcre16_printint.c new file mode 100644 index 00000000..33d8c340 --- /dev/null +++ b/tools/pcre/pcre16_printint.c @@ -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 --git a/tools/pcre/pcre16_refcount.c b/tools/pcre/pcre16_refcount.c new file mode 100644 index 00000000..d3d15439 --- /dev/null +++ b/tools/pcre/pcre16_refcount.c @@ -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 --git a/tools/pcre/pcre16_string_utils.c b/tools/pcre/pcre16_string_utils.c new file mode 100644 index 00000000..382c4079 --- /dev/null +++ b/tools/pcre/pcre16_string_utils.c @@ -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 --git a/tools/pcre/pcre16_study.c b/tools/pcre/pcre16_study.c new file mode 100644 index 00000000..f87de081 --- /dev/null +++ b/tools/pcre/pcre16_study.c @@ -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 --git a/tools/pcre/pcre16_tables.c b/tools/pcre/pcre16_tables.c new file mode 100644 index 00000000..d8429709 --- /dev/null +++ b/tools/pcre/pcre16_tables.c @@ -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 --git a/tools/pcre/pcre16_ucd.c b/tools/pcre/pcre16_ucd.c new file mode 100644 index 00000000..ee23439a --- /dev/null +++ b/tools/pcre/pcre16_ucd.c @@ -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 --git a/tools/pcre/pcre16_utf16_utils.c b/tools/pcre/pcre16_utf16_utils.c new file mode 100644 index 00000000..49ced0c0 --- /dev/null +++ b/tools/pcre/pcre16_utf16_utils.c @@ -0,0 +1,130 @@ +/************************************************* +* 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 /* Not SUPPORT_UTF */ +(void)(output); /* Keep picky compilers happy */ +(void)(input); +(void)(keep_boms); +(void)(host_byte_order); +#endif /* SUPPORT_UTF */ +return length; +} + +/* End of pcre16_utf16_utils.c */ diff --git a/tools/pcre/pcre16_valid_utf16.c b/tools/pcre/pcre16_valid_utf16.c new file mode 100644 index 00000000..c06023a7 --- /dev/null +++ b/tools/pcre/pcre16_valid_utf16.c @@ -0,0 +1,156 @@ +/************************************************* +* 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 Non-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_uint32 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. */ + + /* Check for non-characters */ + if ((c & 0xfffeu) == 0xfffeu || (c >= 0xfdd0u && c <= 0xfdefu)) + { + *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 + { + /* Valid surrogate, but check for non-characters */ + c = (((c & 0x3ffu) << 10) | (*p & 0x3ffu)) + 0x10000u; + if ((c & 0xfffeu) == 0xfffeu) + { + *erroroffset = p - string; + return PCRE_UTF16_ERR4; + } + } + } + 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); +(void)(erroroffset); +#endif /* SUPPORT_UTF */ + +return PCRE_UTF16_ERR0; /* This indicates success */ +} + +/* End of pcre16_valid_utf16.c */ diff --git a/tools/pcre/pcre16_version.c b/tools/pcre/pcre16_version.c new file mode 100644 index 00000000..e991b1a8 --- /dev/null +++ b/tools/pcre/pcre16_version.c @@ -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 --git a/tools/pcre/pcre16_xclass.c b/tools/pcre/pcre16_xclass.c new file mode 100644 index 00000000..5aac2a36 --- /dev/null +++ b/tools/pcre/pcre16_xclass.c @@ -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 --git a/tools/pcre/pcre32_byte_order.c b/tools/pcre/pcre32_byte_order.c new file mode 100644 index 00000000..9cf53627 --- /dev/null +++ b/tools/pcre/pcre32_byte_order.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_byte_order.c" + +/* End of pcre32_byte_order.c */ diff --git a/tools/pcre/pcre32_chartables.c b/tools/pcre/pcre32_chartables.c new file mode 100644 index 00000000..b5d8c23d --- /dev/null +++ b/tools/pcre/pcre32_chartables.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_chartables.c" + +/* End of pcre32_chartables.c */ diff --git a/tools/pcre/pcre32_compile.c b/tools/pcre/pcre32_compile.c new file mode 100644 index 00000000..d781eb37 --- /dev/null +++ b/tools/pcre/pcre32_compile.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_compile.c" + +/* End of pcre32_compile.c */ diff --git a/tools/pcre/pcre32_config.c b/tools/pcre/pcre32_config.c new file mode 100644 index 00000000..d63f3e9e --- /dev/null +++ b/tools/pcre/pcre32_config.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_config.c" + +/* End of pcre32_config.c */ diff --git a/tools/pcre/pcre32_dfa_exec.c b/tools/pcre/pcre32_dfa_exec.c new file mode 100644 index 00000000..b0bfd34f --- /dev/null +++ b/tools/pcre/pcre32_dfa_exec.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_dfa_exec.c" + +/* End of pcre32_dfa_exec.c */ diff --git a/tools/pcre/pcre32_exec.c b/tools/pcre/pcre32_exec.c new file mode 100644 index 00000000..8170ed77 --- /dev/null +++ b/tools/pcre/pcre32_exec.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_exec.c" + +/* End of pcre32_exec.c */ diff --git a/tools/pcre/pcre32_fullinfo.c b/tools/pcre/pcre32_fullinfo.c new file mode 100644 index 00000000..6ecc5209 --- /dev/null +++ b/tools/pcre/pcre32_fullinfo.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_fullinfo.c" + +/* End of pcre32_fullinfo.c */ diff --git a/tools/pcre/pcre32_get.c b/tools/pcre/pcre32_get.c new file mode 100644 index 00000000..d35deee0 --- /dev/null +++ b/tools/pcre/pcre32_get.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_get.c" + +/* End of pcre32_get.c */ diff --git a/tools/pcre/pcre32_globals.c b/tools/pcre/pcre32_globals.c new file mode 100644 index 00000000..32e0914c --- /dev/null +++ b/tools/pcre/pcre32_globals.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_globals.c" + +/* End of pcre32_globals.c */ diff --git a/tools/pcre/pcre32_jit_compile.c b/tools/pcre/pcre32_jit_compile.c new file mode 100644 index 00000000..2e7c6f97 --- /dev/null +++ b/tools/pcre/pcre32_jit_compile.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_jit_compile.c" + +/* End of pcre32_jit_compile.c */ diff --git a/tools/pcre/pcre32_maketables.c b/tools/pcre/pcre32_maketables.c new file mode 100644 index 00000000..5d1b1c64 --- /dev/null +++ b/tools/pcre/pcre32_maketables.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_maketables.c" + +/* End of pcre32_maketables.c */ diff --git a/tools/pcre/pcre32_newline.c b/tools/pcre/pcre32_newline.c new file mode 100644 index 00000000..7f8d5360 --- /dev/null +++ b/tools/pcre/pcre32_newline.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_newline.c" + +/* End of pcre32_newline.c */ diff --git a/tools/pcre/pcre32_ord2utf32.c b/tools/pcre/pcre32_ord2utf32.c new file mode 100644 index 00000000..606bcb3d --- /dev/null +++ b/tools/pcre/pcre32_ord2utf32.c @@ -0,0 +1,82 @@ +/************************************************* +* 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 UTF32 string. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Generate code with 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_internal.h" + +/************************************************* +* Convert character value to UTF-32 * +*************************************************/ + +/* This function takes an integer value in the range 0 - 0x10ffff +and encodes it as a UTF-32 character in 1 pcre_uchars. + +Arguments: + cvalue the character value + buffer pointer to buffer for result - at least 1 pcre_uchars long + +Returns: number of characters placed in the buffer +*/ + +unsigned int +PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer) +{ +#ifdef SUPPORT_UTF + +*buffer = (pcre_uchar)cvalue; +return 1; + +#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 pcre32_ord2utf32.c */ diff --git a/tools/pcre/pcre32_printint.c b/tools/pcre/pcre32_printint.c new file mode 100644 index 00000000..f3fd7b25 --- /dev/null +++ b/tools/pcre/pcre32_printint.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_printint.c" + +/* End of pcre32_printint.c */ diff --git a/tools/pcre/pcre32_refcount.c b/tools/pcre/pcre32_refcount.c new file mode 100644 index 00000000..dbdf432d --- /dev/null +++ b/tools/pcre/pcre32_refcount.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_refcount.c" + +/* End of pcre32_refcount.c */ diff --git a/tools/pcre/pcre32_string_utils.c b/tools/pcre/pcre32_string_utils.c new file mode 100644 index 00000000..e37b3d48 --- /dev/null +++ b/tools/pcre/pcre32_string_utils.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_string_utils.c" + +/* End of pcre32_string_utils.c */ diff --git a/tools/pcre/pcre32_study.c b/tools/pcre/pcre32_study.c new file mode 100644 index 00000000..d3a3afed --- /dev/null +++ b/tools/pcre/pcre32_study.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_study.c" + +/* End of pcre32_study.c */ diff --git a/tools/pcre/pcre32_tables.c b/tools/pcre/pcre32_tables.c new file mode 100644 index 00000000..3d94cca3 --- /dev/null +++ b/tools/pcre/pcre32_tables.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_tables.c" + +/* End of pcre32_tables.c */ diff --git a/tools/pcre/pcre32_ucd.c b/tools/pcre/pcre32_ucd.c new file mode 100644 index 00000000..befe22d3 --- /dev/null +++ b/tools/pcre/pcre32_ucd.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_ucd.c" + +/* End of pcre32_ucd.c */ diff --git a/tools/pcre/pcre32_utf32_utils.c b/tools/pcre/pcre32_utf32_utils.c new file mode 100644 index 00000000..f844e237 --- /dev/null +++ b/tools/pcre/pcre32_utf32_utils.c @@ -0,0 +1,141 @@ +/************************************************* +* 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-32 character +strings to host byte order. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Generate code with 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_internal.h" + +#ifdef SUPPORT_UTF +static pcre_uint32 +swap_uint32(pcre_uint32 value) +{ +return ((value & 0x000000ff) << 24) | + ((value & 0x0000ff00) << 8) | + ((value & 0x00ff0000) >> 8) | + (value >> 24); +} +#endif + + +/************************************************* +* Convert any UTF-32 string to host byte order * +*************************************************/ + +/* This function takes an UTF-32 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-32 string + length the number of 32-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 32-bit units placed into the output buffer, + including the zero-terminator +*/ + +int +pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *output, PCRE_SPTR32 input, + int length, int *host_byte_order, int keep_boms) +{ +#ifdef SUPPORT_UTF +/* This function converts any UTF-32 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) + end = iptr + STRLEN_UC(iptr) + 1; +else + end = iptr + length; + +while (iptr < end) + { + c = *iptr++; + if (c == 0x0000feffu || c == 0xfffe0000u) + { + /* Detecting the byte order of the machine is unnecessary, it is + enough to know that the UTF-32 string has the same byte order or not. */ + host_bo = c == 0x0000feffu; + if (keep_boms != 0) + *optr++ = 0x0000feffu; + } + else + *optr++ = host_bo ? c : swap_uint32(c); + } +if (host_byte_order != NULL) + *host_byte_order = host_bo; + +#else /* SUPPORT_UTF */ +(void)(output); /* Keep picky compilers happy */ +(void)(input); +(void)(keep_boms); +(void)(host_byte_order); +#endif /* SUPPORT_UTF */ +return length; +} + +/* End of pcre32_utf32_utils.c */ diff --git a/tools/pcre/pcre32_valid_utf32.c b/tools/pcre/pcre32_valid_utf32.c new file mode 100644 index 00000000..ff0b0c2e --- /dev/null +++ b/tools/pcre/pcre32_valid_utf32.c @@ -0,0 +1,131 @@ +/************************************************* +* 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-32 character +strings. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Generate code with 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_internal.h" + +/************************************************* +* Validate a UTF-32 string * +*************************************************/ + +/* This function is called (optionally) at the start of compile or match, to +check that a supposed UTF-32 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. + +More information about the details of the error are passed +back in the returned value: + +PCRE_UTF32_ERR0 No error +PCRE_UTF32_ERR1 Surrogate character +PCRE_UTF32_ERR2 Non-character +PCRE_UTF32_ERR3 Character > 0x10ffff + +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-32 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 & 0xfffff800u) != 0xd800u) + { + /* Normal UTF-32 code point. Neither high nor low surrogate. */ + + /* Check for non-characters */ + if ((c & 0xfffeu) == 0xfffeu || (c >= 0xfdd0u && c <= 0xfdefu)) + { + *erroroffset = p - string; + return PCRE_UTF32_ERR2; + } + else if (c > 0x10ffffu) + { + *erroroffset = p - string; + return PCRE_UTF32_ERR3; + } + } + else + { + /* A surrogate */ + *erroroffset = p - string; + return PCRE_UTF32_ERR1; + } + } + +#else /* SUPPORT_UTF */ +(void)(string); /* Keep picky compilers happy */ +(void)(length); +(void)(erroroffset); +#endif /* SUPPORT_UTF */ + +return PCRE_UTF32_ERR0; /* This indicates success */ +} + +/* End of pcre32_valid_utf32.c */ diff --git a/tools/pcre/pcre32_version.c b/tools/pcre/pcre32_version.c new file mode 100644 index 00000000..fdaad9b0 --- /dev/null +++ b/tools/pcre/pcre32_version.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_version.c" + +/* End of pcre32_version.c */ diff --git a/tools/pcre/pcre32_xclass.c b/tools/pcre/pcre32_xclass.c new file mode 100644 index 00000000..5662408a --- /dev/null +++ b/tools/pcre/pcre32_xclass.c @@ -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 32 bit character support. */ +#define COMPILE_PCRE32 + +#include "pcre_xclass.c" + +/* End of pcre32_xclass.c */ diff --git a/tools/pcre/pcre_byte_order.c b/tools/pcre/pcre_byte_order.c new file mode 100644 index 00000000..472eb38b --- /dev/null +++ b/tools/pcre/pcre_byte_order.c @@ -0,0 +1,318 @@ +/************************************************* +* 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 +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re, + pcre_extra *extra_data, const unsigned char *tables) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re, + pcre16_extra *extra_data, const unsigned char *tables) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DECL int pcre32_pattern_to_host_byte_order(pcre32 *argument_re, + pcre32_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; +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +BOOL utf; +BOOL utf16_char; +#endif /* SUPPORT_UTF && COMPILE_PCRE16 */ +#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); +#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 +re->first_char = swap_uint16(re->first_char); +re->req_char = swap_uint16(re->req_char); +#elif defined COMPILE_PCRE32 +re->first_char = swap_uint32(re->first_char); +re->req_char = swap_uint32(re->req_char); +#endif +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; +#ifdef COMPILE_PCRE32 +re->dummy1 = swap_uint16(re->dummy1); +re->dummy2 = swap_uint16(re->dummy2); +#endif + +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; +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +utf = (re->options & PCRE_UTF16) != 0; +utf16_char = FALSE; +#endif /* SUPPORT_UTF && COMPILE_PCRE16 */ + +while(TRUE) + { + /* Swap previous characters. */ + while (length-- > 0) + { +#if defined COMPILE_PCRE16 + *ptr = swap_uint16(*ptr); +#elif defined COMPILE_PCRE32 + *ptr = swap_uint32(*ptr); +#endif + ptr++; + } +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 + 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; +#if defined COMPILE_PCRE16 + *ptr = swap_uint16(*ptr); +#elif defined COMPILE_PCRE32 + *ptr = swap_uint32(*ptr); +#endif + switch (*ptr) + { + case OP_END: + return 0; + +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 + 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++; +#if defined COMPILE_PCRE16 + *ptr = swap_uint16(*ptr); +#elif defined COMPILE_PCRE32 + *ptr = swap_uint32(*ptr); +#endif +#ifndef COMPILE_PCRE32 + if (LINK_SIZE > 1) + { + /* LINK_SIZE can be 1 or 2 in 16 bit mode. */ + ptr++; + *ptr = swap_uint16(*ptr); + } +#endif + ptr++; + length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1); +#if defined COMPILE_PCRE16 + *ptr = swap_uint16(*ptr); +#elif defined COMPILE_PCRE32 + *ptr = swap_uint32(*ptr); +#endif + 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/32 bit mode. */ +#endif /* !COMPILE_PCRE8 */ + +return 0; +} + +/* End of pcre_byte_order.c */ diff --git a/tools/pcre/pcre_chartables.c.dist b/tools/pcre/pcre_chartables.c.dist new file mode 100644 index 00000000..2a39e9ff --- /dev/null +++ b/tools/pcre/pcre_chartables.c.dist @@ -0,0 +1,198 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* This file contains character tables that are used when no external tables +are passed to PCRE by the application that calls it. The tables are used only +for characters whose code values are less than 256. + +This is a default version of the tables that assumes ASCII encoding. A program +called dftables (which is distributed with PCRE) can be used to build +alternative versions of this file. This is necessary if you are running in an +EBCDIC environment, or if you want to default to a different encoding, for +example ISO-8859-1. When dftables is run, it creates these tables in the +current locale. If PCRE is configured with --enable-rebuild-chartables, this +happens automatically. + +The following #includes are present because without them gcc 4.x may remove the +array definition from the final binary if PCRE is built into a static library +and dead code stripping is activated. This leads to link errors. Pulling in the +header ensures that the array gets flagged as "someone outside this compilation +unit might reference this" and so it will always be supplied to the linker. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + +const pcre_uint8 PRIV(default_tables)[] = { + +/* This table is a lower casing table. */ + + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122, 91, 92, 93, 94, 95, + 96, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122,123,124,125,126,127, + 128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151, + 152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167, + 168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183, + 184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231, + 232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255, + +/* This table is a case flipping table. */ + + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122, 91, 92, 93, 94, 95, + 96, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90,123,124,125,126,127, + 128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151, + 152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167, + 168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183, + 184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231, + 232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255, + +/* This table contains bit maps for various character classes. Each map is 32 +bytes long and the bits run from the least significant end of each byte. The +classes that have their own maps are: space, xdigit, digit, upper, lower, word, +graph, print, punct, and cntrl. Other classes are built from combinations. */ + + 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, + 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + +/* This table identifies various classes of character by individual bits: + 0x01 white space character + 0x02 letter + 0x04 decimal digit + 0x08 hexadecimal digit + 0x10 alphanumeric or '_' + 0x80 regular expression metacharacter or binary zero +*/ + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ + 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ + 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ + 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ + 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ + 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ + 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ + 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ + 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ + 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ + +/* End of pcre_chartables.c */ diff --git a/tools/pcre/pcre_compile.c b/tools/pcre/pcre_compile.c new file mode 100644 index 00000000..5f0c8ed0 --- /dev/null +++ b/tools/pcre/pcre_compile.c @@ -0,0 +1,8386 @@ +/************************************************* +* 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 the external function pcre_compile(), along with +supporting internal functions that are not used by other modules. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define NLBLOCK cd /* Block containing newline information */ +#define PSSTART start_pattern /* Field containing processed string start */ +#define PSEND end_pattern /* Field containing processed string end */ + +#include "pcre_internal.h" + + +/* When PCRE_DEBUG is defined, we need the pcre(16|32)_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 +/* pcre_printint.c should not include any headers */ +#define PCRE_INCLUDED +#include "pcre_printint.c" +#undef PCRE_INCLUDED +#endif + + +/* Macro for setting individual bits in class bitmaps. */ + +#define SETBIT(a,b) a[(b)/8] |= (1 << ((b)&7)) + +/* Maximum length value to check against when making sure that the integer that +holds the compiled pattern length does not overflow. We make it a bit less than +INT_MAX to allow for adding in group terminating bytes, so that we don't have +to check them every time. */ + +#define OFLOW_MAX (INT_MAX - 20) + +/* Definitions to allow mutual recursion */ + +static int + add_list_to_class(pcre_uint8 *, pcre_uchar **, int, compile_data *, + const pcre_uint32 *, unsigned int); + +static BOOL + compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int, + pcre_uint32 *, pcre_int32 *, pcre_uint32 *, pcre_int32 *, branch_chain *, + compile_data *, int *); + + + +/************************************************* +* Code parameters and static tables * +*************************************************/ + +/* This value specifies the size of stack workspace that is used during the +first pre-compile phase that determines how much memory is required. The regex +is partly compiled into this space, but the compiled parts are discarded as +soon as they can be, so that hopefully there will never be an overrun. The code +does, however, check for an overrun. The largest amount I've seen used is 218, +so this number is very generous. + +The same workspace is used during the second, actual compile phase for +remembering forward references to groups so that they can be filled in at the +end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE +is 4 there is plenty of room 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 (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_SAFETY_MARGIN (100) + +/* Private flags added to firstchar and reqchar. */ + +#define REQ_CASELESS (1 << 0) /* Indicates caselessness */ +#define REQ_VARY (1 << 1) /* Reqchar followed non-literal item */ +/* Negative values for the firstchar and reqchar flags */ +#define REQ_UNSET (-2) +#define REQ_NONE (-1) + +/* 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 +on. Zero means further processing is needed (for things like \x), or the escape +is invalid. */ + +#ifndef EBCDIC + +/* This is the "normal" table for ASCII systems or for EBCDIC systems running +in UTF-8 mode. */ + +static const short int escapes[] = { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + CHAR_COLON, CHAR_SEMICOLON, + CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, + CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK, + CHAR_COMMERCIAL_AT, -ESC_A, + -ESC_B, -ESC_C, + -ESC_D, -ESC_E, + 0, -ESC_G, + -ESC_H, 0, + 0, -ESC_K, + 0, 0, + -ESC_N, 0, + -ESC_P, -ESC_Q, + -ESC_R, -ESC_S, + 0, 0, + -ESC_V, -ESC_W, + -ESC_X, 0, + -ESC_Z, CHAR_LEFT_SQUARE_BRACKET, + CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET, + CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE, + CHAR_GRAVE_ACCENT, 7, + -ESC_b, 0, + -ESC_d, ESC_e, + ESC_f, 0, + -ESC_h, 0, + 0, -ESC_k, + 0, 0, + ESC_n, 0, + -ESC_p, 0, + ESC_r, -ESC_s, + ESC_tee, 0, + -ESC_v, -ESC_w, + 0, 0, + -ESC_z +}; + +#else + +/* This is the "abnormal" table for EBCDIC systems without UTF-8 support. */ + +static const short int escapes[] = { +/* 48 */ 0, 0, 0, '.', '<', '(', '+', '|', +/* 50 */ '&', 0, 0, 0, 0, 0, 0, 0, +/* 58 */ 0, 0, '!', '$', '*', ')', ';', '~', +/* 60 */ '-', '/', 0, 0, 0, 0, 0, 0, +/* 68 */ 0, 0, '|', ',', '%', '_', '>', '?', +/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"', +/* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, +/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0, +/* 90 */ 0, 0, -ESC_k, 'l', 0, ESC_n, 0, -ESC_p, +/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0, +/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0, +/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0, +/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-', +/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G, +/* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0, +/* D0 */ '}', 0, -ESC_K, 0, 0,-ESC_N, 0, -ESC_P, +/* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0, +/* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X, +/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0, +/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0 +}; +#endif + + +/* Table of special "verbs" like (*PRUNE). This is a short table, so it is +searched linearly. Put all the names into a single string, in order to reduce +the number of relocations when a shared library is dynamically linked. The +string is built from string macros so that it works in UTF-8 mode on EBCDIC +platforms. */ + +typedef struct verbitem { + int len; /* Length of verb name */ + int op; /* Op when no arg, or -1 if arg mandatory */ + int op_arg; /* Op when arg present, or -1 if not allowed */ +} verbitem; + +static const char verbnames[] = + "\0" /* Empty name is a shorthand for MARK */ + STRING_MARK0 + STRING_ACCEPT0 + STRING_COMMIT0 + STRING_F0 + STRING_FAIL0 + STRING_PRUNE0 + STRING_SKIP0 + STRING_THEN; + +static const verbitem verbs[] = { + { 0, -1, OP_MARK }, + { 4, -1, OP_MARK }, + { 6, OP_ACCEPT, -1 }, + { 6, OP_COMMIT, -1 }, + { 1, OP_FAIL, -1 }, + { 4, OP_FAIL, -1 }, + { 5, OP_PRUNE, OP_PRUNE_ARG }, + { 4, OP_SKIP, OP_SKIP_ARG }, + { 4, OP_THEN, OP_THEN_ARG } +}; + +static const int verbcount = sizeof(verbs)/sizeof(verbitem); + + +/* Tables of names of POSIX character classes and their lengths. The names are +now all in a single string, to reduce the number of relocations when a shared +library is dynamically loaded. The list of lengths is terminated by a zero +length entry. The first three must be alpha, lower, upper, as this is assumed +for handling case independence. */ + +static const char posix_names[] = + STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0 + STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0 + STRING_graph0 STRING_print0 STRING_punct0 STRING_space0 + STRING_word0 STRING_xdigit; + +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 +base map, with an optional addition or removal of another map. Then, for some +classes, there is some additional tweaking: for [:blank:] the vertical space +characters are removed, and for [:alpha:] and [:alnum:] the underscore +character is removed. The triples in the table consist of the base map offset, +second map offset or -1 if no second map, and a non-negative value for map +addition or a negative value for map subtraction (if there are two maps). The +absolute value of the third field has these meanings: 0 => no tweaking, 1 => +remove vertical space characters, 2 => remove underscore. */ + +static const int posix_class_maps[] = { + cbit_word, cbit_digit, -2, /* alpha */ + cbit_lower, -1, 0, /* lower */ + cbit_upper, -1, 0, /* upper */ + cbit_word, -1, 2, /* alnum - word without underscore */ + cbit_print, cbit_cntrl, 0, /* ascii */ + cbit_space, -1, 1, /* blank - a GNU extension */ + cbit_cntrl, -1, 0, /* cntrl */ + cbit_digit, -1, 0, /* digit */ + cbit_graph, -1, 0, /* graph */ + cbit_print, -1, 0, /* print */ + cbit_punct, -1, 0, /* punct */ + cbit_space, -1, 0, /* space */ + cbit_word, -1, 0, /* word - a Perl extension */ + cbit_xdigit,-1, 0 /* xdigit */ +}; + +/* Table of substitutes for \d etc when PCRE_UCP is set. The POSIX class +substitutes must be in the order of the names, defined above, and there are +both positive and negative cases. NULL means no substitute. */ + +#ifdef SUPPORT_UCP +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 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 */ + 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(pcre_uchar *)) +#endif + +#define STRING(a) # a +#define XSTRING(s) STRING(s) + +/* The texts of compile-time error messages. These are "char *" because they +are passed to the outside world. Do not ever re-use any error number, because +they are documented. Always add a new error instead. Messages marked DEAD below +are no longer used. This used to be a table of strings, but in order to reduce +the number of relocations needed when a shared library is loaded dynamically, +it is now one long string. We cannot use a table of offsets, because the +lengths of inserts such as XSTRING(MAX_NAME_SIZE) are not known. Instead, we +simply count through to the one we want - this isn't a performance issue +because these strings are used only when there is a compilation error. + +Each substring ends with \0 to insert a null character. This includes the final +substring, so that the whole string ends with \0\0, which can be detected when +counting through. */ + +static const char error_texts[] = + "no error\0" + "\\ at end of pattern\0" + "\\c at end of pattern\0" + "unrecognized character follows \\\0" + "numbers out of order in {} quantifier\0" + /* 5 */ + "number too big in {} quantifier\0" + "missing terminating ] for character class\0" + "invalid escape sequence in character class\0" + "range out of order in character class\0" + "nothing to repeat\0" + /* 10 */ + "operand of unlimited repeat could match the empty string\0" /** DEAD **/ + "internal error: unexpected repeat\0" + "unrecognized character after (? or (?-\0" + "POSIX named classes are supported only within a class\0" + "missing )\0" + /* 15 */ + "reference to non-existent subpattern\0" + "erroffset passed as NULL\0" + "unknown option bit(s) set\0" + "missing ) after comment\0" + "parentheses nested too deeply\0" /** DEAD **/ + /* 20 */ + "regular expression is too large\0" + "failed to get memory\0" + "unmatched parentheses\0" + "internal error: code overflow\0" + "unrecognized character after (?<\0" + /* 25 */ + "lookbehind assertion is not fixed length\0" + "malformed number or name after (?(\0" + "conditional group contains more than two branches\0" + "assertion expected after (?(\0" + "(?R or (?[+-]digits must be followed by )\0" + /* 30 */ + "unknown POSIX class name\0" + "POSIX collating elements are not supported\0" + "this version of PCRE is compiled without UTF support\0" + "spare error\0" /** DEAD **/ + "character value in \\x{...} sequence is too large\0" + /* 35 */ + "invalid condition (?(0)\0" + "\\C not allowed in lookbehind assertion\0" + "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0" + "number after (?C is > 255\0" + "closing ) for (?C expected\0" + /* 40 */ + "recursive call could loop indefinitely\0" + "unrecognized character after (?P\0" + "syntax error in subpattern name (missing terminator)\0" + "two named subpatterns have the same name\0" + "invalid UTF-8 string\0" + /* 45 */ + "support for \\P, \\p, and \\X has not been compiled\0" + "malformed \\P or \\p sequence\0" + "unknown property name after \\P or \\p\0" + "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0" + "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0" + /* 50 */ + "repeated subpattern is too long\0" /** DEAD **/ + "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" /** 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" + "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0" + /* 60 */ + "(*VERB) not recognized\0" + "number is too big\0" + "subpattern name expected\0" + "digit expected after (?+\0" + "] is an invalid data character in JavaScript compatibility mode\0" + /* 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 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" + "invalid UTF-32 string\0" + ; + +/* Table to identify digits and hex digits. This is used when compiling +patterns. Note that the tables in chartables are dependent on the locale, and +may mark arbitrary characters as digits - but the PCRE compiling code expects +to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have +a private table here. It costs 256 bytes, but it is a lot faster than doing +character value tests (at least in some simple cases I timed), and in some +applications one wants PCRE to compile efficiently as well as match +efficiently. + +For convenience, we use the same bit definitions as in chartables: + + 0x04 decimal digit + 0x08 hexadecimal digit + +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 pcre_uint8 digitab[] = + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */ + 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */ + 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */ + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */ + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ + +#else + +/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */ + +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 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- 95 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */ + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */ + 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */ + 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ + +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 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ + 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */ + 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */ + 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- 95 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */ + 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */ + 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */ + 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */ + 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */ + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */ + 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ + 0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */ + 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */ + 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */ + 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ + 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ +#endif + + + +/************************************************* +* Find an error text * +*************************************************/ + +/* The error texts are now all in one long string, to save on relocations. As +some of the text is of unknown length, we can't use a table of offsets. +Instead, just count through the strings. This is not a performance issue +because it happens only when there has been a compilation error. + +Argument: the error number +Returns: pointer to the error string +*/ + +static const char * +find_error_text(int n) +{ +const char *s = error_texts; +for (; n > 0; n--) + { + while (*s++ != CHAR_NULL) {}; + if (*s == CHAR_NULL) return "Error text not found (please report)"; + } +return s; +} + + +/************************************************* +* Expand the workspace * +*************************************************/ + +/* This function is called during the second compiling phase, if the number of +forward references fills the existing workspace, which is originally a block on +the stack. A larger block is obtained from malloc() unless the ultimate limit +has been reached or the increase will be rather small. + +Argument: pointer to the compile data block +Returns: 0 if all went well, else an error number +*/ + +static int +expand_workspace(compile_data *cd) +{ +pcre_uchar *newspace; +int newsize = cd->workspace_size * 2; + +if (newsize > COMPILE_WORK_SIZE_MAX) newsize = COMPILE_WORK_SIZE_MAX; +if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX || + newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN) + return ERR72; + +newspace = (PUBL(malloc))(IN_UCHARS(newsize)); +if (newspace == NULL) return ERR21; +memcpy(newspace, cd->start_workspace, cd->workspace_size * sizeof(pcre_uchar)); +cd->hwm = (pcre_uchar *)newspace + (cd->hwm - cd->start_workspace); +if (cd->workspace_size > COMPILE_WORK_SIZE) + (PUBL(free))((void *)cd->start_workspace); +cd->start_workspace = newspace; +cd->workspace_size = newsize; +return 0; +} + + + +/************************************************* +* Check for counted repeat * +*************************************************/ + +/* This function is called when a '{' is encountered in a place where it might +start a quantifier. It looks ahead to see if it really is a quantifier or not. +It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd} +where the ddds are digits. + +Arguments: + p pointer to the first char after '{' + +Returns: TRUE or FALSE +*/ + +static BOOL +is_counted_repeat(const pcre_uchar *p) +{ +if (!IS_DIGIT(*p)) return FALSE; +p++; +while (IS_DIGIT(*p)) p++; +if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; + +if (*p++ != CHAR_COMMA) return FALSE; +if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; + +if (!IS_DIGIT(*p)) return FALSE; +p++; +while (IS_DIGIT(*p)) p++; + +return (*p == CHAR_RIGHT_CURLY_BRACKET); +} + + + +/************************************************* +* Handle escapes * +*************************************************/ + +/* This function is called when a \ has been encountered. It either returns a +positive value for a simple escape such as \n, or 0 for a data character +which will be placed in chptr. A backreference to group n is returned as +negative n. When UTF-8 is enabled, a positive value greater than 255 may +be returned in chptr. +On entry,ptr is pointing at the \. On exit, it is on the final character of the +escape sequence. + +Arguments: + ptrptr points to the pattern position pointer + chptr points to the data character + errorcodeptr points to the errorcode variable + bracount number of previous extracting brackets + options the options bits + isclass TRUE if inside a character class + +Returns: zero => a data character + positive => a special escape sequence + negative => a back reference + on error, errorcodeptr is set +*/ + +static int +check_escape(const pcre_uchar **ptrptr, pcre_uint32 *chptr, int *errorcodeptr, + int bracount, int options, BOOL isclass) +{ +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +BOOL utf = (options & PCRE_UTF8) != 0; +const pcre_uchar *ptr = *ptrptr + 1; +pcre_uint32 c; +int escape = 0; +int i; + +GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */ +ptr--; /* Set pointer back to the last byte */ + +/* If backslash is at the end of the pattern, it's an error. */ + +if (c == CHAR_NULL) *errorcodeptr = ERR1; + +/* Non-alphanumerics are literals. For digits or letters, do an initial lookup +in a table. A non-zero result is something that can be returned immediately. +Otherwise further processing may be required. */ + +#ifndef EBCDIC /* ASCII/UTF-8 coding */ +/* Not alphanumeric */ +else if (c < CHAR_0 || c > CHAR_z) {} +else if ((i = escapes[c - CHAR_0]) != 0) { if (i > 0) c = (pcre_uint32)i; else escape = -i; } + +#else /* EBCDIC coding */ +/* Not alphanumeric */ +else if (c < CHAR_a || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {} +else if ((i = escapes[c - 0x48]) != 0) { if (i > 0) c = (pcre_uint32)i; else escape = -i; } +#endif + +/* Escapes that need further processing, or are illegal. */ + +else + { + const pcre_uchar *oldptr; + BOOL braced, negated, overflow; + int s; + + switch (c) + { + /* A number of Perl escapes are not handled by PCRE. We give an explicit + error. */ + + 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 pcre_uint32 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 + } + +#if defined COMPILE_PCRE8 + if (c > (utf ? 0x10ffff : 0xff)) +#elif defined COMPILE_PCRE16 + if (c > (utf ? 0x10ffff : 0xffff)) +#elif defined COMPILE_PCRE32 + if (utf && c > 0x10ffff) +#endif + { + *errorcodeptr = ERR76; + } + else if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; + } + } + else + *errorcodeptr = ERR37; + break; + + case CHAR_U: + /* In JavaScript, \U is an uppercase U letter. */ + if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) *errorcodeptr = ERR37; + break; + + /* In a character class, \g is just a literal "g". Outside a character + class, \g must be followed by one of a number of specific things: + + (1) A number, either plain or braced. If positive, it is an absolute + backreference. If negative, it is a relative backreference. This is a Perl + 5.10 feature. + + (2) Perl 5.10 also supports \g{name} as a reference to a named group. This + is part of Perl's movement towards a unified syntax for back references. As + this is synonymous with \k{name}, we fudge it up by pretending it really + was \k. + + (3) For Oniguruma compatibility we also support \g followed by a name or a + number either in angle brackets or in single quotes. However, these are + (possibly recursive) subroutine calls, _not_ backreferences. Just return + the ESC_g code (cf \k). */ + + case CHAR_g: + if (isclass) break; + if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE) + { + escape = ESC_g; + break; + } + + /* Handle the Perl-compatible cases */ + + if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) + { + const pcre_uchar *p; + for (p = ptr+2; *p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET; p++) + if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break; + if (*p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET) + { + escape = ESC_k; + break; + } + braced = TRUE; + ptr++; + } + else braced = FALSE; + + if (ptr[1] == CHAR_MINUS) + { + negated = TRUE; + ptr++; + } + else negated = FALSE; + + /* The integer range is limited by the machine's int representation. */ + s = 0; + overflow = FALSE; + while (IS_DIGIT(ptr[1])) + { + if (s > INT_MAX / 10 - 1) /* Integer overflow */ + { + overflow = TRUE; + break; + } + s = s * 10 + (int)(*(++ptr) - CHAR_0); + } + if (overflow) /* Integer overflow */ + { + while (IS_DIGIT(ptr[1])) + ptr++; + *errorcodeptr = ERR61; + break; + } + + if (braced && *(++ptr) != CHAR_RIGHT_CURLY_BRACKET) + { + *errorcodeptr = ERR57; + break; + } + + if (s == 0) + { + *errorcodeptr = ERR58; + break; + } + + if (negated) + { + if (s > bracount) + { + *errorcodeptr = ERR15; + break; + } + s = bracount - (s - 1); + } + + escape = -s; + break; + + /* The handling of escape sequences consisting of a string of digits + starting with one that is not zero is not straightforward. By experiment, + the way Perl works seems to be as follows: + + Outside a character class, the digits are read as a decimal number. If the + number is less than 10, or if there are that many previous extracting + left brackets, then it is a back reference. Otherwise, up to three octal + digits are read to form an escaped byte. Thus \123 is likely to be octal + 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal + value is greater than 377, the least significant 8 bits are taken. Inside a + character class, \ followed by a digit is always an octal number. */ + + 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: + + if (!isclass) + { + oldptr = ptr; + /* The integer range is limited by the machine's int representation. */ + s = (int)(c -CHAR_0); + overflow = FALSE; + while (IS_DIGIT(ptr[1])) + { + if (s > INT_MAX / 10 - 1) /* Integer overflow */ + { + overflow = TRUE; + break; + } + s = s * 10 + (int)(*(++ptr) - CHAR_0); + } + if (overflow) /* Integer overflow */ + { + while (IS_DIGIT(ptr[1])) + ptr++; + *errorcodeptr = ERR61; + break; + } + if (s < 10 || s <= bracount) + { + escape = -s; + break; + } + ptr = oldptr; /* Put the pointer back and fall through */ + } + + /* Handle an octal number following \. If the first digit is 8 or 9, Perl + generates a binary zero byte and treats the digit as a following literal. + Thus we have to pull back the pointer by one. */ + + if ((c = *ptr) >= CHAR_8) + { + ptr--; + c = 0; + break; + } + + /* \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 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; +#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 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 pcre_uint32 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 pcre_uchar *pt = ptr + 2; + + c = 0; + overflow = FALSE; + while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) + { + register pcre_uint32 cc = *pt++; + if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ + +#ifdef COMPILE_PCRE32 + if (c >= 0x10000000l) { overflow = TRUE; break; } +#endif + +#ifndef EBCDIC /* ASCII/UTF-8 coding */ + if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ + c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); +#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 + +#if defined COMPILE_PCRE8 + if (c > (utf ? 0x10ffff : 0xff)) { overflow = TRUE; break; } +#elif defined COMPILE_PCRE16 + if (c > (utf ? 0x10ffff : 0xffff)) { overflow = TRUE; break; } +#elif defined COMPILE_PCRE32 + if (utf && c > 0x10ffff) { overflow = TRUE; break; } +#endif + } + + if (overflow) + { + while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++; + *errorcodeptr = ERR34; + } + + if (*pt == CHAR_RIGHT_CURLY_BRACKET) + { + if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; + ptr = pt; + break; + } + + /* If the sequence of hex digits does not end with '}', then we don't + recognize this construct; fall through to the normal \x handling. */ + } + + /* Read just a single-byte hex-defined char */ + + c = 0; + while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0) + { + pcre_uint32 cc; /* Some compilers don't like */ + cc = *(++ptr); /* ++ in initializers */ +#ifndef EBCDIC /* ASCII/UTF-8 coding */ + if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ + c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); +#else /* EBCDIC coding */ + if (cc <= CHAR_z) cc += 64; /* Convert to upper case */ + c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); +#endif + } + break; + + /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped. + An error is given if the byte following \c is not an ASCII character. This + coding is ASCII-specific, but then the whole concept of \cx is + ASCII-specific. (However, an EBCDIC equivalent has now been added.) */ + + case CHAR_c: + c = *(++ptr); + if (c == CHAR_NULL) + { + *errorcodeptr = ERR2; + break; + } +#ifndef EBCDIC /* ASCII/UTF-8 coding */ + if (c > 127) /* Excludes all non-ASCII in either mode */ + { + *errorcodeptr = ERR68; + break; + } + if (c >= CHAR_a && c <= CHAR_z) c -= 32; + c ^= 0x40; +#else /* EBCDIC coding */ + if (c >= CHAR_a && c <= CHAR_z) c += 64; + c ^= 0xC0; +#endif + break; + + /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any + other alphanumeric following \ is an error if PCRE_EXTRA was set; + otherwise, for Perl compatibility, it is a literal. This code looks a bit + odd, but there used to be some cases other than the default, and there may + be again in future, so I haven't "optimized" it. */ + + default: + if ((options & PCRE_EXTRA) != 0) switch(c) + { + default: + *errorcodeptr = ERR3; + break; + } + break; + } + } + +/* Perl supports \N{name} for character names, as well as plain \N for "not +newline". PCRE does not support \N{name}. However, it does support +quantification such as \N{2,3}. */ + +if (escape == 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. */ + +if ((options & PCRE_UCP) != 0 && escape >= ESC_D && escape <= ESC_w) + escape += (ESC_DU - ESC_D); + +/* Set the pointer to the final character before returning. */ + +*ptrptr = ptr; +*chptr = c; +return escape; +} + +#ifdef SUPPORT_UCP +/************************************************* +* Handle \P and \p * +*************************************************/ + +/* This function is called after \P or \p has been encountered, provided that +PCRE is compiled with support for Unicode properties. On entry, ptrptr is +pointing at the P or p. On exit, it is pointing at the final character of the +escape sequence. + +Argument: + ptrptr points to the pattern position pointer + negptr points to a boolean that is set TRUE for negation else FALSE + ptypeptr points to an unsigned int that is set to the type value + pdataptr points to an unsigned int that is set to the detailed property value + errorcodeptr points to the error code variable + +Returns: TRUE if the type value was found, or FALSE for an invalid type +*/ + +static BOOL +get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, unsigned int *ptypeptr, + unsigned int *pdataptr, int *errorcodeptr) +{ +pcre_uchar c; +int i, bot, top; +const pcre_uchar *ptr = *ptrptr; +pcre_uchar name[32]; + +c = *(++ptr); +if (c == CHAR_NULL) goto ERROR_RETURN; + +*negptr = FALSE; + +/* \P or \p can be followed by a name in {}, optionally preceded by ^ for +negation. */ + +if (c == CHAR_LEFT_CURLY_BRACKET) + { + if (ptr[1] == CHAR_CIRCUMFLEX_ACCENT) + { + *negptr = TRUE; + ptr++; + } + for (i = 0; i < (int)(sizeof(name) / sizeof(pcre_uchar)) - 1; i++) + { + c = *(++ptr); + if (c == CHAR_NULL) goto ERROR_RETURN; + if (c == CHAR_RIGHT_CURLY_BRACKET) break; + name[i] = c; + } + if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN; + name[i] = 0; + } + +/* Otherwise there is just one following character */ + +else + { + name[0] = c; + name[1] = 0; + } + +*ptrptr = ptr; + +/* Search for a recognized property name using binary chop */ + +bot = 0; +top = PRIV(utt_size); + +while (bot < top) + { + int r; + i = (bot + top) >> 1; + r = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset); + if (r == 0) + { + *ptypeptr = PRIV(utt)[i].type; + *pdataptr = PRIV(utt)[i].value; + return TRUE; + } + if (r > 0) bot = i + 1; else top = i; + } + +*errorcodeptr = ERR47; +*ptrptr = ptr; +return FALSE; + +ERROR_RETURN: +*errorcodeptr = ERR46; +*ptrptr = ptr; +return FALSE; +} +#endif + + + + +/************************************************* +* Read repeat counts * +*************************************************/ + +/* Read an item of the form {n,m} and return the values. This is called only +after is_counted_repeat() has confirmed that a repeat-count quantifier exists, +so the syntax is guaranteed to be correct, but we need to check the values. + +Arguments: + p pointer to first char after '{' + minp pointer to int for min + maxp pointer to int for max + returned as -1 if no max + errorcodeptr points to error code variable + +Returns: pointer to '}' on success; + current ptr on error, with errorcodeptr set non-zero +*/ + +static const pcre_uchar * +read_repeat_counts(const pcre_uchar *p, int *minp, int *maxp, int *errorcodeptr) +{ +int min = 0; +int max = -1; + +/* Read the minimum value and do a paranoid check: a negative value indicates +an integer overflow. */ + +while (IS_DIGIT(*p)) min = min * 10 + (int)(*p++ - CHAR_0); +if (min < 0 || min > 65535) + { + *errorcodeptr = ERR5; + return p; + } + +/* Read the maximum value if there is one, and again do a paranoid on its size. +Also, max must not be less than min. */ + +if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else + { + if (*(++p) != CHAR_RIGHT_CURLY_BRACKET) + { + max = 0; + while(IS_DIGIT(*p)) max = max * 10 + (int)(*p++ - CHAR_0); + if (max < 0 || max > 65535) + { + *errorcodeptr = ERR5; + return p; + } + if (max < min) + { + *errorcodeptr = ERR4; + return p; + } + } + } + +/* Fill in the required variables, and pass back the pointer to the terminating +'}'. */ + +*minp = min; +*maxp = max; +return p; +} + + + +/************************************************* +* Subroutine for finding forward reference * +*************************************************/ + +/* This recursive function is called only from find_parens() below. The +top-level call starts at the beginning of the pattern. All other calls must +start at a parenthesis. It scans along a pattern's text looking for capturing +subpatterns, and counting them. If it finds a named pattern that matches the +name it is given, it returns its number. Alternatively, if the name is NULL, it +returns when it reaches a given numbered subpattern. Recursion is used to keep +track of subpatterns that reset the capturing group numbers - the (?| feature. + +This function was originally called only from the second pass, in which we know +that if (?< or (?' or (?P< is encountered, the name will be correctly +terminated because that is checked in the first pass. There is now one call to +this function in the first pass, to check for a recursive back reference by +name (so that we can make the whole group atomic). In this case, we need check +only up to the current position in the pattern, and that is still OK because +and previous occurrences will have been checked. To make this work, the test +for "end of pattern" is a check against cd->end_pattern in the main loop, +instead of looking for a binary zero. This means that the special first-pass +call can adjust cd->end_pattern temporarily. (Checks for binary zero while +processing items within the loop are OK, because afterwards the main loop will +terminate.) + +Arguments: + ptrptr address of the current character pointer (updated) + cd compile background data + name name to seek, or NULL if seeking a numbered subpattern + lorn name length, or subpattern number if name is NULL + xmode TRUE if we are in /x mode + utf TRUE if we are in UTF-8 / UTF-16 / UTF-32 mode + count pointer to the current capturing subpattern number (updated) + +Returns: the number of the named subpattern, or -1 if not found +*/ + +static int +find_parens_sub(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn, + BOOL xmode, BOOL utf, int *count) +{ +pcre_uchar *ptr = *ptrptr; +int start_count = *count; +int hwm_count = start_count; +BOOL dup_parens = FALSE; + +/* If the first character is a parenthesis, check on the type of group we are +dealing with. The very first call may not start with a parenthesis. */ + +if (ptr[0] == CHAR_LEFT_PARENTHESIS) + { + /* Handle specials such as (*SKIP) or (*UTF8) etc. */ + + if (ptr[1] == CHAR_ASTERISK) ptr += 2; + + /* Handle a normal, unnamed capturing parenthesis. */ + + else if (ptr[1] != CHAR_QUESTION_MARK) + { + *count += 1; + if (name == NULL && *count == lorn) return *count; + ptr++; + } + + /* All cases now have (? at the start. Remember when we are in a group + where the parenthesis numbers are duplicated. */ + + else if (ptr[2] == CHAR_VERTICAL_LINE) + { + ptr += 3; + dup_parens = TRUE; + } + + /* Handle comments; all characters are allowed until a ket is reached. */ + + else if (ptr[2] == CHAR_NUMBER_SIGN) + { + for (ptr += 3; *ptr != CHAR_NULL; ptr++) + if (*ptr == CHAR_RIGHT_PARENTHESIS) break; + goto FAIL_EXIT; + } + + /* Handle a condition. If it is an assertion, just carry on so that it + is processed as normal. If not, skip to the closing parenthesis of the + condition (there can't be any nested parens). */ + + else if (ptr[2] == CHAR_LEFT_PARENTHESIS) + { + ptr += 2; + if (ptr[1] != CHAR_QUESTION_MARK) + { + while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; + if (*ptr != CHAR_NULL) ptr++; + } + } + + /* Start with (? but not a condition. */ + + else + { + ptr += 2; + if (*ptr == CHAR_P) ptr++; /* Allow optional P */ + + /* We have to disambiguate (? for named groups */ + + if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK && + ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE) + { + pcre_uchar term; + const pcre_uchar *thisname; + *count += 1; + if (name == NULL && *count == lorn) return *count; + term = *ptr++; + if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN; + thisname = ptr; + while (*ptr != term) ptr++; + if (name != NULL && lorn == (int)(ptr - thisname) && + STRNCMP_UC_UC(name, thisname, (unsigned int)lorn) == 0) + return *count; + term++; + } + } + } + +/* Past any initial parenthesis handling, scan for parentheses or vertical +bars. Stop if we get to cd->end_pattern. Note that this is important for the +first-pass call when this value is temporarily adjusted to stop at the current +position. So DO NOT change this to a test for binary zero. */ + +for (; ptr < cd->end_pattern; ptr++) + { + /* Skip over backslashed characters and also entire \Q...\E */ + + if (*ptr == CHAR_BACKSLASH) + { + if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT; + if (*ptr == CHAR_Q) for (;;) + { + while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {}; + if (*ptr == CHAR_NULL) goto FAIL_EXIT; + if (*(++ptr) == CHAR_E) break; + } + continue; + } + + /* Skip over character classes; this logic must be similar to the way they + are handled for real. If the first character is '^', skip it. Also, if the + first few characters (either before or after ^) are \Q\E or \E we skip them + too. This makes for compatibility with Perl. Note the use of STR macros to + encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */ + + if (*ptr == CHAR_LEFT_SQUARE_BRACKET) + { + BOOL negate_class = FALSE; + for (;;) + { + if (ptr[1] == CHAR_BACKSLASH) + { + if (ptr[2] == CHAR_E) + ptr+= 2; + else if (STRNCMP_UC_C8(ptr + 2, + STR_Q STR_BACKSLASH STR_E, 3) == 0) + ptr += 4; + else + break; + } + else if (!negate_class && ptr[1] == CHAR_CIRCUMFLEX_ACCENT) + { + negate_class = TRUE; + ptr++; + } + else break; + } + + /* If the next character is ']', it is a data character that must be + skipped, except in JavaScript compatibility mode. */ + + if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET && + (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0) + ptr++; + + while (*(++ptr) != CHAR_RIGHT_SQUARE_BRACKET) + { + if (*ptr == CHAR_NULL) return -1; + if (*ptr == CHAR_BACKSLASH) + { + if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT; + if (*ptr == CHAR_Q) for (;;) + { + while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {}; + if (*ptr == CHAR_NULL) goto FAIL_EXIT; + if (*(++ptr) == CHAR_E) break; + } + continue; + } + } + continue; + } + + /* Skip comments in /x mode */ + + if (xmode && *ptr == CHAR_NUMBER_SIGN) + { + ptr++; + while (*ptr != CHAR_NULL) + { + if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } + ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); +#endif + } + if (*ptr == CHAR_NULL) goto FAIL_EXIT; + continue; + } + + /* Check for the special metacharacters */ + + if (*ptr == CHAR_LEFT_PARENTHESIS) + { + int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count); + if (rc > 0) return rc; + if (*ptr == CHAR_NULL) goto FAIL_EXIT; + } + + else if (*ptr == CHAR_RIGHT_PARENTHESIS) + { + if (dup_parens && *count < hwm_count) *count = hwm_count; + goto FAIL_EXIT; + } + + else if (*ptr == CHAR_VERTICAL_LINE && dup_parens) + { + if (*count > hwm_count) hwm_count = *count; + *count = start_count; + } + } + +FAIL_EXIT: +*ptrptr = ptr; +return -1; +} + + + + +/************************************************* +* Find forward referenced subpattern * +*************************************************/ + +/* This function scans along a pattern's text looking for capturing +subpatterns, and counting them. If it finds a named pattern that matches the +name it is given, it returns its number. Alternatively, if the name is NULL, it +returns when it reaches a given numbered subpattern. This is used for forward +references to subpatterns. We used to be able to start this scan from the +current compiling point, using the current count value from cd->bracount, and +do it all in a single loop, but the addition of the possibility of duplicate +subpattern numbers means that we have to scan from the very start, in order to +take account of such duplicates, and to use a recursive function to keep track +of the different types of group. + +Arguments: + cd compile background data + name name to seek, or NULL if seeking a numbered subpattern + lorn name length, or subpattern number if name is NULL + xmode TRUE if we are in /x mode + utf TRUE if we are in UTF-8 / UTF-16 / UTF-32 mode + +Returns: the number of the found subpattern, or -1 if not found +*/ + +static int +find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode, + BOOL utf) +{ +pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern; +int count = 0; +int rc; + +/* If the pattern does not start with an opening parenthesis, the first call +to find_parens_sub() will scan right to the end (if necessary). However, if it +does start with a parenthesis, find_parens_sub() will return when it hits the +matching closing parens. That is why we have to have a loop. */ + +for (;;) + { + rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count); + if (rc > 0 || *ptr++ == CHAR_NULL) break; + } + +return rc; +} + + + + +/************************************************* +* Find first significant op code * +*************************************************/ + +/* 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, 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 + skipassert TRUE if certain assertions are to be skipped + +Returns: pointer to the first significant opcode +*/ + +static const pcre_uchar* +first_significant_code(const pcre_uchar *code, BOOL skipassert) +{ +for (;;) + { + switch ((int)*code) + { + 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 += PRIV(OP_lengths)[*code]; + break; + + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + if (!skipassert) return code; + /* Fall through */ + + case OP_CALLOUT: + case OP_CREF: + case OP_NCREF: + case OP_RREF: + case OP_NRREF: + case OP_DEF: + code += PRIV(OP_lengths)[*code]; + break; + + default: + return code; + } + } +/* Control never reaches here */ +} + + + + +/************************************************* +* Find the fixed length of a branch * +*************************************************/ + +/* Scan a branch and compute the fixed length of subject that will match it, +if the length is fixed. This is needed for dealing with backward assertions. +In UTF8 mode, the result is in characters rather than bytes. The branch is +temporarily terminated with OP_END when this function is called. + +This function is called when a backward assertion is encountered, so that if it +fails, the error message can point to the correct place in the pattern. +However, we cannot do this when the assertion contains subroutine calls, +because they can be forward references. We solve this by remembering this case +and doing the check at the end; a flag specifies which mode we are running in. + +Arguments: + code points to the start of the pattern (the bracket) + utf TRUE in UTF-8 / UTF-16 / UTF-32 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 (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(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd) +{ +int length = -1; + +register int branchlength = 0; +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. */ + +for (;;) + { + int d; + pcre_uchar *ce, *cs; + register pcre_uchar 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)? 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. 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_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; + cc += 1 + LINK_SIZE; + branchlength = 0; + break; + + /* A true recursion implies not fixed length, but a subroutine call may + be OK. If the subroutine is a forward reference, we can't deal with + it until the end of the pattern, so return -3. */ + + case OP_RECURSE: + if (!atend) return -3; + 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; + break; + + /* Skip over assertive subpatterns */ + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + do cc += GET(cc, 1); while (*cc == OP_ALT); + cc += PRIV(OP_lengths)[*cc]; + break; + + /* Skip over things that don't match chars */ + + 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_DEF: + case OP_DOLL: + case OP_DOLLM: + case OP_EOD: + case OP_EODN: + case OP_FAIL: + case OP_NCREF: + case OP_NRREF: + case OP_NOT_WORD_BOUNDARY: + case OP_PRUNE: + case OP_REVERSE: + case OP_RREF: + case OP_SET_SOM: + case OP_SKIP: + case OP_SOD: + case OP_SOM: + case OP_THEN: + case OP_WORD_BOUNDARY: + cc += PRIV(OP_lengths)[*cc]; + break; + + /* Handle literal characters */ + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + branchlength++; + cc += 2; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + /* Handle exact repetitions. The count is already in characters, but we + need to skip over a multibyte character in UTF8 mode. */ + + case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: + branchlength += (int)GET2(cc,1); + 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[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) + cc += 2; + cc += 1 + IMM2_SIZE + 1; + break; + + /* Handle single-char matchers */ + + case OP_PROP: + case OP_NOTPROP: + 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: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + branchlength++; + cc++; + break; + + /* 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 */ + + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + case OP_XCLASS: + /* The original code caused an unsigned overflow in 64 bit systems, + so now we use a conditional statement. */ + if (op == OP_XCLASS) + cc += GET(cc, 1); + else + cc += PRIV(OP_lengths)[OP_CLASS]; +#else + cc += PRIV(OP_lengths)[OP_CLASS]; +#endif + + switch (*cc) + { + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + return -1; + + case OP_CRRANGE: + case OP_CRMINRANGE: + if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1; + branchlength += (int)GET2(cc,1); + cc += 1 + 2 * IMM2_SIZE; + break; + + default: + branchlength++; + } + break; + + /* Anything else is variable length */ + + 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 */ +} + + + + +/************************************************* +* Scan compiled regex for specific bracket * +*************************************************/ + +/* This little function scans through a compiled pattern until it finds a +capturing bracket with the given number, or, if the number is negative, an +instance of OP_REVERSE for a lookbehind. The function is global in the C sense +so that it can be called from pcre_study() when finding the minimum matching +length. + +Arguments: + code points to start of expression + utf TRUE in UTF-8 / UTF-16 / UTF-32 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 pcre_uchar * +PRIV(find_bracket)(const pcre_uchar *code, BOOL utf, int number) +{ +for (;;) + { + register pcre_uchar c = *code; + + if (c == OP_END) return NULL; + + /* XCLASS is used for classes that cannot be represented just by a bit + map. This includes negated single high-valued characters. The length in + the table is zero; the actual length is stored in the compiled code. */ + + if (c == OP_XCLASS) code += GET(code, 1); + + /* Handle recursion */ + + else if (c == OP_REVERSE) + { + if (number < 0) return (pcre_uchar *)code; + code += PRIV(OP_lengths)[c]; + } + + /* Handle capturing bracket */ + + else if (c == OP_CBRA || c == OP_SCBRA || + c == OP_CBRAPOS || c == OP_SCBRAPOS) + { + int n = (int)GET2(code, 1+LINK_SIZE); + 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 + repeated character types, we have to test for \p and \P, which have an extra + two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we + must add in its length. */ + + else + { + switch(c) + { + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; + break; + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSUPTO: + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + code += 2; + break; + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + code += code[1]; + break; + + case OP_THEN_ARG: + code += code[1]; + break; + } + + /* Add in the fixed length from the table */ + + code += PRIV(OP_lengths)[c]; + + /* In UTF-8 mode, opcodes that are followed by a character may be followed by + a multi-byte character. The length in the table is a minimum, so we have to + arrange to skip the extra bytes. */ + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (utf) switch(c) + { + case OP_CHAR: + case OP_CHARI: + case OP_EXACT: + case OP_EXACTI: + case OP_UPTO: + case OP_UPTOI: + case OP_MINUPTO: + case OP_MINUPTOI: + case OP_POSUPTO: + case OP_POSUPTOI: + case OP_STAR: + case OP_STARI: + case OP_MINSTAR: + case OP_MINSTARI: + case OP_POSSTAR: + case OP_POSSTARI: + case OP_PLUS: + case OP_PLUSI: + case OP_MINPLUS: + case OP_MINPLUSI: + case OP_POSPLUS: + case OP_POSPLUSI: + case OP_QUERY: + case OP_QUERYI: + case OP_MINQUERY: + case OP_MINQUERYI: + case OP_POSQUERY: + case OP_POSQUERYI: + if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); + break; + } +#else + (void)(utf); /* Keep compiler happy by referencing function argument */ +#endif + } + } +} + + + +/************************************************* +* Scan compiled regex for recursion reference * +*************************************************/ + +/* This little function scans through a compiled pattern until it finds an +instance of OP_RECURSE. + +Arguments: + code points to start of expression + utf TRUE in UTF-8 / UTF-16 / UTF-32 mode + +Returns: pointer to the opcode for OP_RECURSE, or NULL if not found +*/ + +static const pcre_uchar * +find_recurse(const pcre_uchar *code, BOOL utf) +{ +for (;;) + { + register pcre_uchar c = *code; + if (c == OP_END) return NULL; + if (c == OP_RECURSE) return code; + + /* XCLASS is used for classes that cannot be represented just by a bit + map. This includes negated single high-valued characters. The length in + the table is zero; the actual length is stored in the compiled code. */ + + if (c == OP_XCLASS) code += GET(code, 1); + + /* Otherwise, we can get the item's length from the table, except that for + repeated character types, we have to test for \p and \P, which have an extra + two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we + must add in its length. */ + + else + { + switch(c) + { + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; + break; + + case OP_TYPEPOSUPTO: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + code += 2; + break; + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + code += code[1]; + break; + + case OP_THEN_ARG: + code += code[1]; + break; + } + + /* Add in the fixed length from the table */ + + code += PRIV(OP_lengths)[c]; + + /* In UTF-8 mode, opcodes that are followed by a character may be followed + by a multi-byte character. The length in the table is a minimum, so we have + to arrange to skip the extra bytes. */ + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (utf) switch(c) + { + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_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: + case OP_POSQUERYI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); + break; + } +#else + (void)(utf); /* Keep compiler happy by referencing function argument */ +#endif + } + } +} + + + +/************************************************* +* Scan compiled branch for non-emptiness * +*************************************************/ + +/* This function scans through a branch of a compiled pattern to see whether it +can match the empty string or not. It is called from could_be_empty() +below and from compile_branch() when checking for an unlimited repeat of a +group that can match nothing. Note that first_significant_code() skips over +backward and negative forward assertions when its final argument is TRUE. If we +hit an unclosed bracket, we return "empty" - this means we've struck an inner +bracket whose current branch will already have been scanned. + +Arguments: + code points to start of search + endcode points to where to stop + utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode + cd contains pointers to tables etc. + +Returns: TRUE if what is matched could be empty +*/ + +static BOOL +could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode, + BOOL utf, compile_data *cd) +{ +register pcre_uchar c; +for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); + code < endcode; + code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE)) + { + const pcre_uchar *ccode; + + c = *code; + + /* Skip over forward assertions; the other assertions are skipped by + first_significant_code() with a TRUE final argument. */ + + if (c == OP_ASSERT) + { + 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 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) + { + const pcre_uchar *scode; + BOOL empty_branch; + + /* Test for forward reference */ + + for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE) + if ((int)GET(scode, 0) == (int)(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, utf, cd)) + { + empty_branch = TRUE; + break; + } + 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_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 */ + + /* If a conditional group has only one branch, there is a second, implied, + empty branch, so just skip over the conditional, because it could be empty. + Otherwise, scan the individual branches of the group. */ + + if (c == OP_COND && code[GET(code, 1)] != OP_ALT) + code += GET(code, 1); + else + { + empty_branch = FALSE; + do + { + if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd)) + empty_branch = TRUE; + code += GET(code, 1); + } + while (*code == OP_ALT); + if (!empty_branch) return FALSE; /* All branches are non-empty */ + } + + c = *code; + continue; + } + + /* Handle the other opcodes */ + + switch (c) + { + /* 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 PRIV(OP_lengths)[] is zero; the + actual length is stored in the compiled code, so we must update "code" + here. */ + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + ccode = code += GET(code, 1); + goto CHECK_CLASS_REPEAT; +#endif + + case OP_CLASS: + case OP_NCLASS: + ccode = code + PRIV(OP_lengths)[OP_CLASS]; + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + CHECK_CLASS_REPEAT: +#endif + + switch (*ccode) + { + case OP_CRSTAR: /* These could be empty; continue */ + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + break; + + default: /* Non-repeat => class must match */ + case OP_CRPLUS: /* These repeats aren't empty */ + case OP_CRMINPLUS: + return FALSE; + + case OP_CRRANGE: + case OP_CRMINRANGE: + if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */ + break; + } + break; + + /* Opcodes that must match a character */ + + case OP_PROP: + case OP_NOTPROP: + case OP_EXTUNI: + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_ANYBYTE: + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_PLUS: + case OP_MINPLUS: + case OP_POSPLUS: + case OP_EXACT: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTPOSPLUS: + case OP_NOTEXACT: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSPLUS: + case OP_TYPEEXACT: + return FALSE; + + /* These are going to continue, as they may be empty, but we have to + fudge the length for the \p and \P cases. */ + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPOSSTAR: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSQUERY: + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; + break; + + /* Same for these */ + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEPOSUPTO: + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + code += 2; + break; + + /* End of branch */ + + 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 */ + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + case OP_STAR: + case OP_STARI: + case OP_MINSTAR: + case OP_MINSTARI: + case OP_POSSTAR: + case OP_POSSTARI: + case OP_QUERY: + case OP_QUERYI: + case OP_MINQUERY: + case OP_MINQUERYI: + case OP_POSQUERY: + case OP_POSQUERYI: + if (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: + case OP_POSUPTOI: + if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]); + break; +#endif + + /* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument + string. */ + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + code += code[1]; + break; + + case OP_THEN_ARG: + code += code[1]; + break; + + /* None of the remaining opcodes are required to match a character. */ + + default: + break; + } + } + +return TRUE; +} + + + +/************************************************* +* Scan compiled regex for non-emptiness * +*************************************************/ + +/* This function is called to check for left recursive calls. We want to check +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 + utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode + cd pointers to tables etc + +Returns: TRUE if what is matched could be empty +*/ + +static BOOL +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, utf, cd)) + return FALSE; + bcptr = bcptr->outer; + } +return TRUE; +} + + + +/************************************************* +* Check for POSIX class syntax * +*************************************************/ + +/* This function is called when the sequence "[:" or "[." or "[=" is +encountered in a character class. It checks whether this is followed by a +sequence of characters terminated by a matching ":]" or ".]" or "=]". If we +reach an unescaped ']' without the special preceding character, return FALSE. + +Originally, this function only recognized a sequence of letters between the +terminators, but it seems that Perl recognizes any sequence of characters, +though of course unknown POSIX names are subsequently rejected. Perl gives an +"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE +didn't consider this to be a POSIX class. Likewise for [:1234:]. + +The problem in trying to be exactly like Perl is in the handling of escapes. We +have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX +class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code +below handles the special case of \], but does not try to do any other escape +processing. This makes it different from Perl for cases such as [:l\ower:] +where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize +"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does, +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 + +Returns: TRUE or FALSE +*/ + +static BOOL +check_posix_syntax(const pcre_uchar *ptr, const pcre_uchar **endptr) +{ +pcre_uchar terminator; /* Don't combine these lines; the Solaris cc */ +terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ +for (++ptr; *ptr != CHAR_NULL; ptr++) + { + if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) + ptr++; + else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE; + else + { + 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; +} + + + + +/************************************************* +* Check POSIX class name * +*************************************************/ + +/* This function is called to check the name given in a POSIX-style class entry +such as [:alnum:]. + +Arguments: + ptr points to the first letter + len the length of the name + +Returns: a value representing the name, or -1 if unknown +*/ + +static int +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_UC_C8(ptr, pn, (unsigned int)len) == 0) return yield; + pn += posix_name_lengths[yield] + 1; + yield++; + } +return -1; +} + + +/************************************************* +* Adjust OP_RECURSE items in repeated group * +*************************************************/ + +/* OP_RECURSE items contain an offset from the start of the regex to the group +that is referenced. This means that groups can be replicated for fixed +repetition simply by copying (because the recursion is allowed to refer to +earlier groups that are outside the current group). However, when a group is +optional (i.e. the minimum quantifier is zero), OP_BRAZERO or OP_SKIPZERO is +inserted before it, after it has been compiled. This means that any OP_RECURSE +items within it that refer to the group itself or any contained groups have to +have their offsets adjusted. That one of the jobs of this function. Before it +is called, the partially compiled regex must be temporarily terminated with +OP_END. + +This function has been extended with the possibility of forward references for +recursions and subroutine calls. It must also check the list of such references +for the group we are dealing with. If it finds that one of the recursions in +the current group is on this list, it adjusts the offset in the list, not the +value in the reference (which is a group number). + +Arguments: + group points to the start of the group + adjust the amount by which the group is to be moved + utf TRUE in UTF-8 / UTF-16 / UTF-32 mode + cd contains pointers to tables etc. + save_hwm the hwm forward reference pointer at the start of the group + +Returns: nothing +*/ + +static void +adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd, + pcre_uchar *save_hwm) +{ +pcre_uchar *ptr = group; + +while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL) + { + int offset; + pcre_uchar *hc; + + /* See if this recursion is on the forward reference list. If so, adjust the + reference. */ + + for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE) + { + offset = (int)GET(hc, 0); + if (cd->start_code + offset == ptr + 1) + { + PUT(hc, 0, offset + adjust); + break; + } + } + + /* Otherwise, adjust the recursion offset if it's after the start of this + group. */ + + if (hc >= cd->hwm) + { + offset = (int)GET(ptr, 1); + if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust); + } + + ptr += 1 + LINK_SIZE; + } +} + + + +/************************************************* +* Insert an automatic callout point * +*************************************************/ + +/* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert +callout points before each pattern item. + +Arguments: + code current code pointer + ptr current pattern pointer + cd pointers to tables etc + +Returns: new code pointer +*/ + +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; +} + + + +/************************************************* +* Complete a callout item * +*************************************************/ + +/* A callout item contains the length of the next item in the pattern, which +we can't fill in till after we have reached the relevant point. This is used +for both automatic and manual callouts. + +Arguments: + previous_callout points to previous callout item + ptr current pattern pointer + cd pointers to tables etc + +Returns: nothing +*/ + +static void +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); +} + + + +#ifdef SUPPORT_UCP +/************************************************* +* Get othercase range * +*************************************************/ + +/* This function is passed the start and end of a class range, in UTF-8 mode +with UCP support. It searches up the characters, looking for ranges of +characters in the "other" case. Each call returns the next one, updating the +start address. A character with multiple other cases is returned on its own +with a special return value. + +Arguments: + cptr points to starting character value; updated + d end value + ocptr where to put start of othercase range + odptr where to put end of othercase range + +Yield: -1 when no more + 0 when a range is returned + >0 the CASESET offset for char with multiple other cases + in this case, ocptr contains the original +*/ + +static int +get_othercase_range(pcre_uint32 *cptr, pcre_uint32 d, pcre_uint32 *ocptr, + pcre_uint32 *odptr) +{ +pcre_uint32 c, othercase, next; +unsigned int co; + +/* Find the first character that has an other case. If it has multiple other +cases, return its case offset value. */ + +for (c = *cptr; c <= d; c++) + { + if ((co = UCD_CASESET(c)) != 0) + { + *ocptr = c++; /* Character that has the set */ + *cptr = c; /* Rest of input range */ + return (int)co; + } + if ((othercase = UCD_OTHERCASE(c)) != c) break; + } + +if (c > d) return -1; /* Reached end of range */ + +*ocptr = othercase; +next = othercase + 1; + +for (++c; c <= d; c++) + { + if (UCD_OTHERCASE(c) != next) break; + next++; + } + +*odptr = next - 1; /* End of othercase range */ +*cptr = c; /* Rest of input range */ +return 0; +} + + + +/************************************************* +* Check a character and a property * +*************************************************/ + +/* This function is called by check_auto_possessive() when a property item +is adjacent to a fixed character. + +Arguments: + c the character + ptype the property type + pdata the data for the type + negated TRUE if it's a negated property (\P or \p{^) + +Returns: TRUE if auto-possessifying is OK +*/ + +static BOOL +check_char_prop(pcre_uint32 c, unsigned int ptype, unsigned int pdata, BOOL negated) +{ +#ifdef SUPPORT_UCP +const pcre_uint32 *p; +#endif + +const ucd_record *prop = GET_UCD(c); + +switch(ptype) + { + case PT_LAMP: + return (prop->chartype == ucp_Lu || + prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt) == negated; + + case PT_GC: + return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated; + + case PT_PC: + return (pdata == prop->chartype) == negated; + + case PT_SC: + return (pdata == prop->script) == negated; + + /* These are specials */ + + case PT_ALNUM: + return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated; + + case PT_SPACE: /* Perl space */ + return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z || + c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) + == negated; + + case PT_PXSPACE: /* POSIX space */ + return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z || + c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || + c == CHAR_FF || c == CHAR_CR) + == negated; + + case PT_WORD: + return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE) == negated; + +#ifdef SUPPORT_UCP + case PT_CLIST: + p = PRIV(ucd_caseless_sets) + prop->caseset; + for (;;) + { + if (c < *p) return !negated; + if (c == *p++) return negated; + } + break; /* Control never reaches here */ +#endif + } + +return FALSE; +} +#endif /* SUPPORT_UCP */ + + + +/************************************************* +* Check if auto-possessifying is possible * +*************************************************/ + +/* This function is called for unlimited repeats of certain items, to see +whether the next thing could possibly match the repeated item. If not, it makes +sense to automatically possessify the repeated item. + +Arguments: + previous pointer to the repeated opcode + utf TRUE in UTF-8 / UTF-16 / UTF-32 mode + ptr next character in pattern + options options bits + cd contains pointers to tables etc. + +Returns: TRUE if possessifying is wanted +*/ + +static BOOL +check_auto_possessive(const pcre_uchar *previous, BOOL utf, + const pcre_uchar *ptr, int options, compile_data *cd) +{ +pcre_uint32 c = NOTACHAR; +pcre_uint32 next; +int escape; +pcre_uchar op_code = *previous++; + +/* Skip whitespace and comments in extended mode */ + +if ((options & PCRE_EXTENDED) != 0) + { + for (;;) + { + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++; + if (*ptr == CHAR_NUMBER_SIGN) + { + ptr++; + while (*ptr != CHAR_NULL) + { + if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } + ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); +#endif + } + } + else break; + } + } + +/* If the next item is one that we can handle, get its value. A non-negative +value is a character, a negative value is an escape value. */ + +if (*ptr == CHAR_BACKSLASH) + { + int temperrorcode = 0; + escape = check_escape(&ptr, &next, &temperrorcode, cd->bracount, options, FALSE); + if (temperrorcode != 0) return FALSE; + ptr++; /* Point after the escape sequence */ + } +else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0) + { + escape = 0; +#ifdef SUPPORT_UTF + if (utf) { GETCHARINC(next, ptr); } else +#endif + next = *ptr++; + } +else return FALSE; + +/* Skip whitespace and comments in extended mode */ + +if ((options & PCRE_EXTENDED) != 0) + { + for (;;) + { + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++; + if (*ptr == CHAR_NUMBER_SIGN) + { + ptr++; + while (*ptr != CHAR_NULL) + { + if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } + ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); +#endif + } + } + else break; + } + } + +/* If the next thing is itself optional, we have to give up. */ + +if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || + STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) + return FALSE; + +/* If the previous item is a character, get its value. */ + +if (op_code == OP_CHAR || op_code == OP_CHARI || + op_code == OP_NOT || op_code == OP_NOTI) + { +#ifdef SUPPORT_UTF + GETCHARTEST(c, previous); +#else + c = *previous; +#endif + } + +/* Now compare the next item with the previous opcode. First, handle cases when +the next item is a character. */ + +if (escape == 0) + { + /* For a caseless UTF match, the next character may have more than one other + case, which maps to the special PT_CLIST property. Check this first. */ + +#ifdef SUPPORT_UCP + if (utf && c != NOTACHAR && (options & PCRE_CASELESS) != 0) + { + unsigned int ocs = UCD_CASESET(next); + if (ocs > 0) return check_char_prop(c, PT_CLIST, ocs, op_code >= OP_NOT); + } +#endif + + switch(op_code) + { + case OP_CHAR: + return c != next; + + /* For CHARI (caseless character) we must check the other case. If we have + Unicode property support, we can use it to test the other case of + high-valued characters. We know that next can have only one other case, + because multi-other-case characters are dealt with above. */ + + case OP_CHARI: + if (c == next) return FALSE; +#ifdef SUPPORT_UTF + if (utf) + { + pcre_uint32 othercase; + if (next < 128) othercase = cd->fcc[next]; else +#ifdef SUPPORT_UCP + othercase = UCD_OTHERCASE(next); +#else + othercase = NOTACHAR; +#endif + return c != othercase; + } + else +#endif /* SUPPORT_UTF */ + return (c != TABLE_GET(next, cd->fcc, next)); /* Not UTF */ + + case OP_NOT: + return c == next; + + case OP_NOTI: + if (c == next) return TRUE; +#ifdef SUPPORT_UTF + if (utf) + { + pcre_uint32 othercase; + if (next < 128) othercase = cd->fcc[next]; else +#ifdef SUPPORT_UCP + othercase = UCD_OTHERCASE(next); +#else + othercase = NOTACHAR; +#endif + return c == othercase; + } + else +#endif /* SUPPORT_UTF */ + return (c == TABLE_GET(next, cd->fcc, next)); /* Not UTF */ + + /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set. + When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ + + case OP_DIGIT: + return next > 255 || (cd->ctypes[next] & ctype_digit) == 0; + + case OP_NOT_DIGIT: + return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0; + + case OP_WHITESPACE: + return next > 255 || (cd->ctypes[next] & ctype_space) == 0; + + case OP_NOT_WHITESPACE: + return next <= 255 && (cd->ctypes[next] & ctype_space) != 0; + + case OP_WORDCHAR: + return next > 255 || (cd->ctypes[next] & ctype_word) == 0; + + case OP_NOT_WORDCHAR: + return next <= 255 && (cd->ctypes[next] & ctype_word) != 0; + + case OP_HSPACE: + case OP_NOT_HSPACE: + switch(next) + { + HSPACE_CASES: + return op_code == OP_NOT_HSPACE; + + default: + return op_code != OP_NOT_HSPACE; + } + + case OP_ANYNL: + case OP_VSPACE: + case OP_NOT_VSPACE: + switch(next) + { + VSPACE_CASES: + return op_code == OP_NOT_VSPACE; + + default: + return op_code != OP_NOT_VSPACE; + } + +#ifdef SUPPORT_UCP + case OP_PROP: + return check_char_prop(next, previous[0], previous[1], FALSE); + + case OP_NOTPROP: + return check_char_prop(next, previous[0], previous[1], TRUE); +#endif + + default: + return FALSE; + } + } + +/* Handle the case when the next item is \d, \s, etc. Note that when PCRE_UCP +is set, \d turns into ESC_du rather than ESC_d, etc., so ESC_d etc. are +generated only when PCRE_UCP is *not* set, that is, when only ASCII +characteristics are recognized. Similarly, the opcodes OP_DIGIT etc. are +replaced by OP_PROP codes when PCRE_UCP is set. */ + +switch(op_code) + { + case OP_CHAR: + case OP_CHARI: + switch(escape) + { + case ESC_d: + return c > 255 || (cd->ctypes[c] & ctype_digit) == 0; + + case ESC_D: + return c <= 255 && (cd->ctypes[c] & ctype_digit) != 0; + + case ESC_s: + return c > 255 || (cd->ctypes[c] & ctype_space) == 0; + + case ESC_S: + return c <= 255 && (cd->ctypes[c] & ctype_space) != 0; + + case ESC_w: + return c > 255 || (cd->ctypes[c] & ctype_word) == 0; + + case ESC_W: + return c <= 255 && (cd->ctypes[c] & ctype_word) != 0; + + case ESC_h: + case ESC_H: + switch(c) + { + HSPACE_CASES: + return escape != ESC_h; + + default: + return escape == ESC_h; + } + + case ESC_v: + case ESC_V: + switch(c) + { + VSPACE_CASES: + return escape != ESC_v; + + default: + return escape == ESC_v; + } + + /* When PCRE_UCP is set, these values get generated for \d etc. Find + their substitutions and process them. The result will always be either + ESC_p or ESC_P. Then fall through to process those values. */ + +#ifdef SUPPORT_UCP + case ESC_du: + case ESC_DU: + case ESC_wu: + case ESC_WU: + case ESC_su: + case ESC_SU: + { + int temperrorcode = 0; + ptr = substitutes[escape - ESC_DU]; + escape = check_escape(&ptr, &next, &temperrorcode, 0, options, FALSE); + if (temperrorcode != 0) return FALSE; + ptr++; /* For compatibility */ + } + /* Fall through */ + + case ESC_p: + case ESC_P: + { + unsigned int ptype = 0, pdata = 0; + int errorcodeptr; + BOOL negated; + + ptr--; /* Make ptr point at the p or P */ + if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcodeptr)) + return FALSE; + ptr++; /* Point past the final curly ket */ + + /* If the property item is optional, we have to give up. (When generated + from \d etc by PCRE_UCP, this test will have been applied much earlier, + to the original \d etc. At this point, ptr will point to a zero byte. */ + + if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || + STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) + return FALSE; + + /* Do the property check. */ + + return check_char_prop(c, ptype, pdata, (escape == ESC_P) != negated); + } +#endif + + default: + return FALSE; + } + + /* In principle, support for Unicode properties should be integrated here as + well. It means re-organizing the above code so as to get hold of the property + values before switching on the op-code. However, I wonder how many patterns + combine ASCII \d etc with Unicode properties? (Note that if PCRE_UCP is set, + these op-codes are never generated.) */ + + case OP_DIGIT: + return escape == ESC_D || escape == ESC_s || escape == ESC_W || + escape == ESC_h || escape == ESC_v || escape == ESC_R; + + case OP_NOT_DIGIT: + return escape == ESC_d; + + case OP_WHITESPACE: + return escape == ESC_S || escape == ESC_d || escape == ESC_w; + + case OP_NOT_WHITESPACE: + return escape == ESC_s || escape == ESC_h || escape == ESC_v || escape == ESC_R; + + case OP_HSPACE: + return escape == ESC_S || escape == ESC_H || escape == ESC_d || + escape == ESC_w || escape == ESC_v || escape == ESC_R; + + case OP_NOT_HSPACE: + return escape == ESC_h; + + /* Can't have \S in here because VT matches \S (Perl anomaly) */ + case OP_ANYNL: + case OP_VSPACE: + return escape == ESC_V || escape == ESC_d || escape == ESC_w; + + case OP_NOT_VSPACE: + return escape == ESC_v || escape == ESC_R; + + case OP_WORDCHAR: + return escape == ESC_W || escape == ESC_s || escape == ESC_h || + escape == ESC_v || escape == ESC_R; + + case OP_NOT_WORDCHAR: + return escape == ESC_w || escape == ESC_d; + + default: + return FALSE; + } + +/* Control does not reach here */ +} + + + +/************************************************* +* Add a character or range to a class * +*************************************************/ + +/* This function packages up the logic of adding a character or range of +characters to a class. The character values in the arguments will be within the +valid values for the current mode (8-bit, 16-bit, UTF, etc). This function is +mutually recursive with the function immediately below. + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options word + cd contains pointers to tables etc. + start start of range character + end end of range character + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static int +add_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr, int options, + compile_data *cd, pcre_uint32 start, pcre_uint32 end) +{ +pcre_uint32 c; +int n8 = 0; + +/* If caseless matching is required, scan the range and process alternate +cases. In Unicode, there are 8-bit characters that have alternate cases that +are greater than 255 and vice-versa. Sometimes we can just extend the original +range. */ + +if ((options & PCRE_CASELESS) != 0) + { +#ifdef SUPPORT_UCP + if ((options & PCRE_UTF8) != 0) + { + int rc; + pcre_uint32 oc, od; + + options &= ~PCRE_CASELESS; /* Remove for recursive calls */ + c = start; + + while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 0) + { + /* Handle a single character that has more than one other case. */ + + if (rc > 0) n8 += add_list_to_class(classbits, uchardptr, options, cd, + PRIV(ucd_caseless_sets) + rc, oc); + + /* Do nothing if the other case range is within the original range. */ + + else if (oc >= start && od <= end) continue; + + /* Extend the original range if there is overlap, noting that if oc < c, we + can't have od > end because a subrange is always shorter than the basic + range. Otherwise, use a recursive call to add the additional range. */ + + else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */ + else if (od > end && oc <= end + 1) end = od; /* Extend upwards */ + else n8 += add_to_class(classbits, uchardptr, options, cd, oc, od); + } + } + else +#endif /* SUPPORT_UCP */ + + /* Not UTF-mode, or no UCP */ + + for (c = start; c <= end && c < 256; c++) + { + SETBIT(classbits, cd->fcc[c]); + n8++; + } + } + +/* Now handle the original range. Adjust the final value according to the bit +length - this means that the same lists of (e.g.) horizontal spaces can be used +in all cases. */ + +#if defined COMPILE_PCRE8 +#ifdef SUPPORT_UTF + if ((options & PCRE_UTF8) == 0) +#endif + if (end > 0xff) end = 0xff; + +#elif defined COMPILE_PCRE16 +#ifdef SUPPORT_UTF + if ((options & PCRE_UTF16) == 0) +#endif + if (end > 0xffff) end = 0xffff; + +#endif /* COMPILE_PCRE[8|16] */ + +/* If all characters are less than 256, use the bit map. Otherwise use extra +data. */ + +if (end < 0x100) + { + for (c = start; c <= end; c++) + { + n8++; + SETBIT(classbits, c); + } + } + +else + { + pcre_uchar *uchardata = *uchardptr; + +#ifdef SUPPORT_UTF + if ((options & PCRE_UTF8) != 0) /* All UTFs use the same flag bit */ + { + if (start < end) + { + *uchardata++ = XCL_RANGE; + uchardata += PRIV(ord2utf)(start, uchardata); + uchardata += PRIV(ord2utf)(end, uchardata); + } + else if (start == end) + { + *uchardata++ = XCL_SINGLE; + uchardata += PRIV(ord2utf)(start, uchardata); + } + } + else +#endif /* SUPPORT_UTF */ + + /* Without UTF support, character values are constrained by the bit length, + and can only be > 256 for 16-bit and 32-bit libraries. */ + +#ifdef COMPILE_PCRE8 + {} +#else + if (start < end) + { + *uchardata++ = XCL_RANGE; + *uchardata++ = start; + *uchardata++ = end; + } + else if (start == end) + { + *uchardata++ = XCL_SINGLE; + *uchardata++ = start; + } +#endif + + *uchardptr = uchardata; /* Updata extra data pointer */ + } + +return n8; /* Number of 8-bit characters */ +} + + + + +/************************************************* +* Add a list of characters to a class * +*************************************************/ + +/* This function is used for adding a list of case-equivalent characters to a +class, and also for adding a list of horizontal or vertical whitespace. If the +list is in order (which it should be), ranges of characters are detected and +handled appropriately. This function is mutually recursive with the function +above. + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options word + cd contains pointers to tables etc. + p points to row of 32-bit values, terminated by NOTACHAR + except character to omit; this is used when adding lists of + case-equivalent characters to avoid including the one we + already know about + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static int +add_list_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr, int options, + compile_data *cd, const pcre_uint32 *p, unsigned int except) +{ +int n8 = 0; +while (p[0] < NOTACHAR) + { + int n = 0; + if (p[0] != except) + { + while(p[n+1] == p[0] + n + 1) n++; + n8 += add_to_class(classbits, uchardptr, options, cd, p[0], p[n]); + } + p += n + 1; + } +return n8; +} + + + +/************************************************* +* Add characters not in a list to a class * +*************************************************/ + +/* This function is used for adding the complement of a list of horizontal or +vertical whitespace to a class. The list must be in order. + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options word + cd contains pointers to tables etc. + p points to row of 32-bit values, terminated by NOTACHAR + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static int +add_not_list_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr, + int options, compile_data *cd, const pcre_uint32 *p) +{ +BOOL utf = (options & PCRE_UTF8) != 0; +int n8 = 0; +if (p[0] > 0) + n8 += add_to_class(classbits, uchardptr, options, cd, 0, p[0] - 1); +while (p[0] < NOTACHAR) + { + while (p[1] == p[0] + 1) p++; + n8 += add_to_class(classbits, uchardptr, options, cd, p[0] + 1, + (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1); + p++; + } +return n8; +} + + + +/************************************************* +* Compile one branch * +*************************************************/ + +/* Scan the pattern, compiling it into the a vector. If the options are +changed during the branch, the pointer is used to change the external options +bits. 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: + optionsptr pointer to the option bits + codeptr points to the pointer to the current code point + ptrptr points to the current pattern pointer + errorcodeptr points to error code variable + firstcharptr place to put the first required character + firstcharflagsptr place to put the first character flags, or a negative number + reqcharptr place to put the last required character + reqcharflagsptr place to put the last required character flags, or a negative number + bcptr points to current branch chain + cond_depth conditional nesting depth + cd contains pointers to tables etc. + lengthptr NULL during the real compile phase + points to length accumulator during pre-compile phase + +Returns: TRUE on success + FALSE, with *errorcodeptr set non-zero on error +*/ + +static BOOL +compile_branch(int *optionsptr, pcre_uchar **codeptr, + const pcre_uchar **ptrptr, int *errorcodeptr, + pcre_uint32 *firstcharptr, pcre_int32 *firstcharflagsptr, + pcre_uint32 *reqcharptr, pcre_int32 *reqcharflagsptr, + 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; +pcre_uint32 firstchar, reqchar; +pcre_int32 firstcharflags, reqcharflags; +pcre_uint32 zeroreqchar, zerofirstchar; +pcre_int32 zeroreqcharflags, zerofirstcharflags; +pcre_int32 req_caseopt, reqvary, tempreqvary; +int options = *optionsptr; /* May change dynamically */ +int after_manual_callout = 0; +int length_prevgroup = 0; +register pcre_uint32 c; +int escape; +register pcre_uchar *code = *codeptr; +pcre_uchar *last_code = code; +pcre_uchar *orig_code = code; +pcre_uchar *tempcode; +BOOL inescq = FALSE; +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_UTF[16|32] have the same value as PCRE_UTF8. */ +BOOL utf = (options & PCRE_UTF8) != 0; +#ifndef COMPILE_PCRE32 +pcre_uchar utf_chars[6]; +#endif +#else +BOOL utf = FALSE; +#endif + +/* Helper variables for OP_XCLASS opcode (for characters > 255). We define +class_uchardata always so that it can be passed to add_to_class() always, +though it will not be used in non-UTF 8-bit cases. This avoids having to supply +alternative calls for the different cases. */ + +pcre_uchar *class_uchardata; +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 +BOOL xclass; +pcre_uchar *class_uchardata_base; +#endif + +#ifdef PCRE_DEBUG +if (lengthptr != NULL) DPRINTF((">> start branch\n")); +#endif + +/* Set up the default and non-default settings for greediness */ + +greedy_default = ((options & PCRE_UNGREEDY) != 0); +greedy_non_default = greedy_default ^ 1; + +/* Initialize no first byte, no required byte. REQ_UNSET means "no char +matching encountered yet". It gets changed to REQ_NONE if we hit something that +matches a non-fixed char first char; 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 zeroreqchar when such a repeat is encountered. The individual +item types that can be repeated set these backoff variables appropriately. */ + +firstchar = reqchar = zerofirstchar = zeroreqchar = 0; +firstcharflags = reqcharflags = zerofirstcharflags = zeroreqcharflags = REQ_UNSET; + +/* 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; + +/* Switch on next character until the end of the branch */ + +for (;; ptr++) + { + BOOL negate_class; + BOOL should_flip_negation; + BOOL possessive_quantifier; + BOOL is_quantifier; + BOOL is_recurse; + BOOL reset_bracount; + int class_has_8bitchar; + int class_one_char; + int newoptions; + int recno; + int refsign; + int skipbytes; + pcre_uint32 subreqchar, subfirstchar; + pcre_int32 subreqcharflags, subfirstcharflags; + int terminator; + unsigned int mclength; + unsigned int tempbracount; + pcre_uint32 ec; + pcre_uchar mcbuffer[8]; + + /* Get next character in the pattern */ + + c = *ptr; + + /* If we are at the end of a nested substitution, revert to the outer level + string. Nesting only happens one level deep. */ + + if (c == CHAR_NULL && nestptr != NULL) + { + ptr = nestptr; + nestptr = NULL; + c = *ptr; + } + + /* If we are in the pre-compile phase, accumulate the length used for the + previous cycle of this loop. */ + + if (lengthptr != NULL) + { +#ifdef PCRE_DEBUG + if (code > cd->hwm) cd->hwm = code; /* High water info */ +#endif + if (code > cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */ + { + *errorcodeptr = ERR52; + goto FAILED; + } + + /* There is at least one situation where code goes backwards: this is the + case of a zero quantifier after a class (e.g. [ab]{0}). At compile time, + the class is simply eliminated. However, it is created first, so we have to + allow memory for it. Therefore, don't ever reduce the length at this point. + */ + + if (code < last_code) code = last_code; + + /* Paranoid check for integer overflow */ + + if (OFLOW_MAX - *lengthptr < code - last_code) + { + *errorcodeptr = ERR20; + goto FAILED; + } + + *lengthptr += (int)(code - last_code); + 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, + if "previous" is NULL, reset the current code pointer to the start. */ + + if (previous != NULL) + { + if (previous > orig_code) + { + memmove(orig_code, previous, IN_UCHARS(code - previous)); + code -= previous - orig_code; + previous = orig_code; + } + } + else code = orig_code; + + /* Remember where this code item starts so we can pick up the length + next time round. */ + + last_code = code; + } + + /* In the real compile phase, just check the workspace used by the forward + reference list. */ + + else if (cd->hwm > cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN) + { + *errorcodeptr = ERR52; + goto FAILED; + } + + /* If in \Q...\E, check for the end; if not, we have a literal */ + + if (inescq && c != CHAR_NULL) + { + if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) + { + inescq = FALSE; + ptr++; + continue; + } + else + { + if (previous_callout != NULL) + { + if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ + complete_callout(previous_callout, ptr, cd); + previous_callout = NULL; + } + if ((options & PCRE_AUTO_CALLOUT) != 0) + { + previous_callout = code; + code = auto_callout(code, ptr, cd); + } + goto NORMAL_CHAR; + } + } + + /* Fill in length of a previous callout, except when the next thing is + a quantifier. */ + + is_quantifier = + c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK || + (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1)); + + if (!is_quantifier && previous_callout != NULL && + after_manual_callout-- <= 0) + { + if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ + complete_callout(previous_callout, ptr, cd); + previous_callout = NULL; + } + + /* In extended mode, skip white space and comments. */ + + if ((options & PCRE_EXTENDED) != 0) + { + if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue; + if (c == CHAR_NUMBER_SIGN) + { + ptr++; + while (*ptr != CHAR_NULL) + { + if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } + ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); +#endif + } + if (*ptr != CHAR_NULL) continue; + + /* Else fall through to handle end of string */ + c = 0; + } + } + + /* No auto callout for quantifiers. */ + + if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier) + { + previous_callout = code; + code = auto_callout(code, ptr, cd); + } + + switch(c) + { + /* ===================================================================*/ + case 0: /* The branch terminates at string end */ + case CHAR_VERTICAL_LINE: /* or | or ) */ + case CHAR_RIGHT_PARENTHESIS: + *firstcharptr = firstchar; + *firstcharflagsptr = firstcharflags; + *reqcharptr = reqchar; + *reqcharflagsptr = reqcharflags; + *codeptr = code; + *ptrptr = ptr; + if (lengthptr != NULL) + { + if (OFLOW_MAX - *lengthptr < code - last_code) + { + *errorcodeptr = ERR20; + goto FAILED; + } + *lengthptr += (int)(code - last_code); /* To include callout length */ + DPRINTF((">> end branch\n")); + } + return TRUE; + + + /* ===================================================================*/ + /* Handle single-character metacharacters. In multiline mode, ^ disables + the setting of any following char as a first character. */ + + case CHAR_CIRCUMFLEX_ACCENT: + previous = NULL; + if ((options & PCRE_MULTILINE) != 0) + { + if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + *code++ = OP_CIRCM; + } + else *code++ = OP_CIRC; + break; + + case CHAR_DOLLAR_SIGN: + previous = NULL; + *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 reqchar doesn't change either. */ + + case CHAR_DOT: + if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + zerofirstchar = firstchar; + zerofirstcharflags = firstcharflags; + zeroreqchar = reqchar; + zeroreqcharflags = reqcharflags; + previous = code; + *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY; + break; + + + /* ===================================================================*/ + /* Character classes. If the included characters are all < 256, we build a + 32-byte bitmap of the permitted characters, except in the special case + where there is only one such character. For negated classes, we build the + map as usual, then invert it at the end. However, we use a different opcode + so that data characters > 255 can be handled correctly. + + If the class contains characters outside the 0-255 range, a different + opcode is compiled. It may optionally have a bit map for characters < 256, + but those above are are explicitly listed afterwards. A flag byte tells + whether the bitmap is present, and whether this is a negated class or not. + + In JavaScript compatibility mode, an isolated ']' causes an error. In + default (Perl) mode, it is treated as a data character. */ + + case CHAR_RIGHT_SQUARE_BRACKET: + if ((cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0) + { + *errorcodeptr = ERR64; + goto FAILED; + } + goto NORMAL_CHAR; + + case CHAR_LEFT_SQUARE_BRACKET: + previous = code; + + /* PCRE supports POSIX class stuff inside a class. Perl gives an error if + they are encountered at the top level, so we'll do that too. */ + + if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || + ptr[1] == CHAR_EQUALS_SIGN) && + check_posix_syntax(ptr, &tempptr)) + { + *errorcodeptr = (ptr[1] == CHAR_COLON)? ERR13 : ERR31; + goto FAILED; + } + + /* If the first character is '^', set the negation flag and skip it. Also, + if the first few characters (either before or after ^) are \Q\E or \E we + skip them too. This makes for compatibility with Perl. */ + + negate_class = FALSE; + for (;;) + { + c = *(++ptr); + if (c == CHAR_BACKSLASH) + { + if (ptr[1] == CHAR_E) + ptr++; + else if (STRNCMP_UC_C8(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0) + ptr += 3; + else + break; + } + else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT) + negate_class = TRUE; + else break; + } + + /* Empty classes are allowed in JavaScript compatibility mode. Otherwise, + an initial ']' is taken as a data character -- the code below handles + that. In JS mode, [] must always fail, so generate OP_FAIL, whereas + [^] must match any character, so generate OP_ALLANY. */ + + if (c == CHAR_RIGHT_SQUARE_BRACKET && + (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0) + { + *code++ = negate_class? OP_ALLANY : OP_FAIL; + if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + zerofirstchar = firstchar; + zerofirstcharflags = firstcharflags; + break; + } + + /* If a class contains a negative special such as \S, we need to flip the + negation flag at the end, so that support for characters > 255 works + correctly (they are all included in the class). */ + + should_flip_negation = FALSE; + + /* 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_one_char will be 1 if the class contains just one + character. */ + + class_has_8bitchar = 0; + class_one_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 fewer than two + 8-bit characters because in that case the compiled code doesn't use the bit + map. */ + + memset(classbits, 0, 32 * sizeof(pcre_uint8)); + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + xclass = FALSE; + class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */ + class_uchardata_base = class_uchardata; /* Save the start */ +#endif + + /* Process characters until ] is reached. By writing this as a "do" it + means that an initial ] is taken as a data character. At the start of the + loop, c contains the first byte of the character. */ + + if (c != CHAR_NULL) do + { + const pcre_uchar *oldptr; + +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(c)) + { /* Braces are required because the */ + GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ + } +#endif + +#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 > 255 characters no longer overwrite the work space + (which is on the stack). We have to remember that there was XCLASS data, + however. */ + + if (lengthptr != NULL && class_uchardata > class_uchardata_base) + { + xclass = TRUE; + *lengthptr += class_uchardata - class_uchardata_base; + class_uchardata = class_uchardata_base; + } +#endif + + /* Inside \Q...\E everything is literal except \E */ + + if (inescq) + { + if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) /* If we are at \E */ + { + inescq = FALSE; /* Reset literal state */ + ptr++; /* Skip the 'E' */ + continue; /* Carry on with next */ + } + goto CHECK_RANGE; /* Could be range if \E follows */ + } + + /* Handle POSIX class names. Perl allows a negation extension of the + form [:^name:]. A square bracket that doesn't match the syntax is + treated as a literal. We also recognize the POSIX constructions + [.ch.] and [=ch=] ("collating elements") and fault them, as Perl + 5.6 and 5.8 do. */ + + if (c == CHAR_LEFT_SQUARE_BRACKET && + (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || + ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr)) + { + BOOL local_negate = FALSE; + int posix_class, taboffset, tabopt; + register const pcre_uint8 *cbits = cd->cbits; + pcre_uint8 pbits[32]; + + if (ptr[1] != CHAR_COLON) + { + *errorcodeptr = ERR31; + goto FAILED; + } + + ptr += 2; + if (*ptr == CHAR_CIRCUMFLEX_ACCENT) + { + local_negate = TRUE; + should_flip_negation = TRUE; /* Note negative special */ + ptr++; + } + + posix_class = check_posix_name(ptr, (int)(tempptr - ptr)); + if (posix_class < 0) + { + *errorcodeptr = ERR30; + goto FAILED; + } + + /* If matching is caseless, upper and lower are converted to + alpha. This relies on the fact that the class table starts with + alpha, lower, upper as the first 3 entries. */ + + if ((options & PCRE_CASELESS) != 0 && posix_class <= 2) + posix_class = 0; + + /* When PCRE_UCP is set, some of the POSIX classes are converted to + different escape sequences that use Unicode properties. */ + +#ifdef SUPPORT_UCP + if ((options & PCRE_UCP) != 0) + { + int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0); + if (posix_substitutes[pc] != NULL) + { + nestptr = tempptr + 1; + ptr = posix_substitutes[pc] - 1; + continue; + } + } +#endif + /* In the non-UCP case, we build the bit map for the POSIX class in a + chunk of local store because we may be adding and subtracting from it, + and we don't want to subtract bits that may be in the main map already. + At the end we or the result into the bit map that is being built. */ + + posix_class *= 3; + + /* Copy in the first table (always present) */ + + memcpy(pbits, cbits + posix_class_maps[posix_class], + 32 * sizeof(pcre_uint8)); + + /* If there is a second table, add or remove it as required. */ + + taboffset = posix_class_maps[posix_class + 1]; + tabopt = posix_class_maps[posix_class + 2]; + + if (taboffset >= 0) + { + if (tabopt >= 0) + for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset]; + else + for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset]; + } + + /* Now see if we need to remove any special characters. An option + value of 1 removes vertical space and 2 removes underscore. */ + + if (tabopt < 0) tabopt = -tabopt; + if (tabopt == 1) pbits[1] &= ~0x3c; + else if (tabopt == 2) pbits[11] &= 0x7f; + + /* Add the POSIX table or its complement into the main table that is + being built and we are done. */ + + if (local_negate) + for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c]; + else + for (c = 0; c < 32; c++) classbits[c] |= pbits[c]; + + ptr = tempptr + 1; + /* Every class contains at least one < 256 character. */ + class_has_8bitchar = 1; + /* Every class contains at least two characters. */ + class_one_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 + speculatively set both class_has_8bitchar and class_one_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) + { + escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, TRUE); + + if (*errorcodeptr != 0) goto FAILED; + + if (escape == 0) + c = ec; + else if (escape == ESC_b) c = CHAR_BS; /* \b is backspace in a class */ + else if (escape == ESC_N) /* \N is not supported in a class */ + { + *errorcodeptr = ERR71; + goto FAILED; + } + else if (escape == ESC_Q) /* Handle start of quoted string */ + { + if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) + { + ptr += 2; /* avoid empty string */ + } + else inescq = TRUE; + continue; + } + else if (escape == ESC_E) continue; /* Ignore orphan \E */ + + else + { + 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_one_char += 2; + + switch (escape) + { +#ifdef SUPPORT_UCP + case ESC_du: /* These are the values given for \d etc */ + case ESC_DU: /* when PCRE_UCP is set. We replace the */ + case ESC_wu: /* escape sequence with an appropriate \p */ + case ESC_WU: /* or \P to test Unicode properties instead */ + case ESC_su: /* of the default ASCII testing. */ + case ESC_SU: + nestptr = ptr; + ptr = substitutes[escape - ESC_DU] - 1; /* Just before substitute */ + class_has_8bitchar--; /* Undo! */ + continue; +#endif + case ESC_d: + for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit]; + continue; + + case ESC_D: + should_flip_negation = TRUE; + for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit]; + continue; + + case ESC_w: + for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word]; + continue; + + case ESC_W: + should_flip_negation = TRUE; + for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word]; + continue; + + /* Perl 5.004 onwards omits VT from \s, but we must preserve it + if it was previously set by something earlier in the character + class. Luckily, the value of CHAR_VT is 0x0b in both ASCII and + EBCDIC, so we lazily just adjust the appropriate bit. */ + + case ESC_s: + classbits[0] |= cbits[cbit_space]; + classbits[1] |= cbits[cbit_space+1] & ~0x08; + for (c = 2; c < 32; c++) classbits[c] |= cbits[c+cbit_space]; + continue; + + case ESC_S: + should_flip_negation = TRUE; + for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space]; + classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */ + continue; + + /* The rest apply in both UCP and non-UCP cases. */ + + case ESC_h: + (void)add_list_to_class(classbits, &class_uchardata, options, cd, + PRIV(hspace_list), NOTACHAR); + continue; + + case ESC_H: + (void)add_not_list_to_class(classbits, &class_uchardata, options, + cd, PRIV(hspace_list)); + continue; + + case ESC_v: + (void)add_list_to_class(classbits, &class_uchardata, options, cd, + PRIV(vspace_list), NOTACHAR); + continue; + + case ESC_V: + (void)add_not_list_to_class(classbits, &class_uchardata, options, + cd, PRIV(vspace_list)); + continue; + +#ifdef SUPPORT_UCP + case ESC_p: + case ESC_P: + { + BOOL negated; + unsigned int ptype = 0, pdata = 0; + if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr)) + goto FAILED; + *class_uchardata++ = ((escape == ESC_p) != negated)? + XCL_PROP : XCL_NOTPROP; + *class_uchardata++ = ptype; + *class_uchardata++ = pdata; + class_has_8bitchar--; /* Undo! */ + continue; + } +#endif + /* Unrecognized escapes are faulted if PCRE is running in its + strict mode. By default, for compatibility with Perl, they are + treated as literals. */ + + default: + if ((options & PCRE_EXTRA) != 0) + { + *errorcodeptr = ERR7; + goto FAILED; + } + class_has_8bitchar--; /* Undo the speculative increase. */ + class_one_char -= 2; /* Undo the speculative increase. */ + c = *ptr; /* Get the final character and fall through */ + break; + } + } + + /* Fall through if the escape just defined a single character (c >= 0). + This may be greater than 256. */ + + escape = 0; + + } /* End of backslash handling */ + + /* A character may be followed by '-' to form a range. However, Perl does + not permit ']' to be the end of the range. A '-' character at the end is + treated as a literal. Perl ignores orphaned \E sequences entirely. The + code for handling \Q and \E is messy. */ + + CHECK_RANGE: + while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) + { + inescq = FALSE; + ptr += 2; + } + oldptr = ptr; + + /* Remember if \r or \n were explicitly used */ + + if (c == CHAR_CR || c == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF; + + /* Check for range */ + + if (!inescq && ptr[1] == CHAR_MINUS) + { + pcre_uint32 d; + ptr += 2; + while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2; + + /* If we hit \Q (not followed by \E) at this point, go into escaped + mode. */ + + while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q) + { + ptr += 2; + if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) + { ptr += 2; continue; } + inescq = TRUE; + break; + } + + /* Minus (hyphen) at the end of a class is treated as a literal, so put + back the pointer and jump to handle the character that preceded it. */ + + if (*ptr == CHAR_NULL || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET)) + { + ptr = oldptr; + goto CLASS_SINGLE_CHARACTER; + } + + /* Otherwise, we have a potential range; pick up the next character */ + +#ifdef SUPPORT_UTF + if (utf) + { /* Braces are required because the */ + GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */ + } + else +#endif + d = *ptr; /* Not UTF-8 mode */ + + /* The second part of a range can be a single-character escape, but + not any of the other escapes. Perl 5.6 treats a hyphen as a literal + in such circumstances. */ + + if (!inescq && d == CHAR_BACKSLASH) + { + int descape; + descape = check_escape(&ptr, &d, errorcodeptr, cd->bracount, options, TRUE); + if (*errorcodeptr != 0) goto FAILED; + + /* \b is backspace; any other special means the '-' was literal. */ + + if (descape != 0) + { + if (descape == ESC_b) d = CHAR_BS; else + { + ptr = oldptr; + goto CLASS_SINGLE_CHARACTER; /* A few lines below */ + } + } + } + + /* Check that the two values are in the correct order. Optimize + one-character ranges. */ + + if (d < c) + { + *errorcodeptr = ERR8; + goto FAILED; + } + if (d == c) goto CLASS_SINGLE_CHARACTER; /* A few lines below */ + + /* We have found a character range, so single character optimizations + cannot be done anymore. Any value greater than 1 indicates that there + is more than one character. */ + + class_one_char = 2; + + /* Remember an explicit \r or \n, and add the range to the class. */ + + if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF; + + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, cd, c, d); + + continue; /* Go get the next char in the class */ + } + + /* Handle a single character - we can get here for a normal non-escape + char, or after \ that introduces a single character or for an apparent + range that isn't. Only the value 1 matters for class_one_char, so don't + increase it if it is already 2 or more ... just in case there's a class + with a zillion characters in it. */ + + CLASS_SINGLE_CHARACTER: + if (class_one_char < 2) class_one_char++; + + /* If class_one_char is 1, we have the first single character in the + class, and there have been no prior ranges, or XCLASS items generated by + escapes. If this is the final character in the class, we can optimize by + turning the item into a 1-character OP_CHAR[I] if it's positive, or + OP_NOT[I] if it's negative. In the positive case, it can cause firstchar + to be set. Otherwise, there can be no first char if this item is first, + whatever repeat count may follow. In the case of reqchar, save the + previous value for reinstating. */ + + if (class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) + { + ptr++; + zeroreqchar = reqchar; + zeroreqcharflags = reqcharflags; + + if (negate_class) + { +#ifdef SUPPORT_UCP + int d; +#endif + if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + zerofirstchar = firstchar; + zerofirstcharflags = firstcharflags; + + /* For caseless UTF-8 mode when UCP support is available, check + whether this character has more than one other case. If so, generate + a special OP_NOTPROP item instead of OP_NOTI. */ + +#ifdef SUPPORT_UCP + if (utf && (options & PCRE_CASELESS) != 0 && + (d = UCD_CASESET(c)) != 0) + { + *code++ = OP_NOTPROP; + *code++ = PT_CLIST; + *code++ = d; + } + else +#endif + /* Char has only one other case, or UCP not available */ + + { + *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT; +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) + code += PRIV(ord2utf)(c, code); + else +#endif + *code++ = c; + } + + /* We are finished with this character class */ + + goto END_CLASS; + } + + /* For a single, positive character, get the value into mcbuffer, and + then we can handle this with the normal one-character code. */ + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + 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 */ + + /* There is more than one character in the class, or an XCLASS item + has been generated. Add this character to the class. */ + + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, cd, c, c); + } + + /* Loop until ']' reached. This "while" is the end of the "do" far above. + If we are at the end of an internal nested string, revert to the outer + string. */ + + while (((c = *(++ptr)) != CHAR_NULL || + (nestptr != NULL && + (ptr = nestptr, nestptr = NULL, c = *(++ptr)) != CHAR_NULL)) && + (c != CHAR_RIGHT_SQUARE_BRACKET || inescq)); + + /* Check for missing terminating ']' */ + + if (c == CHAR_NULL) + { + *errorcodeptr = ERR6; + goto FAILED; + } + + /* We will need an XCLASS if data has been placed in class_uchardata. In + the second phase this is a sufficient test. However, in the pre-compile + phase, class_uchardata gets emptied to prevent workspace overflow, so it + only if the very last character in the class needs XCLASS will it contain + anything at this point. For this reason, xclass gets set TRUE above when + uchar_classdata is emptied, and that's why this code is the way it is here + instead of just doing a test on class_uchardata below. */ + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + if (class_uchardata > class_uchardata_base) xclass = TRUE; +#endif + + /* 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 (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + zerofirstchar = firstchar; + zerofirstcharflags = firstcharflags; + zeroreqchar = reqchar; + zeroreqcharflags = reqcharflags; + + /* If there are characters with values > 255, we have to compile an + extended class, with its own opcode, unless there was a negated special + such as \S in the class, and PCRE_UCP is not set, because in that case all + characters > 255 are in the class, so any that were explicitly given as + well can be ignored. If (when there are explicit characters > 255 that must + be listed) there are no characters < 256, we can omit the bitmap in the + actual compiled code. */ + +#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_uchardata++ = XCL_END; /* Marks the end of extra data */ + *code++ = OP_XCLASS; + code += LINK_SIZE; + *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_has_8bitchar > 0) + { + *code++ |= XCL_MAP; + memmove(code + (32 / sizeof(pcre_uchar)), code, + IN_UCHARS(class_uchardata - code)); + memcpy(code, classbits, 32); + code = class_uchardata + (32 / sizeof(pcre_uchar)); + } + else code = class_uchardata; + + /* Now fill in the complete length of the item */ + + PUT(previous, 1, (int)(code - previous)); + break; /* End of class handling */ + } +#endif + + /* If there are no characters > 255, or they are all to be included or + excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the + whole class was negated and whether there were negative specials such as \S + (non-UCP) in the class. Then copy the 32-byte map into the code vector, + negating it if necessary. */ + + *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS; + 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 / sizeof(pcre_uchar); + + END_CLASS: + break; + + + /* ===================================================================*/ + /* Various kinds of repeat; '{' is not necessarily a quantifier, but this + has been tested above. */ + + case CHAR_LEFT_CURLY_BRACKET: + if (!is_quantifier) goto NORMAL_CHAR; + ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr); + if (*errorcodeptr != 0) goto FAILED; + goto REPEAT; + + case CHAR_ASTERISK: + repeat_min = 0; + repeat_max = -1; + goto REPEAT; + + case CHAR_PLUS: + repeat_min = 1; + repeat_max = -1; + goto REPEAT; + + case CHAR_QUESTION_MARK: + repeat_min = 0; + repeat_max = 1; + + REPEAT: + if (previous == NULL) + { + *errorcodeptr = ERR9; + goto FAILED; + } + + if (repeat_min == 0) + { + firstchar = zerofirstchar; /* Adjust for zero repeat */ + firstcharflags = zerofirstcharflags; + reqchar = zeroreqchar; /* Ditto */ + reqcharflags = zeroreqcharflags; + } + + /* Remember whether this is a variable length repeat */ + + reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY; + + 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 in order to + insert something before it. */ + + tempcode = previous; + + /* If the next character is '+', we have a possessive quantifier. This + implies greediness, whatever the setting of the PCRE_UNGREEDY option. + If the next character is '?' this is a minimizing repeat, by default, + but if PCRE_UNGREEDY is set, it works the other way round. We change the + repeat type to the non-default. */ + + if (ptr[1] == CHAR_PLUS) + { + repeat_type = 0; /* Force greedy */ + possessive_quantifier = TRUE; + ptr++; + } + else if (ptr[1] == CHAR_QUESTION_MARK) + { + repeat_type = greedy_non_default; + ptr++; + } + else repeat_type = greedy_default; + + /* If previous was a recursion call, wrap it in atomic brackets so that + previous becomes the atomic group. All recursions were so wrapped in the + past, but it no longer happens for non-repeated recursions. In fact, the + repeated ones could be re-implemented independently so as not to need this, + but for the moment we rely on the code for repeating groups. */ + + if (*previous == OP_RECURSE) + { + memmove(previous + 1 + LINK_SIZE, previous, 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 UTF_LENGTH to flag that + it's a length rather than a small character. */ + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (utf && NOT_FIRSTCHAR(code[-1])) + { + pcre_uchar *lastchar = code - 1; + BACKCHAR(lastchar); + c = (int)(code - lastchar); /* Length of UTF-8 character */ + memcpy(utf_chars, lastchar, IN_UCHARS(c)); /* Save the char */ + c |= UTF_LENGTH; /* Flag c as a length */ + } + else +#endif /* 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 (*previous <= OP_CHARI && repeat_min > 1) + { + reqchar = c; + reqcharflags = req_caseopt | cd->req_varyopt; + } + } + + /* If the repetition is unlimited, it pays to see if the next thing on + the line is something that cannot possibly match this character. If so, + automatically possessifying this item gains some performance in the case + where the match fails. */ + + if (!possessive_quantifier && + repeat_max < 0 && + check_auto_possessive(previous, utf, ptr + 1, options, cd)) + { + repeat_type = 0; /* Force greedy */ + possessive_quantifier = TRUE; + } + + goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */ + } + + /* 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 + the the Unicode property types will be present only when SUPPORT_UCP is + defined, but we don't wrap the little bits of code here because it just + makes it horribly messy. */ + + else if (*previous < OP_EODN) + { + 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, utf, ptr + 1, options, cd)) + { + repeat_type = 0; /* Force greedy */ + possessive_quantifier = TRUE; + } + + OUTPUT_SINGLE_REPEAT: + if (*previous == OP_PROP || *previous == OP_NOTPROP) + { + prop_type = previous[1]; + prop_value = previous[2]; + } + else prop_type = prop_value = -1; + + oldcode = code; + code = previous; /* Usually overwrite previous item */ + + /* If the maximum is zero then the minimum must also be zero; Perl allows + this case, so we do too - by simply omitting the item altogether. */ + + if (repeat_max == 0) goto END_REPEAT; + + /*--------------------------------------------------------------------*/ + /* This code is obsolete from release 8.00; the restriction was finally + removed: */ + + /* All real repeats make it impossible to handle partial matching (maybe + one day we will be able to remove this restriction). */ + + /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */ + /*--------------------------------------------------------------------*/ + + /* Combine the op_type with the repeat_type */ + + repeat_type += op_type; + + /* A minimum of zero is handled either as the special case * or ?, or as + an UPTO, with the maximum given. */ + + if (repeat_min == 0) + { + if (repeat_max == -1) *code++ = OP_STAR + repeat_type; + else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type; + else + { + *code++ = OP_UPTO + repeat_type; + PUT2INC(code, 0, repeat_max); + } + } + + /* A repeat minimum of 1 is optimized into some special cases. If the + maximum is unlimited, we use OP_PLUS. Otherwise, the original item is + left in place and, if the maximum is greater than 1, we use OP_UPTO with + one less than the maximum. */ + + else if (repeat_min == 1) + { + if (repeat_max == -1) + *code++ = OP_PLUS + repeat_type; + else + { + code = oldcode; /* leave previous item in place */ + if (repeat_max == 1) goto END_REPEAT; + *code++ = OP_UPTO + repeat_type; + PUT2INC(code, 0, repeat_max - 1); + } + } + + /* The case {n,n} is just an EXACT, while the general case {n,m} is + handled as an EXACT followed by an UPTO. */ + + else + { + *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */ + PUT2INC(code, 0, repeat_min); + + /* If the maximum is unlimited, insert an OP_STAR. Before doing so, + 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 UTF_LENGTH bit as a flag. */ + + if (repeat_max < 0) + { +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (utf && (c & UTF_LENGTH) != 0) + { + memcpy(code, utf_chars, IN_UCHARS(c & 7)); + code += c & 7; + } + else +#endif + { + *code++ = c; + if (prop_type >= 0) + { + *code++ = prop_type; + *code++ = prop_value; + } + } + *code++ = OP_STAR + repeat_type; + } + + /* Else insert an UPTO if the max is greater than the min, again + preceded by the character, for the previously inserted code. If the + UPTO is just for 1 instance, we can use QUERY instead. */ + + else if (repeat_max != repeat_min) + { +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (utf && (c & UTF_LENGTH) != 0) + { + memcpy(code, utf_chars, IN_UCHARS(c & 7)); + code += c & 7; + } + else +#endif + *code++ = c; + if (prop_type >= 0) + { + *code++ = prop_type; + *code++ = prop_value; + } + repeat_max -= repeat_min; + + if (repeat_max == 1) + { + *code++ = OP_QUERY + repeat_type; + } + else + { + *code++ = OP_UPTO + repeat_type; + PUT2INC(code, 0, repeat_max); + } + } + } + + /* The character or character type itself comes last in all cases. */ + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (utf && (c & UTF_LENGTH) != 0) + { + memcpy(code, utf_chars, IN_UCHARS(c & 7)); + code += c & 7; + } + else +#endif + *code++ = c; + + /* For a repeated Unicode property match, there are two extra bytes that + define the required property. */ + +#ifdef SUPPORT_UCP + if (prop_type >= 0) + { + *code++ = prop_type; + *code++ = prop_value; + } +#endif + } + + /* If previous was a character class or a back reference, we put the repeat + stuff after it, but just skip the item if the repeat was {0,0}. */ + + else if (*previous == OP_CLASS || + *previous == OP_NCLASS || +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + *previous == OP_XCLASS || +#endif + *previous == OP_REF || + *previous == OP_REFI) + { + if (repeat_max == 0) + { + code = previous; + goto END_REPEAT; + } + + /*--------------------------------------------------------------------*/ + /* This code is obsolete from release 8.00; the restriction was finally + removed: */ + + /* All real repeats make it impossible to handle partial matching (maybe + one day we will be able to remove this restriction). */ + + /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */ + /*--------------------------------------------------------------------*/ + + if (repeat_min == 0 && repeat_max == -1) + *code++ = OP_CRSTAR + repeat_type; + else if (repeat_min == 1 && repeat_max == -1) + *code++ = OP_CRPLUS + repeat_type; + else if (repeat_min == 0 && repeat_max == 1) + *code++ = OP_CRQUERY + repeat_type; + else + { + *code++ = OP_CRRANGE + repeat_type; + PUT2INC(code, 0, repeat_min); + if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */ + PUT2INC(code, 0, repeat_max); + } + } + + /* If previous was a bracket group, we may have to replicate it in certain + 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_ASSERT && *previous <= OP_COND) + { + register int i; + int len = (int)(code - previous); + pcre_uchar *bralink = NULL; + pcre_uchar *brazeroptr = NULL; + + /* 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) + 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 (*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 + OP_BRAZERO in front of it, and because the group appears once in the + data, whereas in other cases it appears the minimum number of times. For + this reason, it is simplest to treat this case separately, as otherwise + the code gets far too messy. There are several special subcases when the + minimum is zero. */ + + if (repeat_min == 0) + { + /* If the maximum is also zero, we used to just omit the group from the + output altogether, like this: + + ** if (repeat_max == 0) + ** { + ** code = previous; + ** goto END_REPEAT; + ** } + + 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 + OP_RECURSE calls inside the group that refer to the group itself or any + internal or forward referenced group, because the offset is from the + start of the whole regex. Temporarily terminate the pattern while doing + this. */ + + if (repeat_max <= 1) /* Covers 0, 1, and unlimited */ + { + *code = OP_END; + 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; + } + + /* If the maximum is greater than 1 and limited, we have to replicate + in a nested fashion, sticking OP_BRAZERO before each set of brackets. + The first one has to be handled carefully because it's the original + copy, which has to be moved up. The remainder can be handled by code + that is common with the non-zero minimum case below. We have to + adjust the value or repeat_max, since one less copy is required. Once + again, we may have to adjust any OP_RECURSE calls inside the group. */ + + else + { + int offset; + *code = OP_END; + 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; + + /* We chain together the bracket offset fields that have to be + filled in later when the ends of the brackets are reached. */ + + offset = (bralink == NULL)? 0 : (int)(previous - bralink); + bralink = previous; + PUTINC(previous, 0, offset); + } + + repeat_max--; + } + + /* If the minimum is greater than zero, replicate the group as many + times as necessary, and adjust the maximum to the number of subsequent + copies that we need. If we set a first char from the group, and didn't + set a required char, copy the latter from the former. If there are any + forward reference subroutine calls in the group, there will be entries on + the workspace list; replicate these with an appropriate increment. */ + + else + { + if (repeat_min > 1) + { + /* In the pre-compile phase, we don't actually do the replication. We + just adjust the length as if we had. Do some paranoid checks for + potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit + integer type when available, otherwise double. */ + + if (lengthptr != NULL) + { + int delta = (repeat_min - 1)*length_prevgroup; + if ((INT64_OR_DOUBLE)(repeat_min - 1)* + (INT64_OR_DOUBLE)length_prevgroup > + (INT64_OR_DOUBLE)INT_MAX || + OFLOW_MAX - *lengthptr < delta) + { + *errorcodeptr = ERR20; + goto FAILED; + } + *lengthptr += delta; + } + + /* 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 (groupsetfirstchar && reqcharflags < 0) + { + reqchar = firstchar; + reqcharflags = firstcharflags; + } + + for (i = 1; i < repeat_min; i++) + { + 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); + cd->hwm += LINK_SIZE; + } + save_hwm = this_hwm; + code += len; + } + } + } + + if (repeat_max > 0) repeat_max -= repeat_min; + } + + /* This code is common to both the zero and non-zero minimum cases. If + the maximum is limited, it replicates the group in a nested fashion, + remembering the bracket starts on a stack. In the case of a zero minimum, + the first one was set up above. In all cases the repeat_max now specifies + the number of additional copies needed. Again, we must remember to + replicate entries on the forward reference list. */ + + if (repeat_max >= 0) + { + /* In the pre-compile phase, we don't actually do the replication. We + just adjust the length as if we had. For each repetition we must add 1 + to the length for BRAZERO and for all but the last repetition we must + add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some + paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is + a 64-bit integer type when available, otherwise double. */ + + if (lengthptr != NULL && repeat_max > 0) + { + int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) - + 2 - 2*LINK_SIZE; /* Last one doesn't nest */ + if ((INT64_OR_DOUBLE)repeat_max * + (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE) + > (INT64_OR_DOUBLE)INT_MAX || + OFLOW_MAX - *lengthptr < delta) + { + *errorcodeptr = ERR20; + goto FAILED; + } + *lengthptr += delta; + } + + /* This is compiling for real */ + + else for (i = repeat_max - 1; i >= 0; i--) + { + pcre_uchar *hc; + pcre_uchar *this_hwm = cd->hwm; + + *code++ = OP_BRAZERO + repeat_type; + + /* All but the final copy start a new nesting, maintaining the + chain of brackets outstanding. */ + + if (i != 0) + { + int offset; + *code++ = OP_BRA; + offset = (bralink == NULL)? 0 : (int)(code - bralink); + bralink = code; + PUTINC(code, 0, offset); + } + + 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)); + cd->hwm += LINK_SIZE; + } + save_hwm = this_hwm; + code += len; + } + + /* Now chain through the pending brackets, and fill in their length + fields (which are holding the chain links pro tem). */ + + while (bralink != NULL) + { + int oldlinkoffset; + int offset = (int)(code - bralink + 1); + pcre_uchar *bra = code - offset; + oldlinkoffset = GET(bra, 1); + bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset; + *code++ = OP_KET; + PUTINC(code, 0, offset); + PUT(bra, 1, offset); + } + } + + /* 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. + + 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 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 + { + 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 + { + /* In the compile phase, check for empty string matching. */ + + if (lengthptr == NULL) + { + pcre_uchar *scode = bracode; + do + { + 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); + } + + /* For non-COND brackets, we modify the BRA code and use KETRPOS. */ + + else + { + *bracode += 1; /* Switch to xxxPOS opcodes */ + *ketcode = OP_KETRPOS; + } + + /* If the minimum is zero, mark it as possessive, then unset the + possessive flag when the minimum is 0 or 1. */ + + if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO; + if (repeat_min < 2) possessive_quantifier = FALSE; + } + + /* Non-possessive quantifier */ + + else *ketcode = OP_KETRMAX + repeat_type; + } + } + } + + /* If previous is OP_FAIL, it was generated by an empty class [] in + JavaScript mode. The other ways in which OP_FAIL can be generated, that is + by (*FAIL) or (?!) set previous to NULL, which gives a "nothing to repeat" + error above. We can just ignore the repeat in JS case. */ + + else if (*previous == OP_FAIL) goto END_REPEAT; + + /* Else there's some kind of shambles */ + + else + { + *errorcodeptr = ERR11; + goto FAILED; + } + + /* If the character following a repeat is '+', or if certain optimization + tests above succeeded, possessive_quantifier is TRUE. For some opcodes, + there are special alternative opcodes for this case. For anything else, we + wrap the entire repeated item inside OP_ONCE brackets. Logically, the '+' + notation is just syntactic sugar, taken from Sun's Java package, but the + special opcodes can optimize it. + + Some (but not all) possessively repeated subpatterns have already been + completely handled in the code just above. For them, possessive_quantifier + is always FALSE at this stage. + + Note that the repeated item starts at tempcode, not at previous, which + might be the first part of a string whose (former) last char we repeated. + + Possessifying an 'exact' quantifier has no effect, so we can ignore it. But + an 'upto' may follow. We skip over an 'exact' item, and then test the + length of what remains before proceeding. */ + + if (possessive_quantifier) + { + int len; + + if (*tempcode == OP_TYPEEXACT) + 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 += PRIV(OP_lengths)[*tempcode]; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(tempcode[-1])) + tempcode += GET_EXTRALEN(tempcode[-1]); +#endif + } + + len = (int)(code - tempcode); + if (len > 0) switch (*tempcode) + { + case OP_STAR: *tempcode = OP_POSSTAR; break; + case OP_PLUS: *tempcode = OP_POSPLUS; break; + case OP_QUERY: *tempcode = OP_POSQUERY; break; + case OP_UPTO: *tempcode = OP_POSUPTO; 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, utf, cd, save_hwm); + memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len)); + code += 1 + LINK_SIZE; + len += 1 + LINK_SIZE; + tempcode[0] = OP_ONCE; + *code++ = OP_KET; + PUTINC(code, 0, len); + PUT(tempcode, 1, len); + break; + } + } + + /* In all case we no longer have a previous item. We also set the + "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: + previous = NULL; + cd->req_varyopt |= reqvary; + break; + + + /* ===================================================================*/ + /* Start of nested parenthesized sub-expression, or comment or lookahead or + lookbehind or option setting or condition or all the other extended + parenthesis forms. */ + + case CHAR_LEFT_PARENTHESIS: + newoptions = options; + skipbytes = 0; + bravalue = OP_CBRA; + save_hwm = cd->hwm; + reset_bracount = FALSE; + + /* First deal with various "verbs" that can be introduced by '*'. */ + + 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 pcre_uchar *name = ptr + 1; + const pcre_uchar *arg = NULL; + previous = NULL; + 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 (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; + arglen = (int)(ptr - arg); + if ((unsigned int)arglen > MAX_MARK) + { + *errorcodeptr = ERR75; + goto FAILED; + } + } + + if (*ptr != CHAR_RIGHT_PARENTHESIS) + { + *errorcodeptr = ERR60; + goto FAILED; + } + + /* Scan the table of verb names */ + + for (i = 0; i < verbcount; i++) + { + if (namelen == verbs[i].len && + STRNCMP_UC_C8(name, vn, namelen) == 0) + { + int setverb; + + /* 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); + } + setverb = *code++ = + (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; + + /* Do not set firstchar after *ACCEPT */ + if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + } + + /* Handle other cases with/without an argument */ + + else if (arglen == 0) + { + if (verbs[i].op < 0) /* Argument is mandatory */ + { + *errorcodeptr = ERR66; + goto FAILED; + } + setverb = *code++ = verbs[i].op; + } + + else + { + if (verbs[i].op_arg < 0) /* Argument is forbidden */ + { + *errorcodeptr = ERR59; + goto FAILED; + } + setverb = *code++ = verbs[i].op_arg; + *code++ = arglen; + memcpy(code, arg, IN_UCHARS(arglen)); + code += arglen; + *code++ = 0; + } + + switch (setverb) + { + case OP_THEN: + case OP_THEN_ARG: + cd->external_flags |= PCRE_HASTHEN; + break; + + case OP_PRUNE: + case OP_PRUNE_ARG: + case OP_SKIP: + case OP_SKIP_ARG: + cd->had_pruneorskip = TRUE; + break; + } + + break; /* Found verb, exit loop */ + } + + vn += verbs[i].len + 1; + } + + if (i < verbcount) continue; /* Successfully handled a verb */ + *errorcodeptr = ERR60; /* Verb not recognized */ + goto FAILED; + } + + /* Deal with the extended parentheses; all are introduced by '?', and the + appearance of any of them means that this is not a capturing group. */ + + else if (*ptr == CHAR_QUESTION_MARK) + { + int i, set, unset, namelen; + int *optset; + const pcre_uchar *name; + pcre_uchar *slot; + + switch (*(++ptr)) + { + case CHAR_NUMBER_SIGN: /* Comment; skip to ket */ + ptr++; + while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; + if (*ptr == CHAR_NULL) + { + *errorcodeptr = ERR18; + goto FAILED; + } + continue; + + + /* ------------------------------------------------------------ */ + case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */ + reset_bracount = TRUE; + /* Fall through */ + + /* ------------------------------------------------------------ */ + case CHAR_COLON: /* Non-capturing bracket */ + bravalue = OP_BRA; + ptr++; + break; + + + /* ------------------------------------------------------------ */ + case CHAR_LEFT_PARENTHESIS: + bravalue = OP_COND; /* Conditional group */ + + /* A condition can be an assertion, a number (referring to a numbered + group), a name (referring to a named group), or 'R', referring to + recursion. R and R&name are also permitted for recursion tests. + + There are several syntaxes for testing a named group: (?(name)) is used + by Python; Perl 5.10 onwards uses (?() or (?('name')). + + There are two unfortunate ambiguities, caused by history. (a) 'R' can + be the recursive thing or the name 'R' (and similarly for 'R' followed + by digits), and (b) a number could be a name that consists of digits. + In both cases, we look for a name first; if not found, we try the other + cases. */ + + /* For conditions that are assertions, check the syntax, and then exit + the switch. This will take control down to where bracketed groups, + including assertions, are processed. */ + + if (ptr[1] == CHAR_QUESTION_MARK && (ptr[2] == CHAR_EQUALS_SIGN || + ptr[2] == CHAR_EXCLAMATION_MARK || ptr[2] == CHAR_LESS_THAN_SIGN)) + break; + + /* Most other conditions use OP_CREF (a couple change to OP_RREF + below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */ + + code[1+LINK_SIZE] = OP_CREF; + skipbytes = 1+IMM2_SIZE; + refsign = -1; + + /* Check for a test for recursion in a named group. */ + + if (ptr[1] == CHAR_R && ptr[2] == CHAR_AMPERSAND) + { + terminator = -1; + ptr += 2; + code[1+LINK_SIZE] = OP_RREF; /* Change the type of test */ + } + + /* Check for a test for a named group's having been set, using the Perl + syntax (?() or (?('name') */ + + else if (ptr[1] == CHAR_LESS_THAN_SIGN) + { + terminator = CHAR_GREATER_THAN_SIGN; + ptr++; + } + else if (ptr[1] == CHAR_APOSTROPHE) + { + terminator = CHAR_APOSTROPHE; + ptr++; + } + else + { + terminator = CHAR_NULL; + if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr); + } + + /* We now expect to read a name; any thing else is an error */ + + if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0) + { + ptr += 1; /* To get the right offset */ + *errorcodeptr = ERR28; + goto FAILED; + } + + /* Read the name, but also get it as a number if it's all digits */ + + recno = 0; + name = ++ptr; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) + { + if (recno >= 0) + recno = (IS_DIGIT(*ptr))? recno * 10 + (int)(*ptr - CHAR_0) : -1; + ptr++; + } + namelen = (int)(ptr - name); + + if ((terminator > 0 && *ptr++ != (pcre_uchar)terminator) || + *ptr++ != CHAR_RIGHT_PARENTHESIS) + { + ptr--; /* Error offset */ + *errorcodeptr = ERR26; + goto FAILED; + } + + /* Do no further checking in the pre-compile phase. */ + + if (lengthptr != NULL) break; + + /* In the real compile we do the work of looking for the actual + reference. If the string started with "+" or "-" we require the rest to + be digits, in which case recno will be set. */ + + if (refsign > 0) + { + if (recno <= 0) + { + *errorcodeptr = ERR58; + goto FAILED; + } + recno = (refsign == CHAR_MINUS)? + cd->bracount - recno + 1 : recno +cd->bracount; + if (recno <= 0 || recno > cd->final_bracount) + { + *errorcodeptr = ERR15; + goto FAILED; + } + PUT2(code, 2+LINK_SIZE, recno); + break; + } + + /* Otherwise (did not start with "+" or "-"), start by looking for the + name. If we find a name, add one to the opcode to change OP_CREF or + OP_RREF into OP_NCREF or OP_NRREF. These behave exactly the same, + except they record that the reference was originally to a name. The + information is used to check duplicate names. */ + + slot = cd->name_table; + for (i = 0; i < cd->names_found; i++) + { + if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0) break; + slot += cd->name_entry_size; + } + + /* Found a previous named subpattern */ + + if (i < cd->names_found) + { + recno = GET2(slot, 0); + PUT2(code, 2+LINK_SIZE, recno); + code[1+LINK_SIZE]++; + } + + /* Search the pattern for a forward reference */ + + else if ((i = find_parens(cd, name, namelen, + (options & PCRE_EXTENDED) != 0, utf)) > 0) + { + PUT2(code, 2+LINK_SIZE, i); + code[1+LINK_SIZE]++; + } + + /* If terminator == CHAR_NULL it means that the name followed directly + after the opening parenthesis [e.g. (?(abc)...] and in this case there + are some further alternatives to try. For the cases where terminator != + 0 [things like (?(... or (?('name')... or (?(R&name)... ] we have + now checked all the possibilities, so give an error. */ + + else if (terminator != CHAR_NULL) + { + *errorcodeptr = ERR15; + goto FAILED; + } + + /* Check for (?(R) for recursion. Allow digits after R to specify a + specific group number. */ + + else if (*name == CHAR_R) + { + recno = 0; + for (i = 1; i < namelen; i++) + { + if (!IS_DIGIT(name[i])) + { + *errorcodeptr = ERR15; + goto FAILED; + } + recno = recno * 10 + name[i] - CHAR_0; + } + if (recno == 0) recno = RREF_ANY; + code[1+LINK_SIZE] = OP_RREF; /* Change test type */ + PUT2(code, 2+LINK_SIZE, recno); + } + + /* Similarly, check for the (?(DEFINE) "condition", which is always + false. */ + + else if (namelen == 6 && STRNCMP_UC_C8(name, STRING_DEFINE, 6) == 0) + { + code[1+LINK_SIZE] = OP_DEF; + skipbytes = 1; + } + + /* Check for the "name" actually being a subpattern number. We are + in the second pass here, so final_bracount is set. */ + + else if (recno > 0 && recno <= cd->final_bracount) + { + PUT2(code, 2+LINK_SIZE, recno); + } + + /* Either an unidentified subpattern, or a reference to (?(0) */ + + else + { + *errorcodeptr = (recno == 0)? ERR35: ERR15; + goto FAILED; + } + break; + + + /* ------------------------------------------------------------ */ + case CHAR_EQUALS_SIGN: /* Positive lookahead */ + bravalue = OP_ASSERT; + cd->assert_depth += 1; + ptr++; + break; + + + /* ------------------------------------------------------------ */ + case CHAR_EXCLAMATION_MARK: /* Negative lookahead */ + ptr++; + if (*ptr == CHAR_RIGHT_PARENTHESIS) /* Optimize (?!) */ + { + *code++ = OP_FAIL; + previous = NULL; + continue; + } + bravalue = OP_ASSERT_NOT; + cd->assert_depth += 1; + break; + + + /* ------------------------------------------------------------ */ + case CHAR_LESS_THAN_SIGN: /* Lookbehind or named define */ + switch (ptr[1]) + { + 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 (MAX_255(ptr[1]) && (cd->ctypes[ptr[1]] & ctype_word) != 0) + goto DEFINE_NAME; + ptr++; /* Correct offset for error */ + *errorcodeptr = ERR24; + goto FAILED; + } + break; + + + /* ------------------------------------------------------------ */ + case CHAR_GREATER_THAN_SIGN: /* One-time brackets */ + bravalue = OP_ONCE; + ptr++; + break; + + + /* ------------------------------------------------------------ */ + 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 */ + *code++ = OP_CALLOUT; + { + int n = 0; + ptr++; + while(IS_DIGIT(*ptr)) + n = n * 10 + *ptr++ - CHAR_0; + if (*ptr != CHAR_RIGHT_PARENTHESIS) + { + *errorcodeptr = ERR39; + goto FAILED; + } + if (n > 255) + { + *errorcodeptr = ERR38; + goto FAILED; + } + *code++ = n; + PUT(code, 0, (int)(ptr - cd->start_pattern + 1)); /* Pattern offset */ + PUT(code, LINK_SIZE, 0); /* Default length */ + code += 2 * LINK_SIZE; + } + previous = NULL; + continue; + + + /* ------------------------------------------------------------ */ + case CHAR_P: /* Python-style named subpattern handling */ + if (*(++ptr) == CHAR_EQUALS_SIGN || + *ptr == CHAR_GREATER_THAN_SIGN) /* Reference or recursion */ + { + is_recurse = *ptr == CHAR_GREATER_THAN_SIGN; + terminator = CHAR_RIGHT_PARENTHESIS; + goto NAMED_REF_OR_RECURSE; + } + else if (*ptr != CHAR_LESS_THAN_SIGN) /* Test for Python-style defn */ + { + *errorcodeptr = ERR41; + goto FAILED; + } + /* Fall through to handle (?P< as (?< is handled */ + + + /* ------------------------------------------------------------ */ + DEFINE_NAME: /* Come here from (?< handling */ + case CHAR_APOSTROPHE: + { + terminator = (*ptr == CHAR_LESS_THAN_SIGN)? + CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; + name = ++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. */ + + if (lengthptr != NULL) + { + if (*ptr != (pcre_uchar)terminator) + { + *errorcodeptr = ERR42; + goto FAILED; + } + if (cd->names_found >= MAX_NAME_COUNT) + { + *errorcodeptr = ERR49; + goto FAILED; + } + if (namelen + IMM2_SIZE + 1 > cd->name_entry_size) + { + cd->name_entry_size = namelen + IMM2_SIZE + 1; + if (namelen > MAX_NAME_SIZE) + { + *errorcodeptr = ERR48; + goto FAILED; + } + } + } + + /* In the real compile, create the entry in the table, maintaining + alphabetical order. Duplicate names for different numbers are + permitted only if PCRE_DUPNAMES is set. Duplicate names for the same + number are always OK. (An existing number can be re-used if (?| + appears in the pattern.) In either event, a duplicate name results in + a duplicate entry in the table, even if the number is the same. This + is because the number of names, and hence the table size, is computed + in the pre-compile, and it affects various numbers and pointers which + would all have to be modified, and the compiled code moved down, if + duplicates with the same number were omitted from the table. This + doesn't seem worth the hassle. However, *different* names for the + same number are not permitted. */ + + else + { + BOOL dupname = FALSE; + slot = cd->name_table; + + for (i = 0; i < cd->names_found; i++) + { + int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen)); + if (crc == 0) + { + if (slot[IMM2_SIZE+namelen] == 0) + { + if (GET2(slot, 0) != cd->bracount + 1 && + (options & PCRE_DUPNAMES) == 0) + { + *errorcodeptr = ERR43; + goto FAILED; + } + else dupname = TRUE; + } + else crc = -1; /* Current name is a substring */ + } + + /* Make space in the table and break the loop for an earlier + name. For a duplicate or later name, carry on. We do this for + duplicates so that in the simple case (when ?(| is not used) they + are in order of their numbers. */ + + if (crc < 0) + { + memmove(slot + cd->name_entry_size, slot, + IN_UCHARS((cd->names_found - i) * cd->name_entry_size)); + break; + } + + /* Continue the loop for a later or duplicate name */ + + slot += cd->name_entry_size; + } + + /* For non-duplicate names, check for a duplicate number before + adding the new name. */ + + if (!dupname) + { + pcre_uchar *cslot = cd->name_table; + for (i = 0; i < cd->names_found; i++) + { + if (cslot != slot) + { + if (GET2(cslot, 0) == cd->bracount + 1) + { + *errorcodeptr = ERR65; + goto FAILED; + } + } + else i--; + cslot += cd->name_entry_size; + } + } + + PUT2(slot, 0, cd->bracount + 1); + memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen)); + slot[IMM2_SIZE + namelen] = 0; + } + } + + /* In both pre-compile and compile, count the number of names we've + encountered. */ + + cd->names_found++; + ptr++; /* Move past > or ' */ + goto NUMBERED_GROUP; + + + /* ------------------------------------------------------------ */ + case CHAR_AMPERSAND: /* Perl recursion/subroutine syntax */ + terminator = CHAR_RIGHT_PARENTHESIS; + is_recurse = TRUE; + /* Fall through */ + + /* We come here from the Python syntax above that handles both + references (?P=name) and recursion (?P>name), as well as falling + through from the Perl recursion syntax (?&name). We also come here from + the Perl \k or \k'name' back reference syntax and the \k{name} + .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */ + + NAMED_REF_OR_RECURSE: + name = ++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 + a dummy reference number, because it was not used in the first pass. + However, with the change of recursive back references to be atomic, + we have to look for the number so that this state can be identified, as + otherwise the incorrect length is computed. If it's not a backwards + reference, the dummy number will do. */ + + if (lengthptr != NULL) + { + const pcre_uchar *temp; + + if (namelen == 0) + { + *errorcodeptr = ERR62; + goto FAILED; + } + if (*ptr != (pcre_uchar)terminator) + { + *errorcodeptr = ERR42; + goto FAILED; + } + if (namelen > MAX_NAME_SIZE) + { + *errorcodeptr = ERR48; + goto FAILED; + } + + /* The name table does not exist in the first pass, so we cannot + do a simple search as in the code below. Instead, we have to scan the + pattern to find the number. It is important that we scan it only as + far as we have got because the syntax of named subpatterns has not + been checked for the rest of the pattern, and find_parens() assumes + correct syntax. In any case, it's a waste of resources to scan + further. We stop the scan at the current point by temporarily + adjusting the value of cd->endpattern. */ + + temp = cd->end_pattern; + cd->end_pattern = ptr; + recno = find_parens(cd, name, namelen, + (options & PCRE_EXTENDED) != 0, utf); + cd->end_pattern = temp; + if (recno < 0) recno = 0; /* Forward ref; set dummy number */ + } + + /* In the real compile, seek the name in the table. We check the name + first, and then check that we have reached the end of the name in the + table. That way, if the name that is longer than any in the table, + the comparison will fail without reading beyond the table entry. */ + + else + { + slot = cd->name_table; + for (i = 0; i < cd->names_found; i++) + { + if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0 && + slot[IMM2_SIZE+namelen] == 0) + break; + slot += cd->name_entry_size; + } + + if (i < cd->names_found) /* Back reference */ + { + recno = GET2(slot, 0); + } + else if ((recno = /* Forward back reference */ + find_parens(cd, name, namelen, + (options & PCRE_EXTENDED) != 0, utf)) <= 0) + { + *errorcodeptr = ERR15; + goto FAILED; + } + } + + /* In both phases, we can now go to the code than handles numerical + recursion or backreferences. */ + + if (is_recurse) goto HANDLE_RECURSION; + else goto HANDLE_REFERENCE; + + + /* ------------------------------------------------------------ */ + case CHAR_R: /* Recursion */ + ptr++; /* Same as (?0) */ + /* Fall through */ + + + /* ------------------------------------------------------------ */ + case CHAR_MINUS: case CHAR_PLUS: /* Recursion or subroutine */ + 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 pcre_uchar *called; + terminator = CHAR_RIGHT_PARENTHESIS; + + /* Come here from the \g<...> and \g'...' code (Oniguruma + compatibility). However, the syntax has been checked to ensure that + the ... are a (signed) number, so that neither ERR63 nor ERR29 will + be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY + ever be taken. */ + + HANDLE_NUMERICAL_RECURSION: + + if ((refsign = *ptr) == CHAR_PLUS) + { + ptr++; + if (!IS_DIGIT(*ptr)) + { + *errorcodeptr = ERR63; + goto FAILED; + } + } + else if (refsign == CHAR_MINUS) + { + if (!IS_DIGIT(ptr[1])) + goto OTHER_CHAR_AFTER_QUERY; + ptr++; + } + + recno = 0; + while(IS_DIGIT(*ptr)) + recno = recno * 10 + *ptr++ - CHAR_0; + + if (*ptr != (pcre_uchar)terminator) + { + *errorcodeptr = ERR29; + goto FAILED; + } + + if (refsign == CHAR_MINUS) + { + if (recno == 0) + { + *errorcodeptr = ERR58; + goto FAILED; + } + recno = cd->bracount - recno + 1; + if (recno <= 0) + { + *errorcodeptr = ERR15; + goto FAILED; + } + } + else if (refsign == CHAR_PLUS) + { + if (recno == 0) + { + *errorcodeptr = ERR58; + goto FAILED; + } + recno += cd->bracount; + } + + /* Come here from code above that handles a named recursion */ + + HANDLE_RECURSION: + + previous = code; + called = cd->start_code; + + /* When we are actually compiling, find the bracket that is being + referenced. Temporarily end the regex in case it doesn't exist before + this point. If we end up with a forward reference, first check that + the bracket does occur later so we can give the error (and position) + now. Then remember this forward reference in the workspace so it can + be filled in at the end. */ + + if (lengthptr == NULL) + { + *code = OP_END; + if (recno != 0) + called = PRIV(find_bracket)(cd->start_code, utf, recno); + + /* Forward reference */ + + if (called == NULL) + { + if (find_parens(cd, NULL, recno, + (options & PCRE_EXTENDED) != 0, utf) < 0) + { + *errorcodeptr = ERR15; + goto FAILED; + } + + /* 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. Then remember the forward reference. */ + + called = cd->start_code + recno; + 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. 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 && cond_depth <= 0 && + could_be_empty(called, code, bcptr, utf, cd)) + { + *errorcodeptr = ERR40; + goto FAILED; + } + } + + /* 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; + groupsetfirstchar = FALSE; + } + + /* Can't determine a first byte now */ + + if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + continue; + + + /* ------------------------------------------------------------ */ + default: /* Other characters: check option setting */ + OTHER_CHAR_AFTER_QUERY: + set = unset = 0; + optset = &set; + + while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON) + { + switch (*ptr++) + { + case CHAR_MINUS: optset = &unset; break; + + case CHAR_J: /* Record that it changed in the external options */ + *optset |= PCRE_DUPNAMES; + cd->external_flags |= PCRE_JCHANGED; + break; + + case CHAR_i: *optset |= PCRE_CASELESS; break; + case CHAR_m: *optset |= PCRE_MULTILINE; break; + case CHAR_s: *optset |= PCRE_DOTALL; break; + case CHAR_x: *optset |= PCRE_EXTENDED; break; + case CHAR_U: *optset |= PCRE_UNGREEDY; break; + case CHAR_X: *optset |= PCRE_EXTRA; break; + + default: *errorcodeptr = ERR12; + ptr--; /* Correct the offset */ + goto FAILED; + } + } + + /* Set up the changed option bits, but don't change anything yet. */ + + newoptions = (options | set) & (~unset); + + /* If the options ended with ')' this is not the start of a nested + group with option changes, so the options change at this level. If this + item is right at the start of the pattern, the options can be + abstracted and made external in the pre-compile phase, and ignored in + the compile phase. This can be helpful when matching -- for instance in + caseless checking of required bytes. + + If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are + definitely *not* at the start of the pattern because something has been + compiled. In the pre-compile phase, however, the code pointer can have + that value after the start, because it gets reset as code is discarded + during the pre-compile. However, this can happen only at top level - if + we are within parentheses, the starting BRA will still be present. At + any parenthesis level, the length value can be used to test if anything + has been compiled at that level. Thus, a test for both these conditions + is necessary to ensure we correctly detect the start of the pattern in + both phases. + + 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) + { + if (code == cd->start_code + 1 + LINK_SIZE && + (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE)) + { + cd->external_options = newoptions; + } + else + { + greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); + greedy_non_default = greedy_default ^ 1; + req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0; + } + + /* Change options at this level, and pass them back for use + in subsequent branches. */ + + *optionsptr = options = newoptions; + previous = NULL; /* This item can't be repeated */ + continue; /* It is complete */ + } + + /* If the options ended with ':' we are heading into a nested group + with possible change of options. Such groups are non-capturing and are + not assertions of any kind. All we need to do is skip over the ':'; + the newoptions value is handled below. */ + + bravalue = OP_BRA; + ptr++; + } /* End of switch for character following (? */ + } /* End of (? handling */ + + /* Opening parenthesis not followed by '*' or '?'. If PCRE_NO_AUTO_CAPTURE + is set, all unadorned brackets become non-capturing and behave like (?:...) + brackets. */ + + else if ((options & PCRE_NO_AUTO_CAPTURE) != 0) + { + bravalue = OP_BRA; + } + + /* Else we have a capturing group. */ + + else + { + NUMBERED_GROUP: + cd->bracount += 1; + PUT2(code, 1+LINK_SIZE, cd->bracount); + skipbytes = IMM2_SIZE; + } + + /* Process nested bracketed regex. Assertions used not to be repeatable, + but this was changed for Perl compatibility, so all kinds can now be + repeated. We copy code into a non-register variable (tempcode) in order to + be able to pass its address because some compilers complain otherwise. */ + + previous = code; /* For handling repetition */ + *code = bravalue; + tempcode = code; + 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 */ + &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 */ + cond_depth + + ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */ + &subfirstchar, /* For possible first char */ + &subfirstcharflags, + &subreqchar, /* For possible last char */ + &subreqcharflags, + 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. + The pattern pointer (ptr) is on the bracket. + + If this is a conditional bracket, check that there are no more than + two branches in the group, or just one if it's a DEFINE group. We do this + in the real compile phase, not in the pre-pass, where the whole group may + not be available. */ + + if (bravalue == OP_COND && lengthptr == NULL) + { + pcre_uchar *tc = code; + int condcount = 0; + + do { + condcount++; + tc += GET(tc,1); + } + while (*tc != OP_KET); + + /* A DEFINE group is never obeyed inline (the "condition" is always + false). It must have only one branch. */ + + if (code[LINK_SIZE+1] == OP_DEF) + { + if (condcount > 1) + { + *errorcodeptr = ERR54; + goto FAILED; + } + bravalue = OP_DEF; /* Just a flag to suppress char handling below */ + } + + /* A "normal" conditional group. If there is just one branch, we must not + make use of its firstchar or reqchar, because this is equivalent to an + empty second branch. */ + + else + { + if (condcount > 2) + { + *errorcodeptr = ERR27; + goto FAILED; + } + if (condcount == 1) subfirstcharflags = subreqcharflags = REQ_NONE; + } + } + + /* Error if hit end of pattern */ + + if (*ptr != CHAR_RIGHT_PARENTHESIS) + { + *errorcodeptr = ERR14; + goto FAILED; + } + + /* In the pre-compile phase, update the length by the length of the group, + less the brackets at either end. Then reduce the compiled code to just a + set of non-capturing brackets so that it doesn't use much memory if it is + duplicated by a quantifier.*/ + + if (lengthptr != NULL) + { + if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE) + { + *errorcodeptr = ERR20; + goto FAILED; + } + *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE; + code++; /* This already contains bravalue */ + PUTINC(code, 0, 1 + LINK_SIZE); + *code++ = OP_KET; + PUTINC(code, 0, 1 + LINK_SIZE); + break; /* No need to waste time with special character handling */ + } + + /* Otherwise update the main code pointer to the end of the group. */ + + code = tempcode; + + /* For a DEFINE group, required and first character settings are not + relevant. */ + + if (bravalue == OP_DEF) break; + + /* 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 zeroreqchar and + zerofirstchar outside the main loop so that they can be accessed for the + back off. */ + + zeroreqchar = reqchar; + zeroreqcharflags = reqcharflags; + zerofirstchar = firstchar; + zerofirstcharflags = firstcharflags; + groupsetfirstchar = FALSE; + + if (bravalue >= OP_ONCE) + { + /* 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 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 (firstcharflags == REQ_UNSET) + { + if (subfirstcharflags >= 0) + { + firstchar = subfirstchar; + firstcharflags = subfirstcharflags; + groupsetfirstchar = TRUE; + } + else firstcharflags = REQ_NONE; + zerofirstcharflags = REQ_NONE; + } + + /* 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 (subfirstcharflags >= 0 && subreqcharflags < 0) + { + subreqchar = subfirstchar; + subreqcharflags = subfirstcharflags | 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 (subreqcharflags >= 0) + { + reqchar = subreqchar; + reqcharflags = subreqcharflags; + } + } + + /* 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 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 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 && subreqcharflags >= 0) + { + reqchar = subreqchar; + reqcharflags = subreqcharflags; + } + break; /* End of processing '(' */ + + + /* ===================================================================*/ + /* Handle metasequences introduced by \. For ones like \d, the ESC_ values + are arranged to be the negation of the corresponding OP_values in the + default case when PCRE_UCP is not set. For the back references, the values + are negative the reference number. Only back references and those types + that consume a character may be repeated. We can test for values between + ESC_b and ESC_Z for the latter; this may have to change if any new ones are + ever created. */ + + case CHAR_BACKSLASH: + tempptr = ptr; + escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, FALSE); + + if (*errorcodeptr != 0) goto FAILED; + + if (escape == 0) + c = ec; + else + { + if (escape == ESC_Q) /* Handle start of quoted string */ + { + if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) + ptr += 2; /* avoid empty string */ + else inescq = TRUE; + continue; + } + + if (escape == ESC_E) continue; /* Perl ignores an orphan \E */ + + /* For metasequences that actually match a character, we disable the + setting of a first character if it hasn't already been set. */ + + if (firstcharflags == REQ_UNSET && escape > ESC_b && escape < ESC_Z) + firstcharflags = REQ_NONE; + + /* Set values to reset to if this is followed by a zero repeat. */ + + zerofirstchar = firstchar; + zerofirstcharflags = firstcharflags; + zeroreqchar = reqchar; + zeroreqcharflags = reqcharflags; + + /* \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 + ESC_g is returned only for these cases. So we don't need to check for < + or ' if the value is ESC_g. For the Perl syntax \g{n} the value is + -n, and for the Perl syntax \g{name} the result is ESC_k (as + that is a synonym for a named back reference). */ + + if (escape == ESC_g) + { + 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; + + /* These two statements stop the compiler for warning about possibly + unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In + fact, because we actually check for a number below, the paths that + would actually be in error are never taken. */ + + skipbytes = 0; + reset_bracount = FALSE; + + /* Test for a name */ + + if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS) + { + BOOL is_a_number = TRUE; + for (p = ptr + 1; *p != CHAR_NULL && *p != (pcre_uchar)terminator; p++) + { + if (!MAX_255(*p)) { is_a_number = FALSE; break; } + if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE; + if ((cd->ctypes[*p] & ctype_word) == 0) break; + } + if (*p != (pcre_uchar)terminator) + { + *errorcodeptr = ERR57; + break; + } + if (is_a_number) + { + ptr++; + goto HANDLE_NUMERICAL_RECURSION; + } + is_recurse = TRUE; + goto NAMED_REF_OR_RECURSE; + } + + /* Test a signed number in angle brackets or quotes. */ + + p = ptr + 2; + while (IS_DIGIT(*p)) p++; + if (*p != (pcre_uchar)terminator) + { + *errorcodeptr = ERR57; + break; + } + ptr++; + goto HANDLE_NUMERICAL_RECURSION; + } + + /* \k or \k'name' is a back reference by name (Perl syntax). + We also support \k{name} (.NET syntax). */ + + if (escape == 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)? + CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET; + goto NAMED_REF_OR_RECURSE; + } + + /* Back references are handled specially; must disable firstchar if + not set to cope with cases like (?=(\w+))\1: which would otherwise set + ':' later. */ + + if (escape < 0) + { + open_capitem *oc; + recno = -escape; + + HANDLE_REFERENCE: /* Come here from named backref handling */ + if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + previous = code; + *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; + + /* Check to see if this back reference is recursive, that it, it + is inside the group that it references. A flag is set so that the + group can be made atomic. */ + + for (oc = cd->open_caps; oc != NULL; oc = oc->next) + { + if (oc->number == recno) + { + oc->flag = TRUE; + break; + } + } + } + + /* So are Unicode property matches, if supported. */ + +#ifdef SUPPORT_UCP + else if (escape == ESC_P || escape == ESC_p) + { + BOOL negated; + unsigned int ptype = 0, pdata = 0; + if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr)) + goto FAILED; + previous = code; + *code++ = ((escape == ESC_p) != negated)? OP_PROP : OP_NOTPROP; + *code++ = ptype; + *code++ = pdata; + } +#else + + /* If Unicode properties are not supported, \X, \P, and \p are not + allowed. */ + + else if (escape == ESC_X || escape == ESC_P || escape == ESC_p) + { + *errorcodeptr = ERR45; + goto FAILED; + } +#endif + + /* 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. Note that \b and \B do a one-character + lookbehind. */ + + else + { + if ((escape == ESC_b || escape == ESC_B) && cd->max_lookbehind == 0) + cd->max_lookbehind = 1; +#ifdef SUPPORT_UCP + if (escape >= ESC_DU && escape <= ESC_wu) + { + nestptr = ptr + 1; /* Where to resume */ + ptr = substitutes[escape - ESC_DU] - 1; /* Just before substitute */ + } + 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 = (escape > ESC_b && escape < ESC_Z)? code : NULL; + *code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape; + } + } + continue; + } + + /* We have a data character whose value is in c. In UTF-8 mode it may have + a value > 127. We set its representation in the length/buffer, and then + handle it as a data character. */ + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) + mclength = PRIV(ord2utf)(c, mcbuffer); + else +#endif + + { + mcbuffer[0] = c; + mclength = 1; + } + goto ONE_CHAR; + + + /* ===================================================================*/ + /* Handle a literal character. It is guaranteed not to be whitespace or # + when the extended flag is set. If we are in UTF-8 mode, it may be a + multi-byte literal character. */ + + default: + NORMAL_CHAR: + mclength = 1; + mcbuffer[0] = c; + +#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 + in mclength. When not in UTF-8 mode, the length is always 1. */ + + ONE_CHAR: + previous = code; + + /* For caseless UTF-8 mode when UCP support is available, check whether + this character has more than one other case. If so, generate a special + OP_PROP item instead of OP_CHARI. */ + +#ifdef SUPPORT_UCP + if (utf && (options & PCRE_CASELESS) != 0) + { + GETCHAR(c, mcbuffer); + if ((c = UCD_CASESET(c)) != 0) + { + *code++ = OP_PROP; + *code++ = PT_CLIST; + *code++ = c; + if (firstcharflags == REQ_UNSET) firstcharflags = zerofirstcharflags = REQ_NONE; + break; + } + } +#endif + + /* Caseful matches, or not one of the multicase characters. */ + + *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 */ + + if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL) + cd->external_flags |= PCRE_HASCRORLF; + + /* 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 firstchar value alone, and don't change it on a zero + repeat. */ + + if (firstcharflags == REQ_UNSET) + { + zerofirstcharflags = REQ_NONE; + zeroreqchar = reqchar; + zeroreqcharflags = reqcharflags; + + /* 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) + { + firstchar = mcbuffer[0] | req_caseopt; + firstchar = mcbuffer[0]; + firstcharflags = req_caseopt; + + if (mclength != 1) + { + reqchar = code[-1]; + reqcharflags = cd->req_varyopt; + } + } + else firstcharflags = reqcharflags = REQ_NONE; + } + + /* firstchar was previously set; we can set reqchar only if the length is + 1 or the matching is caseful. */ + + else + { + zerofirstchar = firstchar; + zerofirstcharflags = firstcharflags; + zeroreqchar = reqchar; + zeroreqcharflags = reqcharflags; + if (mclength == 1 || req_caseopt == 0) + { + reqchar = code[-1]; + reqcharflags = req_caseopt | cd->req_varyopt; + } + } + + break; /* End of literal character handling */ + } + } /* end of big loop */ + + +/* Control never reaches here by falling through, only by a goto for all the +error states. Pass back the position in the pattern so that it can be displayed +to the user for diagnosing the error. */ + +FAILED: +*ptrptr = ptr; +return FALSE; +} + + + +/************************************************* +* Compile sequence of alternatives * +*************************************************/ + +/* 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. +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 + codeptr -> the address of the current code pointer + ptrptr -> the address of the current pattern pointer + errorcodeptr -> pointer to error code variable + lookbehind TRUE if this is a lookbehind assertion + reset_bracount TRUE to reset the count for each branch + skipbytes skip this many bytes at start (for brackets and OP_COND) + cond_depth depth of nesting for conditional subpatterns + firstcharptr place to put the first required character + firstcharflagsptr place to put the first character flags, or a negative number + reqcharptr place to put the last required character + reqcharflagsptr place to put the last required character flags, or a negative number + bcptr pointer to the chain of currently open branches + cd points to the data block with tables pointers etc. + lengthptr NULL during the real compile phase + points to length accumulator during pre-compile phase + +Returns: TRUE on success +*/ + +static BOOL +compile_regex(int options, pcre_uchar **codeptr, const pcre_uchar **ptrptr, + int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes, + int cond_depth, + pcre_uint32 *firstcharptr, pcre_int32 *firstcharflagsptr, + pcre_uint32 *reqcharptr, pcre_int32 *reqcharflagsptr, + branch_chain *bcptr, compile_data *cd, int *lengthptr) +{ +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; +pcre_uint32 firstchar, reqchar; +pcre_int32 firstcharflags, reqcharflags; +pcre_uint32 branchfirstchar, branchreqchar; +pcre_int32 branchfirstcharflags, branchreqcharflags; +int length; +unsigned int orig_bracount; +unsigned int max_bracount; +branch_chain bc; + +bc.outer = bcptr; +bc.current_branch = code; + +firstchar = reqchar = 0; +firstcharflags = reqcharflags = 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 +beginning. We accumulate in a local variable to save frequent testing of +lenthptr for NULL. We cannot do this by looking at the value of code at the +start and end of each alternative, because compiled items are discarded during +the pre-compile phase so that the work space is not exceeded. */ + +length = 2 + 2*LINK_SIZE + skipbytes; + +/* WARNING: If the above line is changed for any reason, you must also change +the code that abstracts option settings at the start of the pattern and makes +them global. It tests the value of length for (2 + 2*LINK_SIZE) in the +pre-compile phase to find out whether anything has yet been compiled or not. */ + +/* If this is a capturing subpattern, add to the chain of open capturing items +so that we can detect them if (*ACCEPT) is encountered. This is also used to +detect groups that contain recursive back references to themselves. 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) + { + capnumber = GET2(code, 1 + LINK_SIZE); + capitem.number = capnumber; + capitem.next = cd->open_caps; + capitem.flag = FALSE; + cd->open_caps = &capitem; + } + +/* Offset is set zero to mark that this bracket is still open */ + +PUT(code, 1, 0); +code += 1 + LINK_SIZE + skipbytes; + +/* Loop for each alternative branch */ + +orig_bracount = max_bracount = cd->bracount; +for (;;) + { + /* For a (?| group, reset the capturing bracket count so that each branch + uses the same numbers. */ + + if (reset_bracount) cd->bracount = orig_bracount; + + /* Set up dummy OP_REVERSE if lookbehind assertion */ + + if (lookbehind) + { + *code++ = OP_REVERSE; + reverse_count = code; + PUTINC(code, 0, 0); + length += 1 + LINK_SIZE; + } + + /* Now compile the branch; in the pre-compile phase its length gets added + into the length. */ + + if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstchar, + &branchfirstcharflags, &branchreqchar, &branchreqcharflags, &bc, + cond_depth, cd, (lengthptr == NULL)? NULL : &length)) + { + *ptrptr = ptr; + return FALSE; + } + + /* Keep the highest bracket count in case (?| was used and some branch + has fewer than the rest. */ + + if (cd->bracount > max_bracount) max_bracount = cd->bracount; + + /* In the real compile phase, there is some post-processing to be done. */ + + if (lengthptr == NULL) + { + /* 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) + { + firstchar = branchfirstchar; + firstcharflags = branchfirstcharflags; + reqchar = branchreqchar; + reqcharflags = branchreqcharflags; + } + + /* 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 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 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 (firstcharflags >= 0 && + (firstcharflags != branchfirstcharflags || firstchar != branchfirstchar)) + { + if (reqcharflags < 0) + { + reqchar = firstchar; + reqcharflags = firstcharflags; + } + firstcharflags = REQ_NONE; + } + + /* 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 (firstcharflags < 0 && branchfirstcharflags >= 0 && branchreqcharflags < 0) + { + branchreqchar = branchfirstchar; + branchreqcharflags = branchfirstcharflags; + } + + /* Now ensure that the reqchars match */ + + if (((reqcharflags & ~REQ_VARY) != (branchreqcharflags & ~REQ_VARY)) || + reqchar != branchreqchar) + reqcharflags = REQ_NONE; + else + { + reqchar = branchreqchar; + reqcharflags |= branchreqcharflags; /* To "or" REQ_VARY */ + } + } + + /* If lookbehind, check that this branch matches a fixed-length string, and + put the length into the OP_REVERSE item. Temporarily mark the end of the + branch with OP_END. If the branch contains OP_RECURSE, the result is -3 + because there may be forward references that we can't check here. Set a + flag to cause another lookbehind check at the end. Why not do it all at the + end? Because common, erroneous checks are picked up here and the offset of + the problem can be shown. */ + + if (lookbehind) + { + int fixed_length; + *code = OP_END; + fixed_length = find_fixedlength(last_branch, (options & PCRE_UTF8) != 0, + FALSE, cd); + DPRINTF(("fixed length = %d\n", fixed_length)); + if (fixed_length == -3) + { + cd->check_lookbehind = TRUE; + } + else if (fixed_length < 0) + { + *errorcodeptr = (fixed_length == -2)? ERR36 : + (fixed_length == -4)? ERR70: ERR25; + *ptrptr = ptr; + return FALSE; + } + else + { + if (fixed_length > cd->max_lookbehind) + cd->max_lookbehind = fixed_length; + PUT(reverse_count, 0, fixed_length); + } + } + } + + /* Reached end of expression, either ')' or end of pattern. In the real + compile phase, go back through the alternative branches and reverse the chain + 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. Return leaving the pointer at the terminating char. */ + + if (*ptr != CHAR_VERTICAL_LINE) + { + if (lengthptr == NULL) + { + int branch_length = (int)(code - last_branch); + do + { + int prev_length = GET(last_branch, 1); + PUT(last_branch, 1, branch_length); + branch_length = prev_length; + last_branch -= branch_length; + } + while (branch_length > 0); + } + + /* Fill in the ket */ + + *code = OP_KET; + PUT(code, 1, (int)(code - start_bracket)); + code += 1 + LINK_SIZE; + + /* If it was a capturing subpattern, check to see if it contained any + recursive back references. If so, we must wrap it in atomic brackets. + In any event, remove the block from the chain. */ + + if (capnumber > 0) + { + if (cd->open_caps->flag) + { + memmove(start_bracket + 1 + LINK_SIZE, start_bracket, + IN_UCHARS(code - start_bracket)); + *start_bracket = OP_ONCE; + code += 1 + LINK_SIZE; + PUT(start_bracket, 1, (int)(code - start_bracket)); + *code = OP_KET; + PUT(code, 1, (int)(code - start_bracket)); + code += 1 + LINK_SIZE; + length += 2 + 2*LINK_SIZE; + } + cd->open_caps = cd->open_caps->next; + } + + /* Retain the highest bracket number, in case resetting was used. */ + + cd->bracount = max_bracount; + + /* Set values to pass back */ + + *codeptr = code; + *ptrptr = ptr; + *firstcharptr = firstchar; + *firstcharflagsptr = firstcharflags; + *reqcharptr = reqchar; + *reqcharflagsptr = reqcharflags; + if (lengthptr != NULL) + { + if (OFLOW_MAX - *lengthptr < length) + { + *errorcodeptr = ERR20; + return FALSE; + } + *lengthptr += length; + } + return TRUE; + } + + /* Another branch follows. In the pre-compile phase, we can move the code + pointer back to where it was for the start of the first branch. (That is, + pretend that each branch is the only one.) + + In the real compile phase, insert an ALT node. Its length field points back + to the previous branch while the bracket remains open. At the end the chain + is reversed. It's done like this so that the start of the bracket has a + zero offset until it is closed, making it possible to detect recursion. */ + + if (lengthptr != NULL) + { + code = *codeptr + 1 + LINK_SIZE + skipbytes; + length += 1 + LINK_SIZE; + } + else + { + *code = OP_ALT; + PUT(code, 1, (int)(code - last_branch)); + bc.current_branch = last_branch = code; + code += 1 + LINK_SIZE; + } + + ptr++; + } +/* Control never reaches here */ +} + + + + +/************************************************* +* Check for anchored expression * +*************************************************/ + +/* 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 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 +into account the match offset". + +A branch is also implicitly anchored if it starts with .* and DOTALL is set, +because that will try the rest of the pattern at all possible matching points, +so there is no point trying again.... er .... + +.... except when the .* appears inside capturing parentheses, and there is a +subsequent back reference to those parentheses. We haven't enough information +to catch that case precisely. + +At first, the best we could do was to detect when .* was in capturing brackets +and the highest back reference was greater than or equal to that level. +However, by keeping a bitmap of the first 31 back references, we can catch some +of the more common cases more precisely. + +... A second exception is when the .* appears inside an atomic group, because +this prevents the number of characters it matches from being adjusted. + +Arguments: + code points to start of expression (the bracket) + 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 + cd points to the compile data block + atomcount atomic group level + +Returns: TRUE or FALSE +*/ + +static BOOL +is_anchored(register const pcre_uchar *code, unsigned int bracket_map, + compile_data *cd, int atomcount) +{ +do { + const pcre_uchar *scode = first_significant_code( + code + PRIV(OP_lengths)[*code], FALSE); + register int op = *scode; + + /* Non-capturing brackets */ + + if (op == OP_BRA || op == OP_BRAPOS || + op == OP_SBRA || op == OP_SBRAPOS) + { + if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE; + } + + /* Capturing brackets */ + + 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, new_map, cd, atomcount)) return FALSE; + } + + /* Positive forward assertions and conditions */ + + else if (op == OP_ASSERT || op == OP_COND) + { + if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE; + } + + /* Atomic groups */ + + else if (op == OP_ONCE || op == OP_ONCE_NC) + { + if (!is_anchored(scode, bracket_map, cd, atomcount + 1)) + return FALSE; + } + + /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and + it isn't in brackets that are or may be referenced or inside an atomic + group. */ + + else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR || + op == OP_TYPEPOSSTAR)) + { + if (scode[1] != OP_ALLANY || (bracket_map & cd->backref_map) != 0 || + atomcount > 0 || cd->had_pruneorskip) + return FALSE; + } + + /* Check for explicit anchoring */ + + 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 */ +return TRUE; +} + + + +/************************************************* +* Check for starting with ^ or .* * +*************************************************/ + +/* This is called to find out if every branch starts with ^ or .* so that +"first char" processing can be done to speed things up in multiline +matching and for non-DOTALL patterns that start with .* (which must start at +the beginning or after \n). As in the case of is_anchored() (see above), we +have to take account of back references to capturing brackets that contain .* +because in that case we can't make the assumption. Also, the appearance of .* +inside atomic brackets or in a pattern that contains *PRUNE or *SKIP does not +count, because once again the assumption no longer holds. + +Arguments: + code points to start of expression (the bracket) + 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 + cd points to the compile data + atomcount atomic group level + +Returns: TRUE or FALSE +*/ + +static BOOL +is_startline(const pcre_uchar *code, unsigned int bracket_map, + compile_data *cd, int atomcount) +{ +do { + 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 + conditional assertion *and* what follows the condition must satisfy the test + for start of line. Other kinds of condition fail. Note that there may be an + auto-callout at the start of a condition. */ + + if (op == OP_COND) + { + scode += 1 + LINK_SIZE; + if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT]; + switch (*scode) + { + case OP_CREF: + case OP_NCREF: + case OP_RREF: + case OP_NRREF: + case OP_DEF: + return FALSE; + + default: /* Assertion */ + if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE; + do scode += GET(scode, 1); while (*scode == OP_ALT); + scode += 1 + LINK_SIZE; + break; + } + scode = first_significant_code(scode, FALSE); + op = *scode; + } + + /* Non-capturing brackets */ + + if (op == OP_BRA || op == OP_BRAPOS || + op == OP_SBRA || op == OP_SBRAPOS) + { + if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE; + } + + /* Capturing brackets */ + + 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_startline(scode, new_map, cd, atomcount)) return FALSE; + } + + /* Positive forward assertions */ + + else if (op == OP_ASSERT) + { + if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE; + } + + /* Atomic brackets */ + + else if (op == OP_ONCE || op == OP_ONCE_NC) + { + if (!is_startline(scode, bracket_map, cd, atomcount + 1)) return FALSE; + } + + /* .* means "start at start or after \n" if it isn't in atomic brackets or + brackets that may be referenced, as long as the pattern does not contain + *PRUNE or *SKIP, because these break the feature. Consider, for example, + /.*?a(*PRUNE)b/ with the subject "aab", which matches "ab", i.e. not at the + start of a line. */ + + else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR) + { + if (scode[1] != OP_ANY || (bracket_map & cd->backref_map) != 0 || + atomcount > 0 || cd->had_pruneorskip) + return FALSE; + } + + /* Check for explicit circumflex; anything else gives a FALSE result. Note + in particular that this includes atomic brackets OP_ONCE and OP_ONCE_NC + because the number of characters matched by .* cannot be adjusted inside + them. */ + + else if (op != OP_CIRC && op != OP_CIRCM) return FALSE; + + /* Move on to the next alternative */ + + code += GET(code, 1); + } +while (*code == OP_ALT); /* Loop for each alternative */ +return TRUE; +} + + + +/************************************************* +* Check for asserted fixed first char * +*************************************************/ + +/* During compilation, the "first char" settings from forward assertions are +discarded, because they can cause conflicts with actual literals that follow. +However, if we end up without a first char setting for an unanchored pattern, +it is worth scanning the regex to see if there is an initial asserted first +char. If all branches start with the same asserted char, or with a bracket all +of whose alternatives start with the same asserted char (recurse ad lib), then +we return that char, otherwise -1. + +Arguments: + code points to start of expression (the bracket) + flags points to the first char flags, or to REQ_NONE + inassert TRUE if in an assertion + +Returns: the fixed first char, or 0 with REQ_NONE in flags +*/ + +static pcre_uint32 +find_firstassertedchar(const pcre_uchar *code, pcre_int32 *flags, + BOOL inassert) +{ +register pcre_uint32 c = 0; +int cflags = REQ_NONE; + +*flags = REQ_NONE; +do { + pcre_uint32 d; + int dflags; + 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 pcre_uchar op = *scode; + + switch(op) + { + default: + return 0; + + 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: + d = find_firstassertedchar(scode, &dflags, op == OP_ASSERT); + if (dflags < 0) + return 0; + if (cflags < 0) { c = d; cflags = dflags; } else if (c != d || cflags != dflags) return 0; + break; + + case OP_EXACT: + scode += IMM2_SIZE; + /* Fall through */ + + case OP_CHAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_POSPLUS: + if (!inassert) return 0; + if (cflags < 0) { c = scode[1]; cflags = 0; } + else if (c != scode[1]) return 0; + break; + + case OP_EXACTI: + scode += IMM2_SIZE; + /* Fall through */ + + case OP_CHARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + if (!inassert) return 0; + if (cflags < 0) { c = scode[1]; cflags = REQ_CASELESS; } + else if (c != scode[1]) return 0; + break; + } + + code += GET(code, 1); + } +while (*code == OP_ALT); + +*flags = cflags; +return c; +} + + + +/************************************************* +* Compile a Regular Expression * +*************************************************/ + +/* This function takes a string and returns a pointer to a block of store +holding a compiled version of the expression. The original API for this +function had no error code return variable; it is retained for backwards +compatibility. The new function is given a new name. + +Arguments: + pattern the regular expression + options various option bits + errorcodeptr pointer to error code variable (pcre_compile2() only) + can be NULL if you don't want a code value + errorptr pointer to pointer to error text + erroroffset ptr offset in pattern where error was detected + tables pointer to character tables or NULL + +Returns: pointer to compiled data block, or NULL on error, + with errorptr and erroroffset set +*/ + +#if defined 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) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION +pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errorptr, + int *erroroffset, const unsigned char *tables) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN pcre32 * PCRE_CALL_CONVENTION +pcre32_compile(PCRE_SPTR32 pattern, int options, const char **errorptr, + int *erroroffset, const unsigned char *tables) +#endif +{ +#if defined COMPILE_PCRE8 +return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables); +#elif defined COMPILE_PCRE16 +return pcre16_compile2(pattern, options, NULL, errorptr, erroroffset, tables); +#elif defined COMPILE_PCRE32 +return pcre32_compile2(pattern, options, NULL, errorptr, erroroffset, tables); +#endif +} + + +#if defined 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) +#elif defined COMPILE_PCRE16 +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) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN pcre32 * PCRE_CALL_CONVENTION +pcre32_compile2(PCRE_SPTR32 pattern, int options, int *errorcodeptr, + const char **errorptr, int *erroroffset, const unsigned char *tables) +#endif +{ +REAL_PCRE *re; +int length = 1; /* For final END opcode */ +pcre_uint32 firstchar, reqchar; +pcre_int32 firstcharflags, reqcharflags; +int newline; +int errorcode = 0; +int skipatstart = 0; +BOOL utf; +size_t size; +pcre_uchar *code; +const pcre_uchar *codestart; +const pcre_uchar *ptr; +compile_data compile_block; +compile_data *cd = &compile_block; + +/* This space is used for "compiling" into during the first phase, when we are +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. That may overflow, in which case +new memory is obtained from malloc(). */ + +pcre_uchar cworkspace[COMPILE_WORK_SIZE]; + +/* Set this early so that early errors get offset 0. */ + +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 +pointer. */ + +if (errorptr == NULL) + { + if (errorcodeptr != NULL) *errorcodeptr = 99; + return NULL; + } + +*errorptr = NULL; +if (errorcodeptr != NULL) *errorcodeptr = ERR0; + +/* However, we can give a message for this error */ + +if (erroroffset == NULL) + { + errorcode = ERR16; + goto PCRE_EARLY_ERROR_RETURN2; + } + +*erroroffset = 0; + +/* Set up pointers to the individual character tables */ + +if (tables == NULL) tables = PRIV(default_tables); +cd->lcc = tables + lcc_offset; +cd->fcc = tables + fcc_offset; +cd->cbits = tables + cbits_offset; +cd->ctypes = tables + ctypes_offset; + +/* Check that all undefined public option bits are zero */ + +if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0) + { + errorcode = ERR17; + goto PCRE_EARLY_ERROR_RETURN; + } + +/* Check for global one-time settings at the start of the pattern, and remember +the offset for later. */ + +while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS && + ptr[skipatstart+1] == CHAR_ASTERISK) + { + int newnl = 0; + int newbsr = 0; + +/* For completeness and backward compatibility, (*UTFn) is supported in the +relevant libraries, but (*UTF) is generic and always supported. Note that +PCRE_UTF8 == PCRE_UTF16 == PCRE_UTF32. */ + +#ifdef COMPILE_PCRE8 + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF8_RIGHTPAR, 5) == 0) + { skipatstart += 7; options |= PCRE_UTF8; continue; } +#endif +#ifdef COMPILE_PCRE16 + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF16_RIGHTPAR, 6) == 0) + { skipatstart += 8; options |= PCRE_UTF16; continue; } +#endif +#ifdef COMPILE_PCRE32 + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF32_RIGHTPAR, 6) == 0) + { skipatstart += 8; options |= PCRE_UTF32; continue; } +#endif + + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 4) == 0) + { skipatstart += 6; options |= PCRE_UTF8; continue; } + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0) + { skipatstart += 6; options |= PCRE_UCP; continue; } + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0) + { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; } + + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0) + { skipatstart += 5; newnl = PCRE_NEWLINE_CR; } + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0) + { skipatstart += 5; newnl = PCRE_NEWLINE_LF; } + 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_UC_C8(ptr+skipatstart+2, STRING_ANY_RIGHTPAR, 4) == 0) + { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; } + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANYCRLF_RIGHTPAR, 8) == 0) + { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; } + + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0) + { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; } + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_UNICODE_RIGHTPAR, 12) == 0) + { skipatstart += 14; newbsr = PCRE_BSR_UNICODE; } + + if (newnl != 0) + options = (options & ~PCRE_NEWLINE_BITS) | newnl; + else if (newbsr != 0) + options = (options & ~(PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) | newbsr; + else break; + } + +/* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */ +utf = (options & PCRE_UTF8) != 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) + { +#if defined COMPILE_PCRE8 + errorcode = ERR44; +#elif defined COMPILE_PCRE16 + errorcode = ERR74; +#elif defined COMPILE_PCRE32 + errorcode = ERR77; +#endif + goto PCRE_EARLY_ERROR_RETURN2; + } +#else +if (utf) + { + errorcode = ERR32; + goto PCRE_EARLY_ERROR_RETURN; + } +#endif + +/* Can't support UCP unless PCRE has been compiled to include the code. */ + +#ifndef SUPPORT_UCP +if ((options & PCRE_UCP) != 0) + { + errorcode = ERR67; + goto PCRE_EARLY_ERROR_RETURN; + } +#endif + +/* Check validity of \R options. */ + +if ((options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == + (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) + { + errorcode = ERR56; + goto PCRE_EARLY_ERROR_RETURN; + } + +/* Handle different types of newline. The three bits give seven cases. The +current code allows for fixed one- or two-byte sequences, plus "any" and +"anycrlf". */ + +switch (options & PCRE_NEWLINE_BITS) + { + case 0: newline = NEWLINE; break; /* Build-time default */ + case PCRE_NEWLINE_CR: newline = CHAR_CR; break; + case PCRE_NEWLINE_LF: newline = CHAR_NL; break; + case PCRE_NEWLINE_CR+ + PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break; + case PCRE_NEWLINE_ANY: newline = -1; break; + case PCRE_NEWLINE_ANYCRLF: newline = -2; break; + default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN; + } + +if (newline == -2) + { + cd->nltype = NLTYPE_ANYCRLF; + } +else if (newline < 0) + { + cd->nltype = NLTYPE_ANY; + } +else + { + cd->nltype = NLTYPE_FIXED; + if (newline > 255) + { + cd->nllen = 2; + cd->nl[0] = (newline >> 8) & 255; + cd->nl[1] = newline & 255; + } + else + { + cd->nllen = 1; + cd->nl[0] = newline; + } + } + +/* Maximum back reference and backref bitmap. The bitmap records up to 31 back +references to help in deciding whether (.*) can be treated as anchored or not. +*/ + +cd->top_backref = 0; +cd->backref_map = 0; + +/* Reflect pattern for debugging output */ + +DPRINTF(("------------------------------------------------------------------\n")); +#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 +argument to compile_regex(). We pass a block of workspace (cworkspace) for it +to compile parts of the pattern into; the compiled code is discarded when it is +no longer needed, so hopefully this workspace will never overflow, though there +is a test for its doing so. */ + +cd->bracount = cd->final_bracount = 0; +cd->names_found = 0; +cd->name_entry_size = 0; +cd->name_table = NULL; +cd->start_code = cworkspace; +cd->hwm = cworkspace; +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; + +/* Now do the pre-compile. On error, errorcode will be set non-zero, so we +don't need to look at the result of the function here. The initial options have +been put into the cd block so that they can be changed if an option setting is +found within the regex right at the beginning. Bringing initial option settings +outside can help speed up starting point checks. */ + +ptr += skipatstart; +code = cworkspace; +*code = OP_BRA; +(void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE, + FALSE, 0, 0, &firstchar, &firstcharflags, &reqchar, &reqcharflags, NULL, + cd, &length); +if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN; + +DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, + (int)(cd->hwm - cworkspace))); + +if (length > MAX_PATTERN_SIZE) + { + errorcode = ERR20; + goto PCRE_EARLY_ERROR_RETURN; + } + +/* Compute the size of data block needed and get it, either from malloc or +externally provided function. Integer overflow should no longer be possible +because nowadays we limit the maximum value of cd->names_found and +cd->name_entry_size. */ + +size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar); +re = (REAL_PCRE *)(PUBL(malloc))(size); + +if (re == NULL) + { + errorcode = ERR21; + goto PCRE_EARLY_ERROR_RETURN; + } + +/* Put in the magic number, and save the sizes, initial options, internal +flags, and character table pointer. NULL is used for the default character +tables. The nullpad field is at the end; it's there to help in the case when a +regex compiled on a system with 4-byte pointers is run on another with 8-byte +pointers. */ + +re->magic_number = MAGIC_NUMBER; +re->size = (int)size; +re->options = cd->external_options; +re->flags = cd->external_flags; +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 == PRIV(default_tables))? NULL : tables; +re->nullpad = NULL; +#ifdef COMPILE_PCRE32 +re->dummy1 = re->dummy2 = 0; +#endif + +/* The starting points of the name/number translation table and of the code are +passed around in the compile data block. The start/end pattern and initial +options are already set from the pre-compile phase, as is the name_entry_size +field. Reset the bracket count and the names_found field. Also reset the hwm +field; this time it's used for remembering forward references to subpatterns. +*/ + +cd->final_bracount = cd->bracount; /* Save for checking forward references */ +cd->assert_depth = 0; +cd->bracount = 0; +cd->max_lookbehind = 0; +cd->names_found = 0; +cd->name_table = (pcre_uchar *)re + re->name_table_offset; +codestart = cd->name_table + re->name_entry_size * re->name_count; +cd->start_code = codestart; +cd->hwm = (pcre_uchar *)(cd->start_workspace); +cd->req_varyopt = 0; +cd->had_accept = FALSE; +cd->had_pruneorskip = FALSE; +cd->check_lookbehind = FALSE; +cd->open_caps = NULL; + +/* Set up a starting, non-extracting bracket, then compile the expression. On +error, errorcode will be set non-zero, so we don't need to look at the result +of the function here. */ + +ptr = (const pcre_uchar *)pattern + skipatstart; +code = (pcre_uchar *)codestart; +*code = OP_BRA; +(void)compile_regex(re->options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0, + &firstchar, &firstcharflags, &reqchar, &reqcharflags, NULL, cd, NULL); +re->top_bracket = cd->bracount; +re->top_backref = cd->top_backref; +re->max_lookbehind = cd->max_lookbehind; +re->flags = cd->external_flags | PCRE_MODE; + +if (cd->had_accept) + { + reqchar = 0; /* Must disable after (*ACCEPT) */ + reqcharflags = REQ_NONE; + } + +/* If not reached end of pattern on success, there's an excess bracket. */ + +if (errorcode == 0 && *ptr != CHAR_NULL) errorcode = ERR22; + +/* Fill in the terminating state and check for disastrous overflow, but +if debugging, leave the test till after things are printed out. */ + +*code++ = OP_END; + +#ifndef PCRE_DEBUG +if (code - codestart > length) errorcode = ERR23; +#endif + +#ifdef SUPPORT_VALGRIND +/* If the estimated length exceeds the really used length, mark the extra +allocated memory as unadressable, so that any out-of-bound reads can be +detected. */ +VALGRIND_MAKE_MEM_NOACCESS(code, (length - (code - codestart)) * sizeof(pcre_uchar)); +#endif + +/* Fill in any forward references that are required. There may be repeated +references; optimize for them, as searching a large regex takes time. */ + +if (cd->hwm > cd->start_workspace) + { + 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. */ + +if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15; + +/* If there were any lookbehind assertions that contained OP_RECURSE +(recursions or subroutine calls), a flag is set for them to be checked here, +because they may contain forward references. Actual recursions cannot be fixed +length, but subroutine calls can. It is done like this so that those without +OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The +exceptional ones forgo this. We scan the pattern to check that they are fixed +length, and set their lengths. */ + +if (cd->check_lookbehind) + { + 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 = (pcre_uchar *)PRIV(find_bracket)(codestart, utf, -1); + cc != NULL; + cc = (pcre_uchar *)PRIV(find_bracket)(cc, utf, -1)) + { + if (GET(cc, 1) == 0) + { + int fixed_length; + 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 & PCRE_UTF8) != 0, TRUE, + cd); + *be = end_op; + DPRINTF(("fixed length = %d\n", fixed_length)); + if (fixed_length < 0) + { + 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; + } + } + +/* Failed to compile, or error while post-processing */ + +if (errorcode != 0) + { + (PUBL(free))(re); + PCRE_EARLY_ERROR_RETURN: + *erroroffset = (int)(ptr - (const pcre_uchar *)pattern); + PCRE_EARLY_ERROR_RETURN2: + *errorptr = find_error_text(errorcode); + if (errorcodeptr != NULL) *errorcodeptr = errorcode; + return NULL; + } + +/* If the anchored option was not passed, set the flag if we can determine that +the pattern is anchored by virtue of ^ characters or \A or anything else, such +as starting with non-atomic .* when DOTALL is set and there are no occurrences +of *PRUNE or *SKIP. + +Otherwise, if we know what the first byte has to be, save it, because that +speeds up unanchored matches no end. If not, see if we can set the +PCRE_STARTLINE flag. This is helpful for multiline matches when all branches +start with ^. and also when all branches start with non-atomic .* for +non-DOTALL matches when *PRUNE and SKIP are not present. */ + +if ((re->options & PCRE_ANCHORED) == 0) + { + if (is_anchored(codestart, 0, cd, 0)) re->options |= PCRE_ANCHORED; + else + { + if (firstcharflags < 0) + firstchar = find_firstassertedchar(codestart, &firstcharflags, FALSE); + if (firstcharflags >= 0) /* Remove caseless flag for non-caseable chars */ + { +#if defined COMPILE_PCRE8 + re->first_char = firstchar & 0xff; +#elif defined COMPILE_PCRE16 + re->first_char = firstchar & 0xffff; +#elif defined COMPILE_PCRE32 + re->first_char = firstchar; +#endif + if ((firstcharflags & 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, 0)) re->flags |= PCRE_STARTLINE; + } + } + +/* For an anchored pattern, we use the "required byte" only if it follows a +variable length item in the regex. Remove the caseless flag for non-caseable +bytes. */ + +if (reqcharflags >= 0 && + ((re->options & PCRE_ANCHORED) == 0 || (reqcharflags & REQ_VARY) != 0)) + { +#if defined COMPILE_PCRE8 + re->req_char = reqchar & 0xff; +#elif defined COMPILE_PCRE16 + re->req_char = reqchar & 0xffff; +#elif defined COMPILE_PCRE32 + re->req_char = reqchar; +#endif + if ((reqcharflags & 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; + } + +/* Print out the compiled data if debugging is enabled. This is never the +case when building a production library. */ + +#ifdef PCRE_DEBUG +printf("Length = %d top_bracket = %d top_backref = %d\n", + length, re->top_bracket, re->top_backref); + +printf("Options=%08x\n", re->options); + +if ((re->flags & PCRE_FIRSTSET) != 0) + { + 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) + { + 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); + } + +#if defined COMPILE_PCRE8 +pcre_printint((pcre *)re, stdout, TRUE); +#elif defined COMPILE_PCRE16 +pcre16_printint((pcre *)re, stdout, TRUE); +#elif defined COMPILE_PCRE32 +pcre32_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) + { + (PUBL(free))(re); + *errorptr = find_error_text(ERR23); + *erroroffset = ptr - (pcre_uchar *)pattern; + if (errorcodeptr != NULL) *errorcodeptr = ERR23; + return NULL; + } +#endif /* PCRE_DEBUG */ + +#if defined COMPILE_PCRE8 +return (pcre *)re; +#elif defined COMPILE_PCRE16 +return (pcre16 *)re; +#elif defined COMPILE_PCRE32 +return (pcre32 *)re; +#endif +} + +/* End of pcre_compile.c */ diff --git a/tools/pcre/pcre_config.c b/tools/pcre/pcre_config.c new file mode 100644 index 00000000..3d5689f6 --- /dev/null +++ b/tools/pcre/pcre_config.c @@ -0,0 +1,186 @@ +/************************************************* +* 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 the external function pcre_config(). */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Keep the original link size. */ +static int real_link_size = LINK_SIZE; + +#include "pcre_internal.h" + + +/************************************************* +* Return info about what features are configured * +*************************************************/ + +/* This function has an extensible interface so that additional items can be +added compatibly. + +Arguments: + what what information is required + where where to put the information + +Returns: 0 if data returned, negative on error +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre_config(int what, void *where) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_config(int what, void *where) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_config(int what, void *where) +#endif +{ +switch (what) + { + case PCRE_CONFIG_UTF8: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + *((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 || defined COMPILE_PCRE32 + *((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_UTF32: +#if defined COMPILE_PCRE8 || 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_UNICODE_PROPERTIES: +#ifdef SUPPORT_UCP + *((int *)where) = 1; +#else + *((int *)where) = 0; +#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; + + case PCRE_CONFIG_BSR: +#ifdef BSR_ANYCRLF + *((int *)where) = 1; +#else + *((int *)where) = 0; +#endif + break; + + case PCRE_CONFIG_LINK_SIZE: + *((int *)where) = real_link_size; + break; + + case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD: + *((int *)where) = POSIX_MALLOC_THRESHOLD; + break; + + case PCRE_CONFIG_MATCH_LIMIT: + *((unsigned long int *)where) = MATCH_LIMIT; + break; + + case PCRE_CONFIG_MATCH_LIMIT_RECURSION: + *((unsigned long int *)where) = MATCH_LIMIT_RECURSION; + break; + + case PCRE_CONFIG_STACKRECURSE: +#ifdef NO_RECURSE + *((int *)where) = 0; +#else + *((int *)where) = 1; +#endif + break; + + default: return PCRE_ERROR_BADOPTION; + } + +return 0; +} + +/* End of pcre_config.c */ diff --git a/tools/pcre/pcre_dfa_exec.c b/tools/pcre/pcre_dfa_exec.c new file mode 100644 index 00000000..91fb730b --- /dev/null +++ b/tools/pcre/pcre_dfa_exec.c @@ -0,0 +1,3582 @@ +/************************************************* +* 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 (but see +below for why this module is different). + + 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 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 +applications. */ + + +/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved +the performance of his patterns greatly. I could not use it as it stood, as it +was not thread safe, and made assumptions about pattern sizes. Also, it caused +test 7 to loop, and test 9 to crash with a segfault. + +The issue is the check for duplicate states, which is done by a simple linear +search up the state list. (Grep for "duplicate" below to find the code.) For +many patterns, there will never be many states active at one time, so a simple +linear search is fine. In patterns that have many active states, it might be a +bottleneck. The suggested code used an indexing scheme to remember which states +had previously been used for each character, and avoided the linear search when +it knew there was no chance of a duplicate. This was implemented when adding +states to the state lists. + +I wrote some thread-safe, not-limited code to try something similar at the time +of checking for duplicates (instead of when adding states), using index vectors +on the stack. It did give a 13% improvement with one specially constructed +pattern for certain subject strings, but on other strings and on many of the +simpler patterns in the test suite it did worse. The major problem, I think, +was the extra time to initialize the index. This had to be done for each call +of internal_dfa_exec(). (The supplied patch used a static vector, initialized +only once - I suspect this was the cause of the problems with the tests.) + +Overall, I concluded that the gains in some cases did not outweigh the losses +in others, so I abandoned this code. */ + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define NLBLOCK md /* Block containing newline information */ +#define PSSTART start_subject /* Field containing processed string start */ +#define PSEND end_subject /* Field containing processed string end */ + +#include "pcre_internal.h" + + +/* For use to indent debugging output */ + +#define SP " " + + +/************************************************* +* Code parameters and static tables * +*************************************************/ + +/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes +into others, under special conditions. A gap of 20 between the blocks should be +enough. The resulting opcodes don't have to be less than 256 because they are +never stored, so we push them well clear of the normal opcodes. */ + +#define OP_PROP_EXTRA 300 +#define OP_EXTUNI_EXTRA 320 +#define OP_ANYNL_EXTRA 340 +#define OP_HSPACE_EXTRA 360 +#define OP_VSPACE_EXTRA 380 + + +/* This table identifies those opcodes that are followed immediately by a +character that is to be tested in some way. This makes it possible to +centralize the loading of these characters. In the case of Type * etc, the +"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a +small value. Non-zero values in the table are the offsets from the opcode where +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 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 */ + 0, 0, 0, /* Any, AllAny, Anybyte */ + 0, 0, /* \P, \p */ + 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */ + 0, /* \X */ + 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */ + 1, /* Char */ + 1, /* Chari */ + 1, /* not */ + 1, /* noti */ + /* Positive single-char repeats */ + 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ + 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 *, *?, +, +?, ?, ?? */ + 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 *, *?, +, +?, ?, ?? */ + 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 */ + 0, /* CLASS */ + 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, 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, 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 +remember the fact that a character could have been inspected when the end of +the subject is reached. ***NOTE*** If the start of this table is modified, the +two tables that follow must also be modified. */ + +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 */ + 1, 1, 1, /* Any, AllAny, Anybyte */ + 1, 1, /* \P, \p */ + 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ + 1, /* \X */ + 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */ + 1, /* Char */ + 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 */ + 1, 1, 1, 1, /* Type *+, ++, ?+, upto+ */ + /* Character class & ref repeats */ + 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ + 1, 1, /* CRRANGE, CRMINRANGE */ + 1, /* CLASS */ + 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, 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, 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 pcre_uint8 toptable1[] = { + 0, 0, 0, 0, 0, 0, + ctype_digit, ctype_digit, + ctype_space, ctype_space, + ctype_word, ctype_word, + 0, 0 /* OP_ANY, OP_ALLANY */ +}; + +static const pcre_uint8 toptable2[] = { + 0, 0, 0, 0, 0, 0, + ctype_digit, 0, + ctype_space, 0, + ctype_word, 0, + 1, 1 /* OP_ANY, OP_ALLANY */ +}; + + +/* Structure for holding data about a particular state, which is in effect the +current data for an active path through the match tree. It must consist +entirely of ints because the working vector we are passed, and which we put +these structures in, is a vector of ints. */ + +typedef struct stateblock { + int offset; /* Offset to opcode */ + int count; /* Count for repeats */ + int data; /* Some use extra data */ +} stateblock; + +#define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int)) + + +#ifdef PCRE_DEBUG +/************************************************* +* Print character string * +*************************************************/ + +/* Character string printing function for debugging. + +Arguments: + p points to string + length number of bytes + f where to print + +Returns: nothing +*/ + +static void +pchars(const pcre_uchar *p, int length, FILE *f) +{ +pcre_uint32 c; +while (length-- > 0) + { + if (isprint(c = *(p++))) + fprintf(f, "%c", c); + else + fprintf(f, "\\x{%02x}", c); + } +} +#endif + + + +/************************************************* +* Execute a Regular Expression - DFA engine * +*************************************************/ + +/* This internal function applies a compiled pattern to a subject string, +starting at a given point, using a DFA engine. This function is called from the +external one, possibly multiple times if the pattern is not anchored. The +function calls itself recursively for some kinds of subpattern. + +Arguments: + md the match_data block with fixed information + this_start_code the opening bracket of this subexpression's code + current_subject where we currently are in the subject string + start_offset start offset in the subject string + offsets vector to contain the matching string offsets + offsetcount size of same + workspace vector of workspace + wscount size of same + rlevel function call recursion level + +Returns: > 0 => number of match offset pairs placed in offsets + = 0 => offsets overflowed; longest matches are present + -1 => failed to match + < -1 => some kind of unexpected problem + +The following macros are used for adding states to the two state vectors (one +for the current character, one for the following character). */ + +#define ADD_ACTIVE(x,y) \ + if (active_count++ < wscount) \ + { \ + next_active_state->offset = (x); \ + next_active_state->count = (y); \ + next_active_state++; \ + DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \ + } \ + else return PCRE_ERROR_DFA_WSSIZE + +#define ADD_ACTIVE_DATA(x,y,z) \ + if (active_count++ < wscount) \ + { \ + next_active_state->offset = (x); \ + next_active_state->count = (y); \ + next_active_state->data = (z); \ + next_active_state++; \ + DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \ + } \ + else return PCRE_ERROR_DFA_WSSIZE + +#define ADD_NEW(x,y) \ + if (new_count++ < wscount) \ + { \ + next_new_state->offset = (x); \ + next_new_state->count = (y); \ + next_new_state++; \ + DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \ + } \ + else return PCRE_ERROR_DFA_WSSIZE + +#define ADD_NEW_DATA(x,y,z) \ + if (new_count++ < wscount) \ + { \ + next_new_state->offset = (x); \ + next_new_state->count = (y); \ + next_new_state->data = (z); \ + next_new_state++; \ + DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d) line %d\n", rlevel*2-2, SP, \ + (x), (y), (z), __LINE__)); \ + } \ + else return PCRE_ERROR_DFA_WSSIZE + +/* And now, here is the code */ + +static int +internal_dfa_exec( + dfa_match_data *md, + const pcre_uchar *this_start_code, + const pcre_uchar *current_subject, + int start_offset, + int *offsets, + int offsetcount, + int *workspace, + int wscount, + int rlevel) +{ +stateblock *active_states, *new_states, *temp_states; +stateblock *next_active_state, *next_new_state; + +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 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_UTF +BOOL utf = (md->poptions & PCRE_UTF8) != 0; +#else +BOOL utf = FALSE; +#endif + +BOOL reset_could_continue = FALSE; + +rlevel++; +offsetcount &= (-2); + +wscount -= 2; +wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) / + (2 * INTS_PER_STATEBLOCK); + +DPRINTF(("\n%.*s---------------------\n" + "%.*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; +fcc = md->tables + fcc_offset; + +match_count = PCRE_ERROR_NOMATCH; /* A negative number */ + +active_states = (stateblock *)(workspace + 2); +next_new_state = new_states = active_states + wscount; +new_count = 0; + +first_op = this_start_code + 1 + LINK_SIZE + + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || + *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 +makes is possible to use this function recursively, when we want to stop at a +matching internal ket rather than at the end. + +If the first opcode in the first alternative is OP_REVERSE, we are dealing with +a backward assertion. In that case, we have to find out the maximum amount to +move back, and set up each alternative appropriately. */ + +if (*first_op == OP_REVERSE) + { + int max_back = 0; + int gone_back; + + end_code = this_start_code; + do + { + int back = GET(end_code, 2+LINK_SIZE); + if (back > max_back) max_back = back; + end_code += GET(end_code, 1); + } + while (*end_code == OP_ALT); + + /* 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_UTF + /* In character mode we have to step back character by character */ + + if (utf) + { + for (gone_back = 0; gone_back < max_back; gone_back++) + { + if (current_subject <= start_subject) break; + current_subject--; + ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--); + } + } + else +#endif + + /* In byte-mode we can do this quickly. */ + + { + gone_back = (current_subject - max_back < start_subject)? + (int)(current_subject - start_subject) : max_back; + current_subject -= gone_back; + } + + /* Save the earliest consulted character */ + + if (current_subject < md->start_used_ptr) + md->start_used_ptr = current_subject; + + /* Now we can process the individual branches. */ + + end_code = this_start_code; + do + { + int back = GET(end_code, 2+LINK_SIZE); + if (back <= gone_back) + { + int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE); + ADD_NEW_DATA(-bstate, 0, gone_back - back); + } + end_code += GET(end_code, 1); + } + while (*end_code == OP_ALT); + } + +/* This is the code for a "normal" subpattern (not a backward assertion). The +start of a whole pattern is always one of these. If we are at the top level, +we may be asked to restart matching from the same point that we reached for a +previous partial match. We still have to scan through the top-level branches to +find the end state. */ + +else + { + end_code = this_start_code; + + /* Restarting */ + + if (rlevel == 1 && (md->moptions & PCRE_DFA_RESTART) != 0) + { + do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT); + new_count = workspace[1]; + if (!workspace[0]) + memcpy(new_states, active_states, new_count * sizeof(stateblock)); + } + + /* Not restarting */ + + else + { + int length = 1 + LINK_SIZE + + ((*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); + end_code += GET(end_code, 1); + length = 1 + LINK_SIZE; + } + while (*end_code == OP_ALT); + } + } + +workspace[0] = 0; /* Bit indicating which vector is current */ + +DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, (int)(end_code - start_code))); + +/* Loop for scanning the subject */ + +ptr = current_subject; +for (;;) + { + int i, j; + int clen, dlen; + pcre_uint32 c, d; + int forced_fail = 0; + 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. */ + + temp_states = active_states; + active_states = new_states; + new_states = temp_states; + active_count = new_count; + new_count = 0; + + workspace[0] ^= 1; /* Remember for the restarting feature */ + workspace[1] = active_count; + +#ifdef PCRE_DEBUG + printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP); + pchars(ptr, STRLEN_UC(ptr), stdout); + printf("\"\n"); + + printf("%.*sActive states: ", rlevel*2-2, SP); + for (i = 0; i < active_count; i++) + printf("%d/%d ", active_states[i].offset, active_states[i].count); + printf("\n"); +#endif + + /* Set the pointers for adding new states */ + + next_active_state = active_states + active_count; + next_new_state = new_states; + + /* Load the current character from the subject outside the loop, as many + different states may want to look at it, and we assume that at least one + will. */ + + if (ptr < end_subject) + { + clen = 1; /* Number of data items in the character */ +#ifdef SUPPORT_UTF + GETCHARLENTEST(c, ptr, clen); +#else + c = *ptr; +#endif /* SUPPORT_UTF */ + } + else + { + clen = 0; /* This indicates the end of the subject */ + c = NOTACHAR; /* This value should never actually be used */ + } + + /* Scan up the active states and act on each one. The result of an action + may be to add more states to the currently active list (e.g. on hitting a + parenthesis) or it may be to put states on the new list, for considering + when we move the character pointer on. */ + + for (i = 0; i < active_count; i++) + { + stateblock *current_state = active_states + i; + BOOL caseless = FALSE; + const pcre_uchar *code; + int state_offset = current_state->offset; + int codevalue, rrc; + unsigned int count; + +#ifdef PCRE_DEBUG + printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset); + if (clen == 0) printf("EOL\n"); + else if (c > 32 && c < 127) printf("'%c'\n", c); + else printf("0x%02x\n", c); +#endif + + /* 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". If the could_continue flag was passed over from a previous + state, arrange for it to passed on. */ + + if (state_offset < 0) + { + if (current_state->data > 0) + { + 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 + { + current_state->offset = state_offset = -state_offset; + } + } + + /* Check for a duplicate state with the same count, and skip if found. + See the note at the head of this module about the possibility of improving + performance here. */ + + for (j = 0; j < i; j++) + { + if (active_states[j].offset == state_offset && + active_states[j].count == current_state->count) + { + DPRINTF(("%.*sDuplicate state: skipped\n", rlevel*2-2, SP)); + goto NEXT_ACTIVE_STATE; + } + } + + /* The state offset is the offset to the opcode */ + + code = start_code + state_offset; + codevalue = *code; + + /* If this opcode inspects a character, but we are at the end of the + subject, remember the fact for use when testing for a partial match. */ + + if (clen == 0 && poptable[codevalue] != 0) + could_continue = TRUE; + + /* If this opcode is followed by an inline character, load it. It is + tempting to test for the presence of a subject character here, but that + is wrong, because sometimes zero repetitions of the subject are + 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 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_UTF + if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else +#endif /* SUPPORT_UTF */ + d = code[coptable[codevalue]]; + if (codevalue >= OP_TYPESTAR) + { + switch(d) + { + case OP_ANYBYTE: return PCRE_ERROR_DFA_UITEM; + case OP_NOTPROP: + case OP_PROP: codevalue += OP_PROP_EXTRA; break; + case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break; + case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break; + case OP_NOT_HSPACE: + case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break; + case OP_NOT_VSPACE: + case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break; + default: break; + } + } + } + else + { + dlen = 0; /* Not strictly necessary, but compilers moan */ + d = NOTACHAR; /* if these variables are not set. */ + } + + + /* Now process the individual opcodes */ + + switch (codevalue) + { +/* ========================================================================== */ + /* These cases are never obeyed. This is a fudge that causes a compile- + time error if the vectors coptable or poptable, 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(coptable) == OP_TABLE_LENGTH) && + (sizeof(poptable) == OP_TABLE_LENGTH)): + break; + +/* ========================================================================== */ + /* Reached a closing bracket. If not at the end of the pattern, carry + 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. */ + + case OP_KET: + case OP_KETRMIN: + case OP_KETRMAX: + case OP_KETRPOS: + if (code != end_code) + { + ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0); + if (codevalue != OP_KET) + { + ADD_ACTIVE(state_offset - GET(code, 1), 0); + } + } + else + { + if (ptr > current_subject || + ((md->moptions & PCRE_NOTEMPTY) == 0 && + ((md->moptions & PCRE_NOTEMPTY_ATSTART) == 0 || + 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) + match_count = 0; + count = ((match_count == 0)? offsetcount : match_count * 2) - 2; + if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int)); + if (offsetcount >= 2) + { + 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], (char *)current_subject)); + } + if ((md->moptions & PCRE_DFA_SHORTEST) != 0) + { + DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n" + "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, + match_count, rlevel*2-2, SP)); + return match_count; + } + } + } + break; + +/* ========================================================================== */ + /* These opcodes add to the current list of states without looking + at the current character. */ + + /*-----------------------------------------------------------------*/ + case OP_ALT: + do { code += GET(code, 1); } while (*code == OP_ALT); + ADD_ACTIVE((int)(code - start_code), 0); + break; + + /*-----------------------------------------------------------------*/ + case OP_BRA: + case OP_SBRA: + do + { + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); + code += GET(code, 1); + } + while (*code == OP_ALT); + break; + + /*-----------------------------------------------------------------*/ + case OP_CBRA: + case OP_SCBRA: + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0); + code += GET(code, 1); + while (*code == OP_ALT) + { + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); + code += GET(code, 1); + } + break; + + /*-----------------------------------------------------------------*/ + case OP_BRAZERO: + case OP_BRAMINZERO: + ADD_ACTIVE(state_offset + 1, 0); + code += 1 + GET(code, 2); + while (*code == OP_ALT) code += GET(code, 1); + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); + break; + + /*-----------------------------------------------------------------*/ + case OP_SKIPZERO: + code += 1 + GET(code, 2); + while (*code == OP_ALT) code += GET(code, 1); + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0); + break; + + /*-----------------------------------------------------------------*/ + 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) || + (ptr != end_subject && WAS_NEWLINE(ptr))) + { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_EOD: + if (ptr >= end_subject) + { + if ((md->moptions & PCRE_PARTIAL_HARD) != 0) + could_continue = TRUE; + else { ADD_ACTIVE(state_offset + 1, 0); } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_SOD: + if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_SOM: + if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); } + break; + + +/* ========================================================================== */ + /* These opcodes inspect the next subject character, and sometimes + the previous one as well, but do not have an argument. The variable + clen contains the length of the current character and is zero if we are + at the end of the subject. */ + + /*-----------------------------------------------------------------*/ + case OP_ANY: + if (clen > 0 && !IS_NEWLINE(ptr)) + { + 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; + + /*-----------------------------------------------------------------*/ + case OP_ALLANY: + if (clen > 0) + { ADD_NEW(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_EODN: + if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0) + could_continue = TRUE; + else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen)) + { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_DOLL: + 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) && + (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 (IS_NEWLINE(ptr)) + { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + + case OP_DIGIT: + case OP_WHITESPACE: + case OP_WORDCHAR: + if (clen > 0 && c < 256 && + ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0) + { ADD_NEW(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_NOT_DIGIT: + case OP_NOT_WHITESPACE: + case OP_NOT_WORDCHAR: + if (clen > 0 && (c >= 256 || + ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)) + { ADD_NEW(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + { + int left_word, right_word; + + if (ptr > start_subject) + { + const pcre_uchar *temp = ptr - 1; + if (temp < md->start_used_ptr) md->start_used_ptr = temp; +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (utf) { BACKCHAR(temp); } +#endif + GETCHARTEST(d, temp); +#ifdef SUPPORT_UCP + if ((md->poptions & PCRE_UCP) != 0) + { + if (d == '_') left_word = TRUE; else + { + int cat = UCD_CATEGORY(d); + left_word = (cat == ucp_L || cat == ucp_N); + } + } + else +#endif + left_word = d < 256 && (ctypes[d] & ctype_word) != 0; + } + else left_word = FALSE; + + if (clen > 0) + { +#ifdef SUPPORT_UCP + if ((md->poptions & PCRE_UCP) != 0) + { + if (c == '_') right_word = TRUE; else + { + int cat = UCD_CATEGORY(c); + right_word = (cat == ucp_L || cat == ucp_N); + } + } + else +#endif + right_word = c < 256 && (ctypes[c] & ctype_word) != 0; + } + else right_word = FALSE; + + if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY)) + { ADD_ACTIVE(state_offset + 1, 0); } + } + break; + + + /*-----------------------------------------------------------------*/ + /* Check the next character by Unicode property. We will get here only + if the support is in the binary; otherwise a compile-time error occurs. + */ + +#ifdef SUPPORT_UCP + case OP_PROP: + case OP_NOTPROP: + if (clen > 0) + { + BOOL OK; + const pcre_uint32 *cp; + const ucd_record * prop = GET_UCD(c); + switch(code[1]) + { + case PT_ANY: + OK = TRUE; + break; + + case PT_LAMP: + OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt; + break; + + case PT_GC: + OK = PRIV(ucp_gentype)[prop->chartype] == code[2]; + break; + + case PT_PC: + OK = prop->chartype == code[2]; + break; + + case PT_SC: + OK = prop->script == code[2]; + break; + + /* These are specials for combination cases. */ + + case PT_ALNUM: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; + break; + + case PT_SPACE: /* Perl space */ + 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 = 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 = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE; + break; + + case PT_CLIST: + cp = PRIV(ucd_caseless_sets) + code[2]; + for (;;) + { + if (c < *cp) { OK = FALSE; break; } + if (c == *cp++) { OK = TRUE; break; } + } + break; + + /* Should never occur, but keep compilers from grumbling. */ + + default: + OK = codevalue != OP_PROP; + break; + } + + if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); } + } + break; +#endif + + + +/* ========================================================================== */ + /* These opcodes likewise inspect the subject character, but have an + argument that is not a data character. It is one of these opcodes: + OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE, + OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */ + + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } + if (clen > 0) + { + 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 > 0 && codevalue == OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW(state_offset, count); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSQUERY: + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + 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 (codevalue == OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset + 2, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPOSSTAR: + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + 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 (codevalue == OP_TYPEPOSSTAR) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_TYPEEXACT: + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + 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 + 1 + IMM2_SIZE + 1, 0); } + else + { ADD_NEW(state_offset, count); } + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEPOSUPTO: + ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + 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 (codevalue == OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= GET2(code, 1)) + { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); } + else + { ADD_NEW(state_offset, count); } + } + } + break; + +/* ========================================================================== */ + /* These are virtual opcodes that are used when something like + OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its + argument. It keeps the code above fast for the other cases. The argument + is in the d variable. */ + +#ifdef SUPPORT_UCP + case OP_PROP_EXTRA + OP_TYPEPLUS: + case OP_PROP_EXTRA + OP_TYPEMINPLUS: + case OP_PROP_EXTRA + OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); } + if (clen > 0) + { + BOOL OK; + const pcre_uint32 *cp; + const ucd_record * prop = GET_UCD(c); + switch(code[2]) + { + case PT_ANY: + OK = TRUE; + break; + + case PT_LAMP: + OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt; + break; + + case PT_GC: + OK = PRIV(ucp_gentype)[prop->chartype] == code[3]; + break; + + case PT_PC: + OK = prop->chartype == code[3]; + break; + + case PT_SC: + OK = prop->script == code[3]; + break; + + /* These are specials for combination cases. */ + + case PT_ALNUM: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; + break; + + case PT_SPACE: /* Perl space */ + 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 = 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 = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE; + break; + + case PT_CLIST: + cp = PRIV(ucd_caseless_sets) + code[3]; + for (;;) + { + if (c < *cp) { OK = FALSE; break; } + if (c == *cp++) { OK = TRUE; break; } + } + break; + + /* Should never occur, but keep compilers from grumbling. */ + + default: + OK = codevalue != OP_PROP; + break; + } + + if (OK == (d == OP_PROP)) + { + if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW(state_offset, count); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_EXTUNI_EXTRA + OP_TYPEPLUS: + case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS: + case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } + if (clen > 0) + { + int lgb, rgb; + const pcre_uchar *nptr = ptr + clen; + int ncount = 0; + if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + lgb = UCD_GRAPHBREAK(c); + while (nptr < end_subject) + { + dlen = 1; + if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } + rgb = UCD_GRAPHBREAK(d); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + ncount++; + lgb = rgb; + nptr += dlen; + } + count++; + ADD_NEW_DATA(-state_offset, count, ncount); + } + break; +#endif + + /*-----------------------------------------------------------------*/ + case OP_ANYNL_EXTRA + OP_TYPEPLUS: + case OP_ANYNL_EXTRA + OP_TYPEMINPLUS: + case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } + if (clen > 0) + { + int ncount = 0; + switch (c) + { + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; + goto ANYNL01; + + case CHAR_CR: + if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1; + /* Fall through */ + + ANYNL01: + case CHAR_LF: + if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW_DATA(-state_offset, count, ncount); + break; + + default: + break; + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_VSPACE_EXTRA + OP_TYPEPLUS: + case OP_VSPACE_EXTRA + OP_TYPEMINPLUS: + case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } + if (clen > 0) + { + BOOL OK; + switch (c) + { + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + break; + } + + if (OK == (d == OP_VSPACE)) + { + if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW_DATA(-state_offset, count, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_HSPACE_EXTRA + OP_TYPEPLUS: + case OP_HSPACE_EXTRA + OP_TYPEMINPLUS: + case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } + if (clen > 0) + { + BOOL OK; + switch (c) + { + HSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + break; + } + + if (OK == (d == OP_HSPACE)) + { + if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW_DATA(-state_offset, count, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ +#ifdef SUPPORT_UCP + case OP_PROP_EXTRA + OP_TYPEQUERY: + case OP_PROP_EXTRA + OP_TYPEMINQUERY: + case OP_PROP_EXTRA + OP_TYPEPOSQUERY: + count = 4; + goto QS1; + + case OP_PROP_EXTRA + OP_TYPESTAR: + case OP_PROP_EXTRA + OP_TYPEMINSTAR: + case OP_PROP_EXTRA + OP_TYPEPOSSTAR: + count = 0; + + QS1: + + ADD_ACTIVE(state_offset + 4, 0); + if (clen > 0) + { + BOOL OK; + const pcre_uint32 *cp; + const ucd_record * prop = GET_UCD(c); + switch(code[2]) + { + case PT_ANY: + OK = TRUE; + break; + + case PT_LAMP: + OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt; + break; + + case PT_GC: + OK = PRIV(ucp_gentype)[prop->chartype] == code[3]; + break; + + case PT_PC: + OK = prop->chartype == code[3]; + break; + + case PT_SC: + OK = prop->script == code[3]; + break; + + /* These are specials for combination cases. */ + + case PT_ALNUM: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; + break; + + case PT_SPACE: /* Perl space */ + 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 = 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 = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE; + break; + + case PT_CLIST: + cp = PRIV(ucd_caseless_sets) + code[3]; + for (;;) + { + if (c < *cp) { OK = FALSE; break; } + if (c == *cp++) { OK = TRUE; break; } + } + break; + + /* Should never occur, but keep compilers from grumbling. */ + + default: + OK = codevalue != OP_PROP; + break; + } + + if (OK == (d == OP_PROP)) + { + if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR || + codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset + count, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_EXTUNI_EXTRA + OP_TYPEQUERY: + case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY: + case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY: + count = 2; + goto QS2; + + case OP_EXTUNI_EXTRA + OP_TYPESTAR: + case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR: + case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR: + count = 0; + + QS2: + + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + int lgb, rgb; + const pcre_uchar *nptr = ptr + clen; + int ncount = 0; + if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR || + codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + lgb = UCD_GRAPHBREAK(c); + while (nptr < end_subject) + { + dlen = 1; + if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } + rgb = UCD_GRAPHBREAK(d); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + ncount++; + lgb = rgb; + nptr += dlen; + } + ADD_NEW_DATA(-(state_offset + count), 0, ncount); + } + break; +#endif + + /*-----------------------------------------------------------------*/ + case OP_ANYNL_EXTRA + OP_TYPEQUERY: + case OP_ANYNL_EXTRA + OP_TYPEMINQUERY: + case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY: + count = 2; + goto QS3; + + case OP_ANYNL_EXTRA + OP_TYPESTAR: + case OP_ANYNL_EXTRA + OP_TYPEMINSTAR: + case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR: + count = 0; + + QS3: + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + int ncount = 0; + switch (c) + { + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; + goto ANYNL02; + + case CHAR_CR: + if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1; + /* Fall through */ + + ANYNL02: + case CHAR_LF: + if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR || + codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW_DATA(-(state_offset + count), 0, ncount); + break; + + default: + break; + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_VSPACE_EXTRA + OP_TYPEQUERY: + case OP_VSPACE_EXTRA + OP_TYPEMINQUERY: + case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY: + count = 2; + goto QS4; + + case OP_VSPACE_EXTRA + OP_TYPESTAR: + case OP_VSPACE_EXTRA + OP_TYPEMINSTAR: + case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR: + count = 0; + + QS4: + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + BOOL OK; + switch (c) + { + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + break; + } + if (OK == (d == OP_VSPACE)) + { + if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR || + codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW_DATA(-(state_offset + count), 0, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_HSPACE_EXTRA + OP_TYPEQUERY: + case OP_HSPACE_EXTRA + OP_TYPEMINQUERY: + case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY: + count = 2; + goto QS5; + + case OP_HSPACE_EXTRA + OP_TYPESTAR: + case OP_HSPACE_EXTRA + OP_TYPEMINSTAR: + case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR: + count = 0; + + QS5: + ADD_ACTIVE(state_offset + 2, 0); + if (clen > 0) + { + BOOL OK; + switch (c) + { + HSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + break; + } + + if (OK == (d == OP_HSPACE)) + { + if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR || + codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW_DATA(-(state_offset + count), 0, 0); + } + } + break; + + /*-----------------------------------------------------------------*/ +#ifdef SUPPORT_UCP + case OP_PROP_EXTRA + OP_TYPEEXACT: + case OP_PROP_EXTRA + OP_TYPEUPTO: + case OP_PROP_EXTRA + OP_TYPEMINUPTO: + case OP_PROP_EXTRA + OP_TYPEPOSUPTO: + if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT) + { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); } + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + BOOL OK; + const pcre_uint32 *cp; + const ucd_record * prop = GET_UCD(c); + switch(code[1 + IMM2_SIZE + 1]) + { + case PT_ANY: + OK = TRUE; + break; + + case PT_LAMP: + OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt; + break; + + case PT_GC: + OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2]; + break; + + case PT_PC: + OK = prop->chartype == code[1 + IMM2_SIZE + 2]; + break; + + case PT_SC: + OK = prop->script == code[1 + IMM2_SIZE + 2]; + break; + + /* These are specials for combination cases. */ + + case PT_ALNUM: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; + break; + + case PT_SPACE: /* Perl space */ + 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 = 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 = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE; + break; + + case PT_CLIST: + cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2]; + for (;;) + { + if (c < *cp) { OK = FALSE; break; } + if (c == *cp++) { OK = TRUE; break; } + } + break; + + /* Should never occur, but keep compilers from grumbling. */ + + default: + OK = codevalue != OP_PROP; + break; + } + + if (OK == (d == OP_PROP)) + { + if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= GET2(code, 1)) + { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); } + else + { ADD_NEW(state_offset, count); } + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_EXTUNI_EXTRA + OP_TYPEEXACT: + case OP_EXTUNI_EXTRA + OP_TYPEUPTO: + case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO: + case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO: + if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT) + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + int lgb, rgb; + const pcre_uchar *nptr = ptr + clen; + int ncount = 0; + if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + lgb = UCD_GRAPHBREAK(c); + while (nptr < end_subject) + { + dlen = 1; + if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } + rgb = UCD_GRAPHBREAK(d); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + ncount++; + lgb = rgb; + nptr += dlen; + } + if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; + if (++count >= GET2(code, 1)) + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } + else + { ADD_NEW_DATA(-state_offset, count, ncount); } + } + break; +#endif + + /*-----------------------------------------------------------------*/ + case OP_ANYNL_EXTRA + OP_TYPEEXACT: + case OP_ANYNL_EXTRA + OP_TYPEUPTO: + case OP_ANYNL_EXTRA + OP_TYPEMINUPTO: + case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO: + if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT) + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + int ncount = 0; + switch (c) + { + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; + goto ANYNL03; + + case CHAR_CR: + if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1; + /* Fall through */ + + ANYNL03: + case CHAR_LF: + if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= GET2(code, 1)) + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } + else + { ADD_NEW_DATA(-state_offset, count, ncount); } + break; + + default: + break; + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_VSPACE_EXTRA + OP_TYPEEXACT: + case OP_VSPACE_EXTRA + OP_TYPEUPTO: + case OP_VSPACE_EXTRA + OP_TYPEMINUPTO: + case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO: + if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT) + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + BOOL OK; + switch (c) + { + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + } + + if (OK == (d == OP_VSPACE)) + { + if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= GET2(code, 1)) + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } + else + { ADD_NEW_DATA(-state_offset, count, 0); } + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_HSPACE_EXTRA + OP_TYPEEXACT: + case OP_HSPACE_EXTRA + OP_TYPEUPTO: + case OP_HSPACE_EXTRA + OP_TYPEMINUPTO: + case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO: + if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT) + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + BOOL OK; + switch (c) + { + HSPACE_CASES: + OK = TRUE; + break; + + default: + OK = FALSE; + break; + } + + if (OK == (d == OP_HSPACE)) + { + if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= GET2(code, 1)) + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } + else + { ADD_NEW_DATA(-state_offset, count, 0); } + } + } + break; + +/* ========================================================================== */ + /* These opcodes are followed by a character that is usually compared + to the current subject character; it is loaded into d. We still get + here even if there is no subject character, because in some cases zero + repetitions are permitted. */ + + /*-----------------------------------------------------------------*/ + case OP_CHAR: + if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_CHARI: + if (clen == 0) break; + +#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. */ +#ifdef SUPPORT_UCP + othercase = UCD_OTHERCASE(c); +#else + othercase = NOTACHAR; +#endif + + if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); } + } + } + else +#endif /* SUPPORT_UTF */ + /* Not UTF mode */ + { + if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d)) + { ADD_NEW(state_offset + 2, 0); } + } + break; + + +#ifdef SUPPORT_UCP + /*-----------------------------------------------------------------*/ + /* This is a tricky one because it can match more than one character. + Find out how many characters to skip, and then set up a negative state + to wait for them to pass before continuing. */ + + case OP_EXTUNI: + if (clen > 0) + { + int lgb, rgb; + const pcre_uchar *nptr = ptr + clen; + int ncount = 0; + lgb = UCD_GRAPHBREAK(c); + while (nptr < end_subject) + { + dlen = 1; + if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } + rgb = UCD_GRAPHBREAK(d); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + ncount++; + lgb = rgb; + nptr += dlen; + } + if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; + ADD_NEW_DATA(-(state_offset + 1), 0, ncount); + } + break; +#endif + + /*-----------------------------------------------------------------*/ + /* This is a tricky like EXTUNI because it too can match more than one + character (when CR is followed by LF). In this case, set up a negative + state to wait for one character to pass before continuing. */ + + case OP_ANYNL: + if (clen > 0) switch(c) + { + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; + + case CHAR_LF: + ADD_NEW(state_offset + 1, 0); + break; + + case CHAR_CR: + if (ptr + 1 >= end_subject) + { + ADD_NEW(state_offset + 1, 0); + if ((md->moptions & PCRE_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; + } + else if (RAWUCHARTEST(ptr + 1) == CHAR_LF) + { + ADD_NEW_DATA(-(state_offset + 1), 0, 1); + } + else + { + ADD_NEW(state_offset + 1, 0); + } + break; + } + break; + + /*-----------------------------------------------------------------*/ + case OP_NOT_VSPACE: + if (clen > 0) switch(c) + { + VSPACE_CASES: + break; + + default: + ADD_NEW(state_offset + 1, 0); + break; + } + break; + + /*-----------------------------------------------------------------*/ + case OP_VSPACE: + if (clen > 0) switch(c) + { + VSPACE_CASES: + ADD_NEW(state_offset + 1, 0); + break; + + default: + break; + } + break; + + /*-----------------------------------------------------------------*/ + case OP_NOT_HSPACE: + if (clen > 0) switch(c) + { + HSPACE_CASES: + break; + + default: + ADD_NEW(state_offset + 1, 0); + break; + } + break; + + /*-----------------------------------------------------------------*/ + case OP_HSPACE: + if (clen > 0) switch(c) + { + HSPACE_CASES: + ADD_NEW(state_offset + 1, 0); + break; + + default: + break; + } + break; + + /*-----------------------------------------------------------------*/ + /* 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; +#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: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTPOSPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); } + if (clen > 0) + { + pcre_uint32 otherd = NOTACHAR; + if (caseless) + { +#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) == (codevalue < OP_NOTSTAR)) + { + if (count > 0 && + (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS)) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW(state_offset, count); + } + } + 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: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTPOSQUERY: + ADD_ACTIVE(state_offset + dlen + 1, 0); + if (clen > 0) + { + pcre_uint32 otherd = NOTACHAR; + if (caseless) + { +#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) == (codevalue < OP_NOTSTAR)) + { + if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset + dlen + 1, 0); + } + } + 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: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPOSSTAR: + ADD_ACTIVE(state_offset + dlen + 1, 0); + if (clen > 0) + { + pcre_uint32 otherd = NOTACHAR; + if (caseless) + { +#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) == (codevalue < OP_NOTSTAR)) + { + if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset, 0); + } + } + 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) + { + pcre_uint32 otherd = NOTACHAR; + if (caseless) + { +#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) == (codevalue < OP_NOTSTAR)) + { + if (++count >= GET2(code, 1)) + { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } + else + { ADD_NEW(state_offset, count); } + } + } + 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 + 1 + IMM2_SIZE, 0); + count = current_state->count; /* Number already matched */ + if (clen > 0) + { + pcre_uint32 otherd = NOTACHAR; + if (caseless) + { +#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) == (codevalue < OP_NOTSTAR)) + { + if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + if (++count >= GET2(code, 1)) + { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } + else + { ADD_NEW(state_offset, count); } + } + } + break; + + +/* ========================================================================== */ + /* These are the class-handling opcodes */ + + case OP_CLASS: + case OP_NCLASS: + case OP_XCLASS: + { + BOOL isinclass = FALSE; + int next_state_offset; + 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 + 1 + (32 / sizeof(pcre_uchar)); + if (clen > 0) + { + isinclass = (c > 255)? (codevalue == OP_NCLASS) : + ((((pcre_uint8 *)(code + 1))[c/8] & (1 << (c&7))) != 0); + } + } + + /* An extended class may have a table or a list of single characters, + ranges, or both, and it may be positive or negative. There's a + function that sorts all this out. */ + + else + { + ecode = code + GET(code, 1); + 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 + points to the byte after the end of the class. If there is a + quantifier, this is where it will be. */ + + next_state_offset = (int)(ecode - start_code); + + switch (*ecode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + ADD_ACTIVE(next_state_offset + 1, 0); + if (isinclass) { ADD_NEW(state_offset, 0); } + break; + + case OP_CRPLUS: + case OP_CRMINPLUS: + count = current_state->count; /* Already matched */ + if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); } + if (isinclass) { count++; ADD_NEW(state_offset, count); } + break; + + case OP_CRQUERY: + case OP_CRMINQUERY: + ADD_ACTIVE(next_state_offset + 1, 0); + if (isinclass) { ADD_NEW(next_state_offset + 1, 0); } + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + count = current_state->count; /* Already matched */ + if (count >= GET2(ecode, 1)) + { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } + if (isinclass) + { + unsigned int max = GET2(ecode, 1 + IMM2_SIZE); + if (++count >= max && max != 0) /* Max 0 => no limit */ + { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } + else + { ADD_NEW(state_offset, count); } + } + break; + + default: + if (isinclass) { ADD_NEW(next_state_offset, 0); } + break; + } + } + break; + +/* ========================================================================== */ + /* These are the opcodes for fancy brackets of various kinds. We have + to use recursion in order to handle them. The "always failing" assertion + (?!) is optimised to OP_FAIL when compiling, so we have to support that, + though the other "backtracking verbs" are not supported. */ + + case OP_FAIL: + forced_fail++; /* Count FAILs for multiple states */ + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + { + int rc; + int local_offsets[2]; + int local_workspace[1000]; + const pcre_uchar *endasscode = code + GET(code, 1); + + while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); + + rc = internal_dfa_exec( + md, /* static match data */ + code, /* 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 */ + rlevel); /* function recursion level */ + + if (rc == PCRE_ERROR_DFA_UITEM) return rc; + if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK)) + { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_COND: + case OP_SCOND: + { + int local_offsets[1000]; + int local_workspace[1000]; + int codelink = GET(code, 1); + int condcode; + + /* Because of the way auto-callout works during compile, a callout item + is inserted between OP_COND and an assertion condition. This does not + happen for the other conditions. */ + + if (code[LINK_SIZE+1] == OP_CALLOUT) + { + rrc = 0; + if (PUBL(callout) != NULL) + { + PUBL(callout_block) cb; + cb.version = 1; /* Version 1 of the callout block */ + cb.callout_number = code[LINK_SIZE+2]; + cb.offset_vector = offsets; +#if defined COMPILE_PCRE8 + cb.subject = (PCRE_SPTR)start_subject; +#elif defined COMPILE_PCRE16 + cb.subject = (PCRE_SPTR16)start_subject; +#elif defined COMPILE_PCRE32 + cb.subject = (PCRE_SPTR32)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); + cb.pattern_position = GET(code, LINK_SIZE + 3); + cb.next_item_length = GET(code, 3 + 2*LINK_SIZE); + cb.capture_top = 1; + cb.capture_last = -1; + cb.callout_data = md->callout_data; + cb.mark = NULL; /* No (*MARK) support */ + if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */ + } + if (rrc > 0) break; /* Fail this thread */ + code += PRIV(OP_lengths)[OP_CALLOUT]; /* Skip callout data */ + } + + condcode = code[LINK_SIZE+1]; + + /* Back reference conditions are not supported */ + + if (condcode == OP_CREF || condcode == OP_NCREF) + return PCRE_ERROR_DFA_UCOND; + + /* The DEFINE condition is always false */ + + if (condcode == OP_DEF) + { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } + + /* The only supported version of OP_RREF is for the value RREF_ANY, + which means "test if in any recursion". We can't test for specifically + recursed groups. */ + + else if (condcode == OP_RREF || condcode == OP_NRREF) + { + int value = GET2(code, LINK_SIZE + 2); + if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND; + if (md->recursive != NULL) + { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); } + else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } + } + + /* Otherwise, the condition is an assertion */ + + else + { + int rc; + const pcre_uchar *asscode = code + LINK_SIZE + 1; + const pcre_uchar *endasscode = asscode + GET(asscode, 1); + + while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); + + rc = internal_dfa_exec( + md, /* fixed match data */ + asscode, /* 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 */ + rlevel); /* function recursion level */ + + if (rc == PCRE_ERROR_DFA_UITEM) return rc; + if ((rc >= 0) == + (condcode == OP_ASSERT || condcode == OP_ASSERTBACK)) + { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); } + else + { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } + } + } + break; + + /*-----------------------------------------------------------------*/ + 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\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 */ + 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 */ + rlevel); /* function recursion level */ + + md->recursive = new_recursive.prevrec; /* Done this recursion */ + + DPRINTF(("%.*sReturn from regex recursion: rc=%d\n", rlevel*2-2, SP, + rc)); + + /* Ran out of internal offsets */ + + if (rc == 0) return PCRE_ERROR_DFA_RECURSE; + + /* For each successful matched substring, set up the next state with a + count of characters to skip before trying it. Note that the count is in + characters, not bytes. */ + + if (rc > 0) + { + for (rc = rc*2 - 2; rc >= 0; rc -= 2) + { + int charcount = local_offsets[rc+1] - local_offsets[rc]; +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + 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)); + } + else + { + ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0); + } + } + } + else if (rc != PCRE_ERROR_NOMATCH) return rc; + } + 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); +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + 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]; + + int rc = internal_dfa_exec( + md, /* fixed match data */ + code, /* 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 */ + rlevel); /* function recursion level */ + + if (rc >= 0) + { + const pcre_uchar *end_subpattern = code; + int charcount = local_offsets[1] - local_offsets[0]; + int next_state_offset, repeat_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); + + /* If the end of this subpattern is KETRMAX or KETRMIN, we must + arrange for the repeat state also to be added to the relevant list. + Calculate the offset, or set -1 for no repeat. */ + + repeat_state_offset = (*end_subpattern == OP_KETRMAX || + *end_subpattern == OP_KETRMIN)? + (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1; + + /* If we have matched an empty string, add the next state at the + current character pointer. This is important so that the duplicate + checking kicks in, which is what breaks infinite loops that match an + empty string. */ + + if (charcount == 0) + { + ADD_ACTIVE(next_state_offset, 0); + } + + /* 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. */ + + else if (i + 1 >= active_count && new_count == 0) + { + ptr += charcount; + clen = 0; + ADD_NEW(next_state_offset, 0); + + /* If we are adding a repeat state at the new character position, + we must fudge things so that it is the only current state. + Otherwise, it might be a duplicate of one we processed before, and + that would cause it to be skipped. */ + + if (repeat_state_offset >= 0) + { + next_active_state = active_states; + active_count = 0; + i = -1; + ADD_ACTIVE(repeat_state_offset, 0); + } + } + else + { +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + 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; + } + break; + + +/* ========================================================================== */ + /* Handle callouts */ + + case OP_CALLOUT: + rrc = 0; + if (PUBL(callout) != NULL) + { + PUBL(callout_block) cb; + cb.version = 1; /* Version 1 of the callout block */ + cb.callout_number = code[1]; + cb.offset_vector = offsets; +#if defined COMPILE_PCRE8 + cb.subject = (PCRE_SPTR)start_subject; +#elif defined COMPILE_PCRE16 + cb.subject = (PCRE_SPTR16)start_subject; +#elif defined COMPILE_PCRE32 + cb.subject = (PCRE_SPTR32)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); + cb.pattern_position = GET(code, 2); + cb.next_item_length = GET(code, 2 + LINK_SIZE); + cb.capture_top = 1; + cb.capture_last = -1; + cb.callout_data = md->callout_data; + cb.mark = NULL; /* No (*MARK) support */ + if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */ + } + if (rrc == 0) + { ADD_ACTIVE(state_offset + PRIV(OP_lengths)[OP_CALLOUT], 0); } + break; + + +/* ========================================================================== */ + default: /* Unsupported opcode */ + return PCRE_ERROR_DFA_UITEM; + } + + NEXT_ACTIVE_STATE: continue; + + } /* End of loop scanning active states */ + + /* We have finished the processing at the current subject character. If no + new states have been set for the next character, we have found all the + matches that we are going to find. If we are at the top level and partial + matching has been requested, check for appropriate conditions. + + The "forced_ fail" variable counts the number of (*F) encountered for the + character. If it is equal to the original active_count (saved in + workspace[1]) it means that (*F) was found on every active state. In this + case we don't want to give a partial match. + + The "could_continue" variable is true if a state could have continued but + for the fact that the end of the subject was reached. */ + + if (new_count <= 0) + { + if (rlevel == 1 && /* Top level, and */ + could_continue && /* Some could go on, and */ + forced_fail != workspace[1] && /* Not all forced fail & */ + ( /* either... */ + (md->moptions & PCRE_PARTIAL_HARD) != 0 /* Hard partial */ + || /* or... */ + ((md->moptions & PCRE_PARTIAL_SOFT) != 0 && /* Soft partial and */ + match_count < 0) /* no matches */ + ) && /* And... */ + ( + 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) + { + offsets[0] = (int)(md->start_used_ptr - start_subject); + offsets[1] = (int)(end_subject - start_subject); + } + match_count = PCRE_ERROR_PARTIAL; + } + + DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n" + "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count, + rlevel*2-2, SP)); + break; /* In effect, "return", but see the comment below */ + } + + /* One or more states are active for the next character. */ + + ptr += clen; /* Advance to next subject character */ + } /* Loop to move along the subject string */ + +/* Control gets here from "break" a few lines above. We do it this way because +if we use "return" above, we have compiler trouble. Some compilers warn if +there's nothing here because they think the function doesn't return a value. On +the other hand, if we put a dummy statement here, some more clever compilers +complain that it can't be reached. Sigh. */ + +return match_count; +} + + + + +/************************************************* +* Execute a Regular Expression - DFA engine * +*************************************************/ + +/* This external function applies a compiled re to a subject string using a DFA +engine. This function calls the internal function multiple times if the pattern +is not anchored. + +Arguments: + argument_re points to the compiled expression + extra_data points to extra data or is NULL + subject points to the subject string + length length of subject string (may contain binary zeros) + start_offset where to start in the subject string + options option bits + offsets vector of match offsets + offsetcount size of same + workspace workspace vector + wscount size of same + +Returns: > 0 => number of match offset pairs placed in offsets + = 0 => offsets overflowed; longest matches are present + -1 => failed to match + < -1 => some kind of unexpected problem +*/ + +#if defined 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) +#elif defined COMPILE_PCRE16 +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) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_dfa_exec(const pcre32 *argument_re, const pcre32_extra *extra_data, + PCRE_SPTR32 subject, int length, int start_offset, int options, int *offsets, + int offsetcount, int *workspace, int wscount) +#endif +{ +REAL_PCRE *re = (REAL_PCRE *)argument_re; +dfa_match_data match_block; +dfa_match_data *md = &match_block; +BOOL utf, anchored, startline, firstline; +const pcre_uchar *current_subject, *end_subject; +const pcre_study_data *study = NULL; + +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 */ + +if ((options & ~PUBLIC_DFA_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; +if (re == NULL || subject == NULL || workspace == NULL || + (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; +if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; +if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE; +if (length < 0) return PCRE_ERROR_BADLENGTH; +if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; + +/* 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; + +if (extra_data != NULL) + { + unsigned int flags = extra_data->flags; + if ((flags & PCRE_EXTRA_STUDY_DATA) != 0) + study = (const pcre_study_data *)extra_data->study_data; + if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) return PCRE_ERROR_DFA_UMLIMIT; + if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0) + return PCRE_ERROR_DFA_UMLIMIT; + if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0) + md->callout_data = extra_data->callout_data; + if ((flags & PCRE_EXTRA_TABLES) != 0) + md->tables = extra_data->tables; + } + +/* Set some local values */ + +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_UTF(16|32) have the same value as PCRE_UTF8. */ +utf = (re->options & PCRE_UTF8) != 0; +#else +utf = FALSE; +#endif + +anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 || + (re->options & PCRE_ANCHORED) != 0; + +/* The remaining fixed data for passing around. */ + +md->start_code = (const pcre_uchar *)argument_re + + re->name_table_offset + re->name_count * re->name_entry_size; +md->start_subject = (const pcre_uchar *)subject; +md->end_subject = end_subject; +md->start_offset = start_offset; +md->moptions = options; +md->poptions = re->options; + +/* If the BSR option is not set at match time, copy what was set +at compile time. */ + +if ((md->moptions & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == 0) + { + if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0) + md->moptions |= re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE); +#ifdef BSR_ANYCRLF + else md->moptions |= PCRE_BSR_ANYCRLF; +#endif + } + +/* Handle different types of newline. The three bits give eight cases. If +nothing is set at run time, whatever was used at compile time applies. */ + +switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) & + PCRE_NEWLINE_BITS) + { + case 0: newline = NEWLINE; break; /* Compile-time default */ + case PCRE_NEWLINE_CR: newline = CHAR_CR; break; + case PCRE_NEWLINE_LF: newline = CHAR_NL; break; + case PCRE_NEWLINE_CR+ + PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break; + case PCRE_NEWLINE_ANY: newline = -1; break; + case PCRE_NEWLINE_ANYCRLF: newline = -2; break; + default: return PCRE_ERROR_BADNEWLINE; + } + +if (newline == -2) + { + md->nltype = NLTYPE_ANYCRLF; + } +else if (newline < 0) + { + md->nltype = NLTYPE_ANY; + } +else + { + md->nltype = NLTYPE_FIXED; + if (newline > 255) + { + md->nllen = 2; + md->nl[0] = (newline >> 8) & 255; + md->nl[1] = newline & 255; + } + else + { + md->nllen = 1; + md->nl[0] = newline; + } + } + +/* Check a UTF-8 string if required. Unfortunately there's no way of passing +back the character offset. */ + +#ifdef SUPPORT_UTF +if (utf && (options & PCRE_NO_UTF8_CHECK) == 0) + { + int erroroffset; + int errorcode = PRIV(valid_utf)((pcre_uchar *)subject, length, &erroroffset); + if (errorcode != 0) + { + if (offsetcount >= 2) + { + offsets[0] = erroroffset; + offsets[1] = errorcode; + } +#if defined COMPILE_PCRE8 + return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0) ? + PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; +#elif defined COMPILE_PCRE16 + return (errorcode <= PCRE_UTF16_ERR1 && (options & PCRE_PARTIAL_HARD) != 0) ? + PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16; +#elif defined COMPILE_PCRE32 + return PCRE_ERROR_BADUTF32; +#endif + } +#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 + if (start_offset > 0 && start_offset < length && + NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset])) + return PCRE_ERROR_BADUTF8_OFFSET; +#endif + } +#endif + +/* If the exec call supplied NULL for tables, use the inbuilt ones. This +is a feature that makes it possible to save compiled regex and re-use them +in other programs later. */ + +if (md->tables == NULL) md->tables = PRIV(default_tables); + +/* The "must be at the start of a line" flags are used in a loop when finding +where to start. */ + +startline = (re->flags & PCRE_STARTLINE) != 0; +firstline = (re->options & PCRE_FIRSTLINE) != 0; + +/* Set up the first character to match, if available. The first_byte 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 +studied, there may be a bitmap of possible first characters. */ + +if (!anchored) + { + if ((re->flags & PCRE_FIRSTSET) != 0) + { + 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 + { + if (!startline && study != NULL && + (study->flags & PCRE_STUDY_MAPPED) != 0) + start_bits = study->start_bits; + } + } + +/* For anchored or unanchored matches, there may be a "last known required +character" set. */ + +if ((re->flags & PCRE_REQCHSET) != 0) + { + 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 +failed match. If not restarting, perform certain optimizations at the start of +a match. */ + +for (;;) + { + int rc; + + if ((options & PCRE_DFA_RESTART) == 0) + { + 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 + end_subject so that we stop scanning at a newline. If the match fails at + the newline, later code breaks this loop. */ + + if (firstline) + { + PCRE_PUCHAR t = current_subject; +#ifdef SUPPORT_UTF + if (utf) + { + while (t < md->end_subject && !IS_NEWLINE(t)) + { + t++; + ACROSSCHAR(t < end_subject, *t, t++); + } + } + else +#endif + while (t < md->end_subject && !IS_NEWLINE(t)) t++; + end_subject = t; + } + + /* There are some optimizations that avoid running the match if a known + starting point is not found. However, there is an option that disables + these, for testing and for ensuring that all callouts do actually occur. + The option can be set in the regex by (*NO_START_OPT) or passed in + match-time options. */ + + if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0) + { + /* Advance to a known first char. */ + + if (has_first_char) + { + if (first_char != first_char2) + { + pcre_uchar csc; + while (current_subject < end_subject && + (csc = RAWUCHARTEST(current_subject)) != first_char && csc != first_char2) + current_subject++; + } + else + while (current_subject < end_subject && + RAWUCHARTEST(current_subject) != first_char) + current_subject++; + } + + /* Or to just after a linebreak for a multiline match if possible */ + + else if (startline) + { + if (current_subject > md->start_subject + start_offset) + { +#ifdef SUPPORT_UTF + if (utf) + { + while (current_subject < end_subject && + !WAS_NEWLINE(current_subject)) + { + current_subject++; + ACROSSCHAR(current_subject < end_subject, *current_subject, + current_subject++); + } + } + else +#endif + while (current_subject < end_subject && !WAS_NEWLINE(current_subject)) + current_subject++; + + /* If we have just passed a CR and the newline option is ANY or + ANYCRLF, and we are now at a LF, advance the match position by one + more character. */ + + if (RAWUCHARTEST(current_subject - 1) == CHAR_CR && + (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) && + current_subject < end_subject && + RAWUCHARTEST(current_subject) == CHAR_NL) + current_subject++; + } + } + + /* Or to a non-unique first char after study */ + + else if (start_bits != NULL) + { + while (current_subject < end_subject) + { + register pcre_uint32 c = RAWUCHARTEST(current_subject); +#ifndef COMPILE_PCRE8 + if (c > 255) c = 255; +#endif + if ((start_bits[c/8] & (1 << (c&7))) == 0) + { + 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; + } + } + } + + /* Restore fudged end_subject */ + + end_subject = save_end_subject; + + /* The following two optimizations are disabled for partial matching or if + disabling is explicitly requested (and of course, by the test above, this + code is not obeyed when restarting after a partial match). */ + + 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 + is a lower bound; no actual string of that length may actually match the + pattern. Although the value is, strictly, in characters, we treat it as + bytes to avoid spending too much time in this optimization. */ + + if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 && + (pcre_uint32)(end_subject - current_subject) < study->minlength) + return PCRE_ERROR_NOMATCH; + + /* 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 + code for cased/caseless versions makes it go faster, as does using an + autoincrement and backing off on a match. + + HOWEVER: when the subject string is very, very long, searching to its end + can take a long time, and give bad performance on quite ordinary + 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 (has_req_char && end_subject - current_subject < REQ_BYTE_MAX) + { + 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_char_ptr) + { + if (req_char != req_char2) + { + while (p < end_subject) + { + register pcre_uint32 pp = RAWUCHARINCTEST(p); + if (pp == req_char || pp == req_char2) { p--; break; } + } + } + else + { + while (p < end_subject) + { + if (RAWUCHARINCTEST(p) == req_char) { p--; break; } + } + } + + /* If we can't find the required character, break the matching loop, + which will cause a return or PCRE_ERROR_NOMATCH. */ + + if (p >= end_subject) break; + + /* If we have found the required character, save the point where we + found it, so that we don't search again next time round the loop if + the start hasn't passed this character yet. */ + + req_char_ptr = p; + } + } + } + } /* End of optimizations that are done when not restarting */ + + /* OK, now we can do the business */ + + md->start_used_ptr = current_subject; + md->recursive = NULL; + + rc = internal_dfa_exec( + md, /* fixed match data */ + md->start_code, /* this subexpression's code */ + current_subject, /* where we currently are */ + start_offset, /* start offset in subject */ + offsets, /* offset vector */ + offsetcount, /* size of same */ + workspace, /* workspace vector */ + wscount, /* size of same */ + 0); /* function recurse level */ + + /* Anything other than "no match" means we are done, always; otherwise, carry + on only if not anchored. */ + + if (rc != PCRE_ERROR_NOMATCH || anchored) return rc; + + /* Advance to the next subject character unless we are at the end of a line + and firstline is set. */ + + if (firstline && IS_NEWLINE(current_subject)) break; + current_subject++; +#ifdef SUPPORT_UTF + if (utf) + { + 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 + 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. */ + + if (RAWUCHARTEST(current_subject - 1) == CHAR_CR && + current_subject < end_subject && + RAWUCHARTEST(current_subject) == CHAR_NL && + (re->flags & PCRE_HASCRORLF) == 0 && + (md->nltype == NLTYPE_ANY || + md->nltype == NLTYPE_ANYCRLF || + md->nllen == 2)) + current_subject++; + + } /* "Bumpalong" loop */ + +return PCRE_ERROR_NOMATCH; +} + +/* End of pcre_dfa_exec.c */ diff --git a/tools/pcre/pcre_exec.c b/tools/pcre/pcre_exec.c new file mode 100644 index 00000000..05d0e52d --- /dev/null +++ b/tools/pcre/pcre_exec.c @@ -0,0 +1,7049 @@ +/************************************************* +* 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 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. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define NLBLOCK md /* Block containing newline information */ +#define PSSTART start_subject /* Field containing processed string start */ +#define PSEND end_subject /* Field containing processed string end */ + +#include "pcre_internal.h" + +/* Undefine some potentially clashing cpp symbols */ + +#undef min +#undef max + +/* 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 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. */ + +#define MATCH_MATCH 1 +#define MATCH_NOMATCH 0 + +/* Special internal returns from the match() function. Make them sufficiently +negative to avoid the external error codes. */ + +#define MATCH_ACCEPT (-999) +#define MATCH_COMMIT (-998) +#define MATCH_KETRPOS (-997) +#define MATCH_ONCE (-996) +#define MATCH_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, +because the offset vector is always a multiple of 3 long. */ + +#define REC_STACK_SAVE_MAX 30 + +/* Min and max values for the common repeats; for the maxima, 0 => infinity */ + +static const char rep_min[] = { 0, 0, 1, 1, 0, 0 }; +static const char rep_max[] = { 0, 0, 0, 0, 1, 1 }; + +#ifdef PCRE_DEBUG +/************************************************* +* Debugging function to print chars * +*************************************************/ + +/* Print a sequence of chars in printable format, stopping at the end of the +subject if the requested. + +Arguments: + p points to characters + length number to print + is_subject TRUE if printing from within md->start_subject + md pointer to matching data block, if is_subject is TRUE + +Returns: nothing +*/ + +static void +pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md) +{ +pcre_uint32 c; +BOOL utf = md->utf; +if (is_subject && length > md->end_subject - p) length = md->end_subject - p; +while (length-- > 0) + if (isprint(c = RAWUCHARINCTEST(p))) printf("%c", (char)c); else printf("\\x{%02x}", c); +} +#endif + + + +/************************************************* +* Match a back-reference * +*************************************************/ + +/* 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 pointer into the subject + length length of reference to be matched (number of bytes) + md points to match data block + caseless TRUE if caseless + +Returns: >= 0 the number of subject bytes matched + -1 no match + -2 partial match; always given if at end subject +*/ + +static int +match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md, + BOOL caseless) +{ +PCRE_PUCHAR eptr_start = eptr; +register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset]; +#ifdef SUPPORT_UTF +BOOL utf = md->utf; +#endif + +#ifdef PCRE_DEBUG +if (eptr >= md->end_subject) + printf("matching subject "); +else + { + printf("matching subject "); + pchars(eptr, length, TRUE, md); + } +printf(" against backref "); +pchars(p, length, FALSE, md); +printf("\n"); +#endif + +/* Always fail if reference not set (and not JavaScript compatible - in that +case the length is passed as zero). */ + +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 (caseless) + { +#ifdef SUPPORT_UTF +#ifdef SUPPORT_UCP + if (utf) + { + /* Match characters up to the end of the reference. NOTE: the number of + data units matched may differ, because in UTF-8 there are some characters + whose upper and lower case versions code have 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) + { + pcre_uint32 c, d; + const ucd_record *ur; + if (eptr >= md->end_subject) return -2; /* Partial match */ + GETCHARINC(c, eptr); + GETCHARINC(d, p); + ur = GET_UCD(d); + if (c != d && c != d + ur->other_case) + { + const pcre_uint32 *pp = PRIV(ucd_caseless_sets) + ur->caseset; + for (;;) + { + if (c < *pp) return -1; + if (c == *pp++) break; + } + } + } + } + else +#endif +#endif + + /* The same code works when not in UTF-8 mode and in UTF-8 mode when there + is no UCP support. */ + { + while (length-- > 0) + { + pcre_uchar cc, cp; + if (eptr >= md->end_subject) return -2; /* Partial match */ + cc = RAWUCHARTEST(eptr); + cp = RAWUCHARTEST(p); + if (TABLE_GET(cp, md->lcc, cp) != TABLE_GET(cc, md->lcc, cc)) 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 (eptr >= md->end_subject) return -2; /* Partial match */ + if (RAWUCHARINCTEST(p) != RAWUCHARINCTEST(eptr)) return -1; + } + } + +return (int)(eptr - eptr_start); +} + + + +/*************************************************************************** +**************************************************************************** + RECURSION IN THE match() FUNCTION + +The match() function is highly recursive, though not every recursive call +increases the recursive depth. Nevertheless, some regular expressions can cause +it to recurse to a great depth. I was writing for Unix, so I just let it call +itself recursively. This uses the stack for saving everything that has to be +saved for a recursive call. On Unix, the stack can be large, and this works +fine. + +It turns out that on some non-Unix-like systems there are problems with +programs that use a lot of stack. (This despite the fact that every last chip +has oodles of memory these days, and techniques for extending the stack have +been known for decades.) So.... + +There is a fudge, triggered by defining NO_RECURSE, which avoids recursive +calls by keeping local variables that need to be preserved in blocks of memory +obtained from malloc() instead instead of on the stack. Macros are used to +achieve this so that the actual code doesn't look very different to what it +always used to. + +The original heap-recursive code used longjmp(). However, it seems that this +can be very slow on some operating systems. Following a suggestion from Stan +Switzer, the use of longjmp() has been abolished, at the cost of having to +provide a unique number for each call to RMATCH. There is no way of generating +a sequence of numbers at compile time in C. I have given them names, to make +them stand out more clearly. + +Crude tests on x86 Linux show a small speedup of around 5-8%. However, on +FreeBSD, avoiding longjmp() more than halves the time taken to run the standard +tests. Furthermore, not using longjmp() means that local dynamic variables +don't have indeterminate values; this has meant that the frame size can be +reduced because the result can be "passed back" by straight setting of the +variable instead of being passed in the frame. +**************************************************************************** +***************************************************************************/ + +/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN +below must be updated in sync. */ + +enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, + RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, + RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, + 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, RM63, RM64, RM65, RM66, RM67 }; + +/* 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 +actually used in this definition. */ + +#ifndef NO_RECURSE +#define REGISTER register + +#ifdef PCRE_DEBUG +#define RMATCH(ra,rb,rc,rd,re,rw) \ + { \ + printf("match() called in line %d\n", __LINE__); \ + rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \ + printf("to line %d\n", __LINE__); \ + } +#define RRETURN(ra) \ + { \ + printf("match() returned %d from line %d\n", ra, __LINE__); \ + return ra; \ + } +#else +#define RMATCH(ra,rb,rc,rd,re,rw) \ + rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1) +#define RRETURN(ra) return ra +#endif + +#else + + +/* These versions of the macros manage a private stack on the heap. Note that +the "rd" argument of RMATCH isn't actually used in this definition. It's the md +argument of match(), which never changes. */ + +#define REGISTER + +#define RMATCH(ra,rb,rc,rd,re,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->Xoffset_top = rc;\ + newframe->Xeptrb = re;\ + newframe->Xrdepth = frame->Xrdepth + 1;\ + newframe->Xprevframe = frame;\ + frame = newframe;\ + DPRINTF(("restarting from line %d\n", __LINE__));\ + goto HEAP_RECURSE;\ + L_##rw:\ + DPRINTF(("jumped back to line %d\n", __LINE__));\ + } + +#define RRETURN(ra)\ + {\ + heapframe *oldframe = frame;\ + frame = oldframe->Xprevframe;\ + if (frame != NULL)\ + {\ + rrc = ra;\ + goto HEAP_RETURN;\ + }\ + return ra;\ + } + + +/* Structure for remembering the local variables in a private frame */ + +typedef struct heapframe { + struct heapframe *Xprevframe; + struct heapframe *Xnextframe; + + /* Function arguments that may change */ + + PCRE_PUCHAR Xeptr; + const pcre_uchar *Xecode; + PCRE_PUCHAR Xmstart; + int Xoffset_top; + eptrblock *Xeptrb; + unsigned int Xrdepth; + + /* Function local variables */ + + 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; + + BOOL Xcur_is_word; + BOOL Xcondition; + BOOL Xprev_is_word; + +#ifdef SUPPORT_UCP + int Xprop_type; + unsigned int Xprop_value; + int Xprop_fail_result; + int Xoclength; + pcre_uchar Xocchars[6]; +#endif + + int Xcodelink; + int Xctype; + unsigned int Xfc; + int Xfi; + int Xlength; + int Xmax; + int Xmin; + int Xnumber; + int Xoffset; + int Xop; + int Xsave_capture_last; + int Xsave_offset1, Xsave_offset2, Xsave_offset3; + int Xstacksave[REC_STACK_SAVE_MAX]; + + eptrblock Xnewptrb; + + /* Where to jump back to */ + + int Xwhere; + +} heapframe; + +#endif + + +/*************************************************************************** +***************************************************************************/ + + + +/************************************************* +* Match from current position * +*************************************************/ + +/* This function is called recursively in many circumstances. Whenever it +returns a negative (error) response, the outer incarnation must also return the +same response. */ + +/* These macros pack up tests that are used for partial matching, and which +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 +the subject. */ + +#define CHECK_PARTIAL()\ + if (md->partial != 0 && eptr >= md->end_subject && \ + eptr > md->start_used_ptr) \ + { \ + md->hitend = TRUE; \ + 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) RRETURN(PCRE_ERROR_PARTIAL); \ + } + + +/* Performance note: It might be tempting to extract commonly used fields from +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. + +Arguments: + eptr pointer to current character in subject + ecode pointer to current position in compiled code + mstart pointer to the current match start position (can be modified + by encountering \K) + offset_top current top pointer + md pointer to "static" info for the match + eptrb pointer to chain of blocks containing eptr at start of + brackets - for testing for empty matches + rdepth the recursion depth + +Returns: MATCH_MATCH if matched ) these values are >= 0 + MATCH_NOMATCH if failed to match ) + a negative MATCH_xxx value for PRUNE, SKIP, etc + a negative PCRE_ERROR_xxx value if aborted by an error condition + (e.g. stopped by repeated call or recursion limit) +*/ + +static int +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 +"register" because they are used a lot in loops. */ + +register int rrc; /* Returns from recursive calls */ +register int i; /* Used for loops not involving calls to RMATCH() */ +register pcre_uint32 c; /* Character values not kept over RMATCH() calls */ +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". 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 *)md->match_frames_base; + +/* Copy in the original argument variables */ + +frame->Xeptr = eptr; +frame->Xecode = ecode; +frame->Xmstart = mstart; +frame->Xoffset_top = offset_top; +frame->Xeptrb = eptrb; +frame->Xrdepth = rdepth; + +/* This is where control jumps back to to effect "recursion" */ + +HEAP_RECURSE: + +/* Macros make the argument variables come from the current frame */ + +#define eptr frame->Xeptr +#define ecode frame->Xecode +#define mstart frame->Xmstart +#define offset_top frame->Xoffset_top +#define eptrb frame->Xeptrb +#define rdepth frame->Xrdepth + +/* Ditto for the local variables */ + +#ifdef SUPPORT_UTF +#define charptr frame->Xcharptr +#endif +#define callpat frame->Xcallpat +#define codelink frame->Xcodelink +#define data frame->Xdata +#define next frame->Xnext +#define pp frame->Xpp +#define prev frame->Xprev +#define saved_eptr frame->Xsaved_eptr + +#define new_recursive frame->Xnew_recursive + +#define cur_is_word frame->Xcur_is_word +#define condition frame->Xcondition +#define prev_is_word frame->Xprev_is_word + +#ifdef SUPPORT_UCP +#define prop_type frame->Xprop_type +#define prop_value frame->Xprop_value +#define prop_fail_result frame->Xprop_fail_result +#define oclength frame->Xoclength +#define occhars frame->Xocchars +#endif + +#define ctype frame->Xctype +#define fc frame->Xfc +#define fi frame->Xfi +#define length frame->Xlength +#define max frame->Xmax +#define min frame->Xmin +#define number frame->Xnumber +#define offset frame->Xoffset +#define op frame->Xop +#define save_capture_last frame->Xsave_capture_last +#define save_offset1 frame->Xsave_offset1 +#define save_offset2 frame->Xsave_offset2 +#define save_offset3 frame->Xsave_offset3 +#define stacksave frame->Xstacksave + +#define newptrb frame->Xnewptrb + +/* When recursion is being used, local variables are allocated on the stack and +get preserved during recursion in the normal way. In this environment, fi and +i, and fc and c, can be the same variables. */ + +#else /* NO_RECURSE not defined */ +#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; + +BOOL cur_is_word; +BOOL condition; +BOOL prev_is_word; + +#ifdef SUPPORT_UCP +int prop_type; +unsigned int prop_value; +int prop_fail_result; +int oclength; +pcre_uchar occhars[6]; +#endif + +int codelink; +int ctype; +int length; +int max; +int min; +unsigned int number; +int offset; +pcre_uchar op; +int save_capture_last; +int save_offset1, save_offset2, save_offset3; +int stacksave[REC_STACK_SAVE_MAX]; + +eptrblock newptrb; + +/* There is a special fudge for calling match() in a way that causes it to +measure the size of its basic stack frame when the stack is being used for +recursion. The second argument (ecode) being NULL triggers this behaviour. It +cannot normally ever be NULL. The return is the negated value of the frame +size. */ + +if (ecode == NULL) + { + if (rdepth == 0) + return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1); + else + { + int len = (char *)&rdepth - (char *)eptr; + return (len > 0)? -len : len; + } + } +#endif /* NO_RECURSE */ + +/* To save space on the stack and in the heap frame, I have doubled up on some +of the local variables that are used only in localised parts of the code, but +still need to be preserved over recursive calls of match(). These macros define +the alternative names that are used. */ + +#define allow_zero cur_is_word +#define cbegroup condition +#define code_offset codelink +#define condassert condition +#define matched_once prev_is_word +#define foc number +#define save_mark data + +/* These statements are here to stop the compiler complaining about unitialized +variables. */ + +#ifdef SUPPORT_UCP +prop_value = 0; +prop_fail_result = 0; +#endif + + +/* This label is used for tail recursion, which is used in a few cases even +when NO_RECURSE is not defined, in order to reduce the amount of stack that is +used. Thanks to Ian Taylor for noticing this possibility and sending the +original patch. */ + +TAIL_RECURSE: + +/* OK, now we can get on with the real code of the function. Recursive calls +are specified by the macro RMATCH and RRETURN is used to return. When +NO_RECURSE is *not* defined, these just turn into a recursive call to match() +and a "return", respectively (possibly with some debugging if PCRE_DEBUG is +defined). However, RMATCH isn't like a function call because it's quite a +complicated macro. It has to be used in one particular way. This shouldn't, +however, impact performance when true recursion is being used. */ + +#ifdef SUPPORT_UTF +utf = md->utf; /* Local copy of the flag */ +#else +utf = FALSE; +#endif + +/* First check that we haven't called match() too many times, or that we +haven't exceeded the recursive call limit. */ + +if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT); +if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT); + +/* At the start of a group with an unlimited repeat that may match an empty +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 (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. */ + +for (;;) + { + minimize = possessive = FALSE; + op = *ecode; + + switch(op) + { + case OP_MARK: + 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 + argument. It is passed back in md->start_match_ptr (an overloading of that + variable). If it does match, we reset that variable to the current subject + position and return MATCH_SKIP. Otherwise, pass back the return code + unaltered. */ + + else if (rrc == MATCH_SKIP_ARG && + STRCMP_UC_UC_TEST(ecode + 2, md->start_match_ptr) == 0) + { + md->start_match_ptr = eptr; + RRETURN(MATCH_SKIP); + } + RRETURN(rrc); + + case OP_FAIL: + RRETURN(MATCH_NOMATCH); + + /* COMMIT overrides PRUNE, SKIP, and THEN */ + + case OP_COMMIT: + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM52); + if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && + rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG && + rrc != MATCH_THEN) + RRETURN(rrc); + RRETURN(MATCH_COMMIT); + + /* PRUNE overrides THEN */ + + case OP_PRUNE: + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM51); + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); + RRETURN(MATCH_PRUNE); + + case OP_PRUNE_ARG: + md->nomatch_mark = ecode + 2; + md->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, + eptrb, RM56); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + md->mark == NULL) md->mark = ecode + 2; + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); + RRETURN(MATCH_PRUNE); + + /* SKIP overrides PRUNE and THEN */ + + case OP_SKIP: + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM53); + if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) + RRETURN(rrc); + md->start_match_ptr = eptr; /* Pass back current position */ + RRETURN(MATCH_SKIP); + + /* Note that, for Perl compatibility, SKIP with an argument does NOT set + nomatch_mark. There is a flag that disables this opcode when re-matching a + pattern that ended with a SKIP for which there was not a matching MARK. */ + + case OP_SKIP_ARG: + 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 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 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 + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM54); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->start_match_ptr = ecode; + RRETURN(MATCH_THEN); + + case OP_THEN_ARG: + md->nomatch_mark = ecode + 2; + md->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, + md, eptrb, RM58); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + md->mark == NULL) md->mark = ecode + 2; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->start_match_ptr = ecode; + RRETURN(MATCH_THEN); + + /* 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 + case here; that is handled in the code for KET. */ + + case OP_CBRA: + case OP_SCBRA: + number = GET2(ecode, 1+LINK_SIZE); + offset = number << 1; + +#ifdef PCRE_DEBUG + printf("start bracket %d\n", number); + printf("subject="); + pchars(eptr, 16, TRUE, md); + printf("\n"); +#endif + + if (offset < md->offset_max) + { + 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; + 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); + + for (;;) + { + 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; + } + + 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; + + /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */ + + RRETURN(rrc); + } + + /* FALL THROUGH ... Insufficient room for saving captured contents. Treat + as a non-capturing bracket. */ + + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + + DPRINTF(("insufficient capture room: treat as non-capturing\n")); + + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + + /* Non-capturing or atomic group, except for possessive with unlimited + repeat and ONCE group with no captures. Loop for all the alternatives. + + When we get to the final alternative within the brackets, we used to return + the result of a recursive call to match() whatever happened so it was + possible to reduce stack usage by turning this into a tail recursion, + except in the case of a possibly empty group. However, now that there is + the possiblity of (*THEN) occurring in the final alternative, this + optimization is no longer always possible. + + We can optimize if we know there are no (*THEN)s in the pattern; at present + this is the best that can be done. + + MATCH_ONCE is returned when the end of an atomic group is successfully + reached, but subsequent matching fails. It passes back up the tree (causing + captured values to be reset) until the original atomic group level is + reached. This is tested by comparing md->once_target with the start of the + group. At this point, the return is converted into MATCH_NOMATCH so that + previous backup points can be taken. */ + + case OP_ONCE: + case OP_BRA: + case OP_SBRA: + DPRINTF(("start non-capturing bracket\n")); + + for (;;) + { + if (op >= OP_SBRA || op == OP_ONCE) + md->match_function_type = MATCH_CBEGROUP; + + /* If this is not a possibly empty group, and there are no (*THEN)s in + the pattern, and this is the final alternative, optimize as described + above. */ + + else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT) + { + ecode += PRIV(OP_lengths)[*ecode]; + goto TAIL_RECURSE; + } + + /* In all other cases, we have to make another call to match(). */ + + save_mark = md->mark; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, + RM2); + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) + { + if (rrc == MATCH_ONCE) + { + const pcre_uchar *scode = ecode; + if (*scode != OP_ONCE) /* If not at start, find it */ + { + while (*scode == OP_ALT) scode += GET(scode, 1); + scode -= GET(scode, 1); + } + if (md->once_target == scode) rrc = MATCH_NOMATCH; + } + RRETURN(rrc); + } + ecode += GET(ecode, 1); + md->mark = save_mark; + if (*ecode != OP_ALT) break; + } + + RRETURN(MATCH_NOMATCH); + + /* Handle possessive capturing brackets with an unlimited repeat. We come + here from BRAZERO with allow_zero set TRUE. The offset_vector values are + handled similarly to the normal case above. However, the matching is + different. The end of these brackets will always be OP_KETRPOS, which + returns MATCH_KETRPOS without going further in the pattern. By this means + we can handle the group by iteration rather than recursion, thereby + reducing the amount of stack needed. */ + + case OP_CBRAPOS: + case OP_SCBRAPOS: + allow_zero = FALSE; + + POSSESSIVE_CAPTURE: + number = GET2(ecode, 1+LINK_SIZE); + offset = number << 1; + +#ifdef PCRE_DEBUG + printf("start possessive bracket %d\n", number); + printf("subject="); + pchars(eptr, 16, TRUE, md); + printf("\n"); +#endif + + if (offset < md->offset_max) + { + matched_once = FALSE; + code_offset = (int)(ecode - md->start_code); + + save_offset1 = md->offset_vector[offset]; + save_offset2 = md->offset_vector[offset+1]; + save_offset3 = md->offset_vector[md->offset_end - number]; + save_capture_last = md->capture_last; + + DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); + + /* Each time round the loop, save the current subject position for use + when the group matches. For MATCH_MATCH, the group has matched, so we + restart it with a new subject starting position, remembering that we had + at least one match. For MATCH_NOMATCH, carry on with the alternatives, as + usual. If we haven't matched any alternatives in any iteration, check to + see if a previous iteration matched. If so, the group has matched; + continue from afterwards. Otherwise it has failed; restore the previous + capture values before returning NOMATCH. */ + + for (;;) + { + md->offset_vector[md->offset_end - number] = + (int)(eptr - md->start_subject); + if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM63); + if (rrc == MATCH_KETRPOS) + { + offset_top = md->end_offset_top; + eptr = md->end_match_ptr; + ecode = md->start_code + code_offset; + save_capture_last = md->capture_last; + matched_once = TRUE; + continue; + } + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->capture_last = save_capture_last; + ecode += GET(ecode, 1); + if (*ecode != OP_ALT) break; + } + + if (!matched_once) + { + md->offset_vector[offset] = save_offset1; + md->offset_vector[offset+1] = save_offset2; + md->offset_vector[md->offset_end - number] = save_offset3; + } + + if (allow_zero || matched_once) + { + ecode += 1 + LINK_SIZE; + break; + } + + RRETURN(MATCH_NOMATCH); + } + + /* 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. */ + + case OP_COND: + case OP_SCOND: + 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 (PUBL(callout) != NULL) + { + 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; +#if defined COMPILE_PCRE8 + cb.subject = (PCRE_SPTR)md->start_subject; +#elif defined COMPILE_PCRE16 + cb.subject = (PCRE_SPTR16)md->start_subject; +#elif defined COMPILE_PCRE32 + cb.subject = (PCRE_SPTR32)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); + cb.pattern_position = GET(ecode, LINK_SIZE + 3); + cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE); + cb.capture_top = offset_top/2; + cb.capture_last = md->capture_last; + cb.callout_data = md->callout_data; + cb.mark = md->nomatch_mark; + if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); + if (rrc < 0) RRETURN(rrc); + } + ecode += PRIV(OP_lengths)[OP_CALLOUT]; + } + + condcode = ecode[LINK_SIZE+1]; + + /* Now see what the actual condition is */ + + if (condcode == OP_RREF || condcode == OP_NRREF) /* Recursion test */ + { + if (md->recursive == NULL) /* Not recursing => FALSE */ + { + condition = FALSE; + ecode += GET(ecode, 1); + } + else + { + unsigned int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/ + 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) + { + pcre_uchar *slotA = md->name_table; + for (i = 0; i < md->name_count; i++) + { + if (GET2(slotA, 0) == recno) break; + slotA += md->name_entry_size; + } + + /* Found a name for the number - there can be only one; duplicate + names for different numbers are allowed, but not vice versa. First + scan down for duplicates. */ + + if (i < md->name_count) + { + pcre_uchar *slotB = slotA; + while (slotB > md->name_table) + { + slotB -= md->name_entry_size; + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) + { + condition = GET2(slotB, 0) == md->recursive->group_num; + if (condition) break; + } + else break; + } + + /* Scan up for duplicates */ + + if (!condition) + { + slotB = slotA; + for (i++; i < md->name_count; i++) + { + slotB += md->name_entry_size; + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) + { + condition = GET2(slotB, 0) == md->recursive->group_num; + if (condition) break; + } + else break; + } + } + } + } + + /* Chose branch according to the condition */ + + ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); + } + } + + else if (condcode == OP_CREF || condcode == OP_NCREF) /* Group used test */ + { + offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */ + condition = offset < offset_top && md->offset_vector[offset] >= 0; + + /* If the numbered capture is unset, but the reference was by name, + scan the table to see if the name refers to any other numbers, and test + them. The condition is true if any one is set. This is tediously similar + to the code above, but not close enough to try to amalgamate. */ + + if (!condition && condcode == OP_NCREF) + { + unsigned int refno = offset >> 1; + pcre_uchar *slotA = md->name_table; + + for (i = 0; i < md->name_count; i++) + { + if (GET2(slotA, 0) == refno) break; + slotA += md->name_entry_size; + } + + /* Found a name for the number - there can be only one; duplicate names + for different numbers are allowed, but not vice versa. First scan down + for duplicates. */ + + if (i < md->name_count) + { + pcre_uchar *slotB = slotA; + while (slotB > md->name_table) + { + slotB -= md->name_entry_size; + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) + { + offset = GET2(slotB, 0) << 1; + condition = offset < offset_top && + md->offset_vector[offset] >= 0; + if (condition) break; + } + else break; + } + + /* Scan up for duplicates */ + + if (!condition) + { + slotB = slotA; + for (i++; i < md->name_count; i++) + { + slotB += md->name_entry_size; + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) + { + offset = GET2(slotB, 0) << 1; + condition = offset < offset_top && + md->offset_vector[offset] >= 0; + if (condition) break; + } + else break; + } + } + } + } + + /* Chose branch according to the condition */ + + ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); + } + + else if (condcode == OP_DEF) /* DEFINE - always false */ + { + condition = FALSE; + ecode += GET(ecode, 1); + } + + /* The condition is an assertion. Call match() to evaluate it - setting + md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of + an assertion. */ + + else + { + 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); + } + + /* 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 */ + } + else + { + condition = FALSE; + ecode += codelink; + } + } + + /* 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) + { + if (op != OP_SCOND) + { + ecode += 1 + LINK_SIZE; + goto TAIL_RECURSE; + } + + md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49); + RRETURN(rrc); + } + + /* Condition false & no alternative; continue after the group. */ + + else + { + ecode += 1 + LINK_SIZE; + } + break; + + + /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes, + to close any currently open capturing brackets. */ + + case OP_CLOSE: + number = GET2(ecode, 1); + offset = number << 1; + +#ifdef PCRE_DEBUG + printf("end bracket %d at *ACCEPT", number); + printf("\n"); +#endif + + md->capture_last = number; + if (offset >= md->offset_max) md->offset_overflow = TRUE; else + { + 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; + } + ecode += 1 + IMM2_SIZE; + break; + + + /* End of the pattern, either real or forced. */ + + case OP_END: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + + /* 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. */ + + md->end_match_ptr = eptr; /* Record where we ended */ + md->end_offset_top = offset_top; /* and how many extracts were taken */ + 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 RRETURN when the heap is in use. */ + + rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT; + 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. 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, NULL, RM4); + if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) + { + mstart = md->start_match_ptr; /* In case \K reset it */ + break; + } + 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) RRETURN(MATCH_NOMATCH); + + /* If checking an assertion for a condition, return 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. */ + + do ecode += GET(ecode,1); while (*ecode == OP_ALT); + ecode += 1 + LINK_SIZE; + offset_top = md->end_offset_top; + continue; + + /* Negative assertion: all branches must fail to match. Encountering SKIP, + PRUNE, or COMMIT means we must assume failure without checking subsequent + branches. */ + + 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, 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; + } + + /* 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 (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */ + + ecode += 1 + LINK_SIZE; + continue; + + /* Move the subject pointer back. This occurs only at the start of + each branch of a lookbehind assertion. If we are too close to the start to + move back, this match function fails. When working with UTF-8 we move + back a number of characters, not bytes. */ + + case OP_REVERSE: +#ifdef SUPPORT_UTF + if (utf) + { + i = GET(ecode, 1); + while (i-- > 0) + { + eptr--; + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); + BACKCHAR(eptr); + } + } + else +#endif + + /* No UTF-8 support, or not in UTF-8 mode: count is byte count */ + + { + eptr -= GET(ecode, 1); + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); + } + + /* Save the earliest consulted character, then skip to next op code */ + + if (eptr < md->start_used_ptr) md->start_used_ptr = eptr; + ecode += 1 + LINK_SIZE; + break; + + /* The callout item calls an external function, if one is provided, passing + details of the match so far. This is mainly for debugging, though the + function is able to force a failure. */ + + case OP_CALLOUT: + if (PUBL(callout) != NULL) + { + PUBL(callout_block) cb; + cb.version = 2; /* Version 1 of the callout block */ + cb.callout_number = ecode[1]; + cb.offset_vector = md->offset_vector; +#if defined COMPILE_PCRE8 + cb.subject = (PCRE_SPTR)md->start_subject; +#elif defined COMPILE_PCRE16 + cb.subject = (PCRE_SPTR16)md->start_subject; +#elif defined COMPILE_PCRE32 + cb.subject = (PCRE_SPTR32)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); + cb.pattern_position = GET(ecode, 2); + cb.next_item_length = GET(ecode, 2 + LINK_SIZE); + cb.capture_top = offset_top/2; + cb.capture_last = md->capture_last; + cb.callout_data = md->callout_data; + cb.mark = md->nomatch_mark; + if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); + if (rrc < 0) RRETURN(rrc); + } + ecode += 2 + 2*LINK_SIZE; + break; + + /* Recursion either matches the current regex, or some subexpression. The + 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.) + + 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. 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; + unsigned int recno; + + callpat = md->start_code + GET(ecode, 1); + 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; + + /* Where to continue from afterwards */ + + ecode += 1 + LINK_SIZE; + + /* Now save the offset data */ + + new_recursive.saved_max = md->offset_end; + if (new_recursive.saved_max <= REC_STACK_SAVE_MAX) + new_recursive.offset_save = stacksave; + else + { + new_recursive.offset_save = + (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)); + + /* 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)); + cbegroup = (*callpat >= OP_SBRA); + do + { + 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")); + if (new_recursive.offset_save != stacksave) + (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 */ + } + + /* 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) + (PUBL(free))(new_recursive.offset_save); + RRETURN(rrc); + } + + md->recursive = &new_recursive; + callpat += GET(callpat, 1); + } + while (*callpat == OP_ALT); + + DPRINTF(("Recursion didn't match\n")); + md->recursive = new_recursive.prevrec; + if (new_recursive.offset_save != stacksave) + (PUBL(free))(new_recursive.offset_save); + RRETURN(MATCH_NOMATCH); + } + + 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. */ + + case OP_ALT: + do ecode += GET(ecode,1); while (*ecode == OP_ALT); + break; + + /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group, + indicating that it may occur zero times. It may repeat infinitely, or not + at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets + with fixed upper repeat limits are compiled as a number of copies, with the + optional ones preceded by BRAZERO or BRAMINZERO. */ + + case OP_BRAZERO: + 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, 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; + 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 || *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 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_NC */ + md->end_offset_top = offset_top; + md->start_match_ptr = mstart; + 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. 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 || + *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 + + /* 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; + } + } + + /* For an ordinary non-repeating ket, just continue at this level. This + also happens for a repeating ket if no characters were matched in the + group. This is the forcible breaking of infinite loops as implemented in + Perl 5.005. For a non-repeating atomic group that includes captures, + establish a backup point by processing the rest of the pattern at a lower + level. If this results in a NOMATCH return, pass MATCH_ONCE back to the + original OP_ONCE level, thereby bypassing intermediate backup points, but + resetting any captures that happened along the way. */ + + if (*ecode == OP_KET || eptr == saved_eptr) + { + if (*prev == OP_ONCE) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM12); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ + RRETURN(MATCH_ONCE); + } + ecode += 1 + LINK_SIZE; /* Carry on at this level */ + break; + } + + /* 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_KETRPOS) + { + md->end_match_ptr = eptr; + md->end_offset_top = offset_top; + RRETURN(MATCH_KETRPOS); + } + + /* The normal repeating kets try the rest of the pattern or restart from + the preceding bracket, in the appropriate order. In the second case, we can + use tail recursion to avoid using another stack frame, unless we have an + an atomic group or an unlimited repeat of a group that can match an empty + string. */ + + if (*ecode == OP_KETRMIN) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM7); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + 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, eptrb, RM50); + RRETURN(rrc); + } + ecode = prev; + goto TAIL_RECURSE; + } + else /* OP_KETRMAX */ + { + 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; + goto TAIL_RECURSE; + } + /* Control never gets here */ + + /* Not multiline mode: start of subject assertion, unless notbol. */ + + case OP_CIRC: + if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); + + /* Start of subject assertion */ + + case OP_SOD: + 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) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* Reset the start of match point */ + + case OP_SET_SOM: + mstart = eptr; + ecode++; + break; + + /* Multiline mode: assert before any newline, or before end of subject + unless noteol is set. */ + + case OP_DOLLM: + if (eptr < md->end_subject) + { + if (!IS_NEWLINE(eptr)) + { + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + RAWUCHARTEST(eptr) == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + RRETURN(MATCH_NOMATCH); + } + } + else + { + if (md->noteol) RRETURN(MATCH_NOMATCH); + SCHECK_PARTIAL(); + } + ecode++; + break; + + /* Not multiline mode: assert before a terminating newline or before end of + subject unless noteol is set. */ + + case OP_DOLL: + if (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) RRETURN(MATCH_NOMATCH); + SCHECK_PARTIAL(); + ecode++; + break; + + /* End of subject or ending \n assertion (\Z) */ + + case OP_EODN: + ASSERT_NL_OR_EOS: + if (eptr < md->end_subject && + (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen)) + { + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + RAWUCHARTEST(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. */ + + SCHECK_PARTIAL(); + ecode++; + break; + + /* Word boundary assertions */ + + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + { + + /* Find out if the previous and current characters are "word" characters. + It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to + be "non-word" characters. Remember the earliest consulted character for + partial matching. */ + +#ifdef SUPPORT_UTF + if (utf) + { + /* Get status of previous character */ + + if (eptr == md->start_subject) prev_is_word = FALSE; else + { + PCRE_PUCHAR lastptr = eptr - 1; + BACKCHAR(lastptr); + if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr; + GETCHAR(c, lastptr); +#ifdef SUPPORT_UCP + if (md->use_ucp) + { + if (c == '_') prev_is_word = TRUE; else + { + int cat = UCD_CATEGORY(c); + prev_is_word = (cat == ucp_L || cat == ucp_N); + } + } + else +#endif + prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0; + } + + /* Get status of next character */ + + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + cur_is_word = FALSE; + } + else + { + GETCHAR(c, eptr); +#ifdef SUPPORT_UCP + if (md->use_ucp) + { + if (c == '_') cur_is_word = TRUE; else + { + int cat = UCD_CATEGORY(c); + cur_is_word = (cat == ucp_L || cat == ucp_N); + } + } + else +#endif + cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0; + } + } + else +#endif + + /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for + consistency with the behaviour of \w we do use it in this case. */ + + { + /* Get status of previous character */ + + if (eptr == md->start_subject) prev_is_word = FALSE; else + { + if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1; +#ifdef SUPPORT_UCP + if (md->use_ucp) + { + c = eptr[-1]; + if (c == '_') prev_is_word = TRUE; else + { + int cat = UCD_CATEGORY(c); + prev_is_word = (cat == ucp_L || cat == ucp_N); + } + } + else +#endif + prev_is_word = MAX_255(eptr[-1]) + && ((md->ctypes[eptr[-1]] & ctype_word) != 0); + } + + /* Get status of next character */ + + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + cur_is_word = FALSE; + } + else +#ifdef SUPPORT_UCP + if (md->use_ucp) + { + c = *eptr; + if (c == '_') cur_is_word = TRUE; else + { + int cat = UCD_CATEGORY(c); + cur_is_word = (cat == ucp_L || cat == ucp_N); + } + } + else +#endif + 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) + RRETURN(MATCH_NOMATCH); + } + break; + + /* Match any single character type except newline; have to take care with + CRLF newlines and partial matching. */ + + case OP_ANY: + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + RAWUCHARTEST(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) /* DO NOT merge the eptr++ here; it must */ + { /* not be updated before SCHECK_PARTIAL. */ + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr++; +#ifdef SUPPORT_UTF + if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); +#endif + ecode++; + break; + + /* Match a single byte, even in UTF-8 mode. This opcode really does match + any byte, even newline, independent of the setting of PCRE_DOTALL. */ + + case OP_ANYBYTE: + if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */ + { /* not be updated before SCHECK_PARTIAL. */ + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr++; + ecode++; + break; + + case OP_NOT_DIGIT: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c < 256 && +#endif + (md->ctypes[c] & ctype_digit) != 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_DIGIT: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c > 255 || +#endif + (md->ctypes[c] & ctype_digit) == 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_NOT_WHITESPACE: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c < 256 && +#endif + (md->ctypes[c] & ctype_space) != 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_WHITESPACE: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c > 255 || +#endif + (md->ctypes[c] & ctype_space) == 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_NOT_WORDCHAR: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c < 256 && +#endif + (md->ctypes[c] & ctype_word) != 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_WORDCHAR: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ( +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c > 255 || +#endif + (md->ctypes[c] & ctype_word) == 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_ANYNL: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + + case CHAR_CR: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + } + else if (RAWUCHARTEST(eptr) == CHAR_LF) eptr++; + break; + + case CHAR_LF: + break; + + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); + break; + } + ecode++; + break; + + case OP_NOT_HSPACE: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */ + default: break; + } + ecode++; + break; + + case OP_HSPACE: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + HSPACE_CASES: break; /* Byte and multibyte cases */ + default: RRETURN(MATCH_NOMATCH); + } + ecode++; + break; + + case OP_NOT_VSPACE: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + VSPACE_CASES: RRETURN(MATCH_NOMATCH); + default: break; + } + ecode++; + break; + + case OP_VSPACE: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + switch(c) + { + VSPACE_CASES: break; + default: RRETURN(MATCH_NOMATCH); + } + ecode++; + break; + +#ifdef SUPPORT_UCP + /* Check the next character by Unicode property. We will get here only + if the support is in the binary; otherwise a compile-time error occurs. */ + + case OP_PROP: + case OP_NOTPROP: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + { + const pcre_uint32 *cp; + const ucd_record *prop = GET_UCD(c); + + switch(ecode[1]) + { + case PT_ANY: + 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)) + RRETURN(MATCH_NOMATCH); + break; + + case PT_GC: + 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)) + RRETURN(MATCH_NOMATCH); + break; + + case PT_SC: + if ((ecode[2] != prop->script) == (op == OP_PROP)) + RRETURN(MATCH_NOMATCH); + break; + + /* These are specials */ + + case PT_ALNUM: + 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 ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || + c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) + == (op == OP_NOTPROP)) + RRETURN(MATCH_NOMATCH); + break; + + case PT_PXSPACE: /* POSIX space */ + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || + c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || + c == CHAR_FF || c == CHAR_CR) + == (op == OP_NOTPROP)) + RRETURN(MATCH_NOMATCH); + break; + + case PT_WORD: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE) == (op == OP_NOTPROP)) + RRETURN(MATCH_NOMATCH); + break; + + case PT_CLIST: + cp = PRIV(ucd_caseless_sets) + ecode[2]; + for (;;) + { + if (c < *cp) + { if (op == OP_PROP) { RRETURN(MATCH_NOMATCH); } else break; } + if (c == *cp++) + { if (op == OP_PROP) break; else { RRETURN(MATCH_NOMATCH); } } + } + break; + + /* This should never occur */ + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + + ecode += 3; + } + break; + + /* Match an extended Unicode sequence. We will get here only if the support + is in the binary; otherwise a compile-time error occurs. */ + + case OP_EXTUNI: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + else + { + int lgb, rgb; + GETCHARINCTEST(c, eptr); + lgb = UCD_GRAPHBREAK(c); + while (eptr < md->end_subject) + { + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + rgb = UCD_GRAPHBREAK(c); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + lgb = rgb; + eptr += len; + } + } + CHECK_PARTIAL(); + ecode++; + break; +#endif /* SUPPORT_UCP */ + + + /* Match a back reference, possibly repeatedly. Look past the end of the + item to see if there is repeat information following. The code is similar + to that for character classes, but repeated for efficiency. Then obey + similar code to character type repeats - written out again for speed. + However, if the referenced string is the empty string, always treat + it as matched, any number of times (otherwise there could be infinite + loops). */ + + case OP_REF: + case OP_REFI: + caseless = op == OP_REFI; + offset = GET2(ecode, 1) << 1; /* Doubled ref number */ + ecode += 1 + IMM2_SIZE; + + /* If the reference is unset, there are two possibilities: + + (a) In the default, Perl-compatible state, set the length negative; + this ensures that every attempt at a match fails. We can't just fail + here, because of the possibility of quantifiers with zero minima. + + (b) If the JavaScript compatibility flag is set, set the length to zero + so that the back reference matches an empty string. + + Otherwise, set the length to the length of what was matched by the + referenced subpattern. */ + + if (offset >= offset_top || md->offset_vector[offset] < 0) + length = (md->jscript_compat)? 0 : -1; + else + length = md->offset_vector[offset+1] - md->offset_vector[offset]; + + /* Set up for repetition, or handle the non-repeated case */ + + switch (*ecode) + { + 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, 1 + IMM2_SIZE); + if (max == 0) max = INT_MAX; + ecode += 1 + 2 * IMM2_SIZE; + break; + + 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 */ + } + + /* 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 && min == 0) continue; + + /* First, ensure the minimum number of matches are present. We get back + the length of the reference string explicitly rather than passing the + address of eptr, so that eptr can be a register variable. */ + + for (i = 1; i <= min; i++) + { + int slength; + if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) + { + if (slength == -2) eptr = md->end_subject; /* Partial match */ + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr += slength; + } + + /* If min = max, continue at the same level without recursion. + They are not both allowed to be zero. */ + + if (min == max) continue; + + /* If minimizing, keep trying and advancing the pointer */ + + if (minimize) + { + for (fi = min;; fi++) + { + int slength; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM14); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) + { + if (slength == -2) eptr = md->end_subject; /* Partial match */ + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr += slength; + } + /* Control never gets here */ + } + + /* If maximizing, find the longest string and work backwards */ + + else + { + pp = eptr; + for (i = min; i < max; i++) + { + int slength; + if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) + { + /* 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) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + break; + } + 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 */ + + /* Match a bit-mapped character class, possibly repeatedly. This op code is + used when all the characters in the class have values in the range 0-255, + and either the matching is caseful, or the characters are in the range + 0-127 when UTF-8 processing is enabled. The only difference between + OP_CLASS and OP_NCLASS occurs when a data character outside the range is + encountered. + + First, look past the end of the item to see if there is repeat information + following. Then obey similar code to character type repeats - written out + again for speed. */ + + 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 += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */ + + 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, 1 + IMM2_SIZE); + if (max == 0) max = INT_MAX; + ecode += 1 + 2 * IMM2_SIZE; + break; + + default: /* No repeat follows */ + min = max = 1; + break; + } + + /* First, ensure the minimum number of matches are present. */ + +#ifdef SUPPORT_UTF + if (utf) + { + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + c = *eptr++; +#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); + } + } + + /* If max == min we can continue with the main loop without the + need to recurse. */ + + if (min == max) continue; + + /* If minimizing, keep testing the rest of the expression and advancing + the pointer while it matches the class. */ + + if (minimize) + { +#ifdef SUPPORT_UTF + if (utf) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM16); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM17); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + c = *eptr++; +#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 */ + } + + /* If maximizing, find the longest possible run, then work backwards. */ + + else + { + pp = eptr; + +#ifdef SUPPORT_UTF + if (utf) + { + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c > 255) + { + if (op == OP_CLASS) break; + } + else + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; + eptr += len; + } + for (;;) + { + 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); + } + } + else +#endif + /* Not UTF mode */ + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + c = *eptr; +#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, eptrb, RM19); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + } + } + + RRETURN(MATCH_NOMATCH); + } +#undef BYTE_MAP + } + /* Control never gets here */ + + + /* Match an extended character class. This opcode is encountered only + when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8 + mode, because Unicode properties are supported in non-UTF-8 mode. */ + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + { + data = ecode + 1 + LINK_SIZE; /* Save for matching */ + ecode += GET(ecode, 1); /* Advance past the item */ + + 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, 1 + IMM2_SIZE); + if (max == 0) max = INT_MAX; + ecode += 1 + 2 * IMM2_SIZE; + break; + + default: /* No repeat follows */ + min = max = 1; + break; + } + + /* First, ensure the minimum number of matches are present. */ + + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); + } + + /* If max == min we can continue with the main loop without the + need to recurse. */ + + if (min == max) continue; + + /* If minimizing, keep testing the rest of the expression and advancing + the pointer while it matches the class. */ + + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM20); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + + /* If maximizing, find the longest possible run, then work backwards. */ + + else + { + pp = eptr; + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } +#ifdef SUPPORT_UTF + GETCHARLENTEST(c, eptr, len); +#else + c = *eptr; +#endif + if (!PRIV(xclass)(c, data, utf)) break; + eptr += len; + } + for(;;) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM21); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr-- == pp) break; /* Stop if tried at original pos */ +#ifdef SUPPORT_UTF + if (utf) BACKCHAR(eptr); +#endif + } + RRETURN(MATCH_NOMATCH); + } + + /* Control never gets here */ + } +#endif /* End of XCLASS */ + + /* Match a single character, casefully */ + + case OP_CHAR: +#ifdef SUPPORT_UTF + if (utf) + { + length = 1; + ecode++; + GETCHARLEN(fc, ecode, length); + if (length > md->end_subject - eptr) + { + CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */ + RRETURN(MATCH_NOMATCH); + } + while (length-- > 0) if (*ecode++ != RAWUCHARINC(eptr)) RRETURN(MATCH_NOMATCH); + } + else +#endif + /* Not UTF mode */ + { + if (md->end_subject - eptr < 1) + { + SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */ + RRETURN(MATCH_NOMATCH); + } + if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH); + ecode += 2; + } + break; + + /* 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); + } + +#ifdef SUPPORT_UTF + if (utf) + { + length = 1; + ecode++; + GETCHARLEN(fc, ecode, length); + + /* If the pattern character's value is < 128, we have only one byte, and + 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) + { + pcre_uchar cc = RAWUCHAR(eptr); + if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH); + ecode++; + eptr++; + } + + /* 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 + { + pcre_uint32 dc; + GETCHARINC(dc, eptr); + ecode += length; + + /* If we have Unicode property support, we can use it to test the other + case of the character, if there is one. */ + + if (fc != dc) + { +#ifdef SUPPORT_UCP + if (dc != UCD_OTHERCASE(fc)) +#endif + RRETURN(MATCH_NOMATCH); + } + } + } + else +#endif /* SUPPORT_UTF */ + + /* Not UTF mode */ + { + if (TABLE_GET(ecode[1], md->lcc, ecode[1]) + != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH); + eptr++; + ecode += 2; + } + break; + + /* Match a single character repeatedly. */ + + case OP_EXACT: + case OP_EXACTI: + min = max = GET2(ecode, 1); + 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 == OP_MINUPTOI; + ecode += 1 + IMM2_SIZE; + goto REPEATCHAR; + + case OP_POSSTAR: + case OP_POSSTARI: + possessive = TRUE; + min = 0; + max = INT_MAX; + ecode++; + goto REPEATCHAR; + + case OP_POSPLUS: + case OP_POSPLUSI: + possessive = TRUE; + min = 1; + max = INT_MAX; + ecode++; + goto REPEATCHAR; + + case OP_POSQUERY: + case OP_POSQUERYI: + possessive = TRUE; + min = 0; + max = 1; + ecode++; + 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: + 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; + + /* Common code for all repeated single-character matches. */ + + REPEATCHAR: +#ifdef SUPPORT_UTF + if (utf) + { + length = 1; + charptr = ecode; + GETCHARLEN(fc, ecode, length); + ecode += length; + + /* Handle multibyte character matching specially here. There is + support for caseless matching if UCP support is present. */ + + if (length > 1) + { +#ifdef SUPPORT_UCP + pcre_uint32 othercase; + if (op >= OP_STARI && /* Caseless */ + (othercase = UCD_OTHERCASE(fc)) != fc) + 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, IN_UCHARS(length)) == 0) eptr += length; +#ifdef SUPPORT_UCP + else if (oclength > 0 && + eptr <= md->end_subject - oclength && + memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; +#endif /* SUPPORT_UCP */ + else + { + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + } + + if (min == max) continue; + + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM22); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr <= md->end_subject - 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, IN_UCHARS(oclength)) == 0) eptr += oclength; +#endif /* SUPPORT_UCP */ + else + { + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + } + + else /* Maximize */ + { + pp = eptr; + for (i = min; i < max; i++) + { + if (eptr <= md->end_subject - 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, IN_UCHARS(oclength)) == 0) eptr += oclength; +#endif /* SUPPORT_UCP */ + else + { + CHECK_PARTIAL(); + break; + } + } + + if (possessive) continue; + + for(;;) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM23); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr == pp) { RRETURN(MATCH_NOMATCH); } +#ifdef SUPPORT_UCP + eptr--; + BACKCHAR(eptr); +#else /* without SUPPORT_UCP */ + eptr -= length; +#endif /* SUPPORT_UCP */ + } + } + /* Control never gets here */ + } + + /* If the length of a UTF-8 character is 1, we fall through here, and + obey the code as for non-UTF-8 characters below, though in this case the + value of fc will always be < 128. */ + } + else +#endif /* SUPPORT_UTF */ + /* When not in UTF-8 mode, load a single-byte character. */ + fc = *ecode++; + + /* 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 + minimizing, keep trying the rest of the expression and advancing one + matching character if failing, up to the maximum. Alternatively, if + maximizing, find the maximum number of characters and work backwards. */ + + DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max, + max, (char *)eptr)); + + if (op >= OP_STARI) /* Caseless */ + { +#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++) + { + pcre_uchar cc; + + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = RAWUCHARTEST(eptr); + if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH); + eptr++; + } + if (min == max) continue; + if (minimize) + { + for (fi = min;; fi++) + { + pcre_uchar cc; + + RMATCH(eptr, ecode, offset_top, md, eptrb, RM24); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = RAWUCHARTEST(eptr); + if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH); + eptr++; + } + /* Control never gets here */ + } + else /* Maximize */ + { + pp = eptr; + for (i = min; i < max; i++) + { + pcre_uchar cc; + + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + cc = RAWUCHARTEST(eptr); + if (fc != cc && foc != cc) break; + eptr++; + } + + if (possessive) continue; + + while (eptr >= pp) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM25); + eptr--; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + + /* Caseful comparisons (includes all multi-byte characters) */ + + else + { + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH); + } + + if (min == max) continue; + + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM26); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + else /* Maximize */ + { + pp = eptr; + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (fc != RAWUCHARTEST(eptr)) break; + eptr++; + } + if (possessive) continue; + + while (eptr >= pp) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM27); + eptr--; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + + /* Match a negated single one-byte character. The character we are + checking can be multibyte. */ + + case OP_NOT: + case OP_NOTI: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } +#ifdef SUPPORT_UTF + if (utf) + { + register pcre_uint32 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 + { + register pcre_uint32 ch = ecode[1]; + c = *eptr++; + if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c)) + RRETURN(MATCH_NOMATCH); + ecode += 2; + } + break; + + /* Match a negated single one-byte character repeatedly. This is almost a + repeat of the code for a repeated single character, but I haven't found a + nice way of commoning these up that doesn't require a test of the + positive/negative option for each character match. Maybe that wouldn't add + very much to the time taken, but character matching *is* what this is all + about... */ + + case OP_NOTEXACT: + case OP_NOTEXACTI: + min = max = GET2(ecode, 1); + 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 == OP_NOTMINUPTOI; + ecode += 1 + IMM2_SIZE; + goto REPEATNOTCHAR; + + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + possessive = TRUE; + min = 0; + max = INT_MAX; + ecode++; + goto REPEATNOTCHAR; + + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + possessive = TRUE; + min = 1; + max = INT_MAX; + ecode++; + goto REPEATNOTCHAR; + + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + possessive = TRUE; + min = 0; + max = 1; + ecode++; + goto REPEATNOTCHAR; + + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + possessive = TRUE; + min = 0; + max = GET2(ecode, 1); + 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: + 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 */ + if (max == 0) max = INT_MAX; + + /* Common code for all repeated single-byte matches. */ + + REPEATNOTCHAR: + 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 + minimum number of matches are present. If min = max, continue at the same + level without recursing. Otherwise, if minimizing, keep trying the rest of + the expression and advancing one matching character if failing, up to the + maximum. Alternatively, if maximizing, find the maximum number of + characters and work backwards. */ + + DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max, + max, (char *)eptr)); + + if (op >= OP_NOTSTARI) /* Caseless */ + { +#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_UTF + if (utf) + { + register pcre_uint32 d; + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(d, eptr); + if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); + eptr++; + } + } + + if (min == max) continue; + + if (minimize) + { +#ifdef SUPPORT_UTF + if (utf) + { + register pcre_uint32 d; + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM28); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(d, eptr); + if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM29); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); + eptr++; + } + } + /* Control never gets here */ + } + + /* Maximize case */ + + else + { + pp = eptr; + +#ifdef SUPPORT_UTF + if (utf) + { + register pcre_uint32 d; + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(d, eptr, len); + if (fc == d || (unsigned int)foc == d) break; + eptr += len; + } + if (possessive) continue; + for(;;) + { + 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); + } + } + else +#endif + /* Not UTF mode */ + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (fc == *eptr || foc == *eptr) break; + eptr++; + } + if (possessive) continue; + while (eptr >= pp) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM31); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + } + } + + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + + /* Caseful comparisons */ + + else + { +#ifdef SUPPORT_UTF + if (utf) + { + register pcre_uint32 d; + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(d, eptr); + if (fc == d) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc == *eptr++) RRETURN(MATCH_NOMATCH); + } + } + + if (min == max) continue; + + if (minimize) + { +#ifdef SUPPORT_UTF + if (utf) + { + register pcre_uint32 d; + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM32); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(d, eptr); + if (fc == d) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF mode */ + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM33); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (fc == *eptr++) RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + } + + /* Maximize case */ + + else + { + pp = eptr; + +#ifdef SUPPORT_UTF + if (utf) + { + register pcre_uint32 d; + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(d, eptr, len); + if (fc == d) break; + eptr += len; + } + if (possessive) continue; + for(;;) + { + 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); + } + } + else +#endif + /* Not UTF mode */ + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (fc == *eptr) break; + eptr++; + } + if (possessive) continue; + while (eptr >= pp) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM35); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + } + } + + RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + + /* Match a single character type repeatedly; several different opcodes + share code. This is very similar to the code for single characters, but we + repeat it in the interests of efficiency. */ + + case OP_TYPEEXACT: + min = max = GET2(ecode, 1); + minimize = TRUE; + ecode += 1 + IMM2_SIZE; + goto REPEATTYPE; + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + min = 0; + max = GET2(ecode, 1); + minimize = *ecode == OP_TYPEMINUPTO; + ecode += 1 + IMM2_SIZE; + goto REPEATTYPE; + + case OP_TYPEPOSSTAR: + possessive = TRUE; + min = 0; + max = INT_MAX; + ecode++; + goto REPEATTYPE; + + case OP_TYPEPOSPLUS: + possessive = TRUE; + min = 1; + max = INT_MAX; + ecode++; + goto REPEATTYPE; + + case OP_TYPEPOSQUERY: + possessive = TRUE; + min = 0; + max = 1; + ecode++; + goto REPEATTYPE; + + case OP_TYPEPOSUPTO: + possessive = TRUE; + min = 0; + max = GET2(ecode, 1); + ecode += 1 + IMM2_SIZE; + goto REPEATTYPE; + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + c = *ecode++ - OP_TYPESTAR; + 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; + + /* Common code for all repeated single character type matches. Note that + in UTF-8 mode, '.' matches a character of any length, but for the other + character types, the valid characters are all one-byte long. */ + + REPEATTYPE: + ctype = *ecode++; /* Code for the character type */ + +#ifdef SUPPORT_UCP + if (ctype == OP_PROP || ctype == OP_NOTPROP) + { + prop_fail_result = ctype == OP_NOTPROP; + prop_type = *ecode++; + prop_value = *ecode++; + } + else prop_type = -1; +#endif + + /* First, ensure the minimum number of matches are present. Use inline + code for maximizing the speed, and do the type test once at the start + (i.e. keep it out of the loop). Separate the UTF-8 code completely as that + is tidier. Also separate the UCP code, which can be the same for both UTF-8 + and single-bytes. */ + + if (min > 0) + { +#ifdef SUPPORT_UCP + if (prop_type >= 0) + { + switch(prop_type) + { + case PT_ANY: + if (prop_fail_result) RRETURN(MATCH_NOMATCH); + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + } + break; + + case PT_LAMP: + for (i = 1; i <= min; i++) + { + int chartype; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_GC: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_PC: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_SC: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + 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(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_SPACE: /* Perl space */ + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || + c == CHAR_FF || c == CHAR_CR) + == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_PXSPACE: /* POSIX space */ + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || + c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) + == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_WORD: + for (i = 1; i <= min; i++) + { + int category; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE) + == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + + case PT_CLIST: + for (i = 1; i <= min; i++) + { + const pcre_uint32 *cp; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + cp = PRIV(ucd_caseless_sets) + prop_value; + for (;;) + { + if (c < *cp) + { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } } + if (c == *cp++) + { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; } + } + } + break; + + /* This should not occur */ + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + } + + /* Match extended Unicode sequences. We will get here only if the + support is in the binary; otherwise a compile-time error occurs. */ + + else if (ctype == OP_EXTUNI) + { + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + else + { + int lgb, rgb; + GETCHARINCTEST(c, eptr); + lgb = UCD_GRAPHBREAK(c); + while (eptr < md->end_subject) + { + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + rgb = UCD_GRAPHBREAK(c); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + lgb = rgb; + eptr += len; + } + } + CHECK_PARTIAL(); + } + } + + else +#endif /* SUPPORT_UCP */ + +/* Handle all other cases when the coding is UTF-8 */ + +#ifdef SUPPORT_UTF + if (utf) switch(ctype) + { + case OP_ANY: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + 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 && + RAWUCHAR(eptr) == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); + } + break; + + case OP_ALLANY: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); + } + break; + + case OP_ANYBYTE: + if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH); + eptr += min; + break; + + case OP_ANYNL: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + + case CHAR_CR: + if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++; + break; + + case CHAR_LF: + break; + + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); + break; + } + } + break; + + case OP_NOT_HSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + switch(c) + { + HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */ + default: break; + } + } + break; + + case OP_HSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + switch(c) + { + HSPACE_CASES: break; /* Byte and multibyte cases */ + default: RRETURN(MATCH_NOMATCH); + } + } + break; + + case OP_NOT_VSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + switch(c) + { + VSPACE_CASES: RRETURN(MATCH_NOMATCH); + default: break; + } + } + break; + + case OP_VSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + switch(c) + { + VSPACE_CASES: break; + default: RRETURN(MATCH_NOMATCH); + } + } + break; + + case OP_NOT_DIGIT: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINC(c, eptr); + if (c < 128 && (md->ctypes[c] & ctype_digit) != 0) + RRETURN(MATCH_NOMATCH); + } + break; + + case OP_DIGIT: + for (i = 1; i <= min; i++) + { + pcre_uchar cc; + + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = RAWUCHAR(eptr); + if (cc >= 128 || (md->ctypes[cc] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + /* No need to skip more bytes - we know it's a 1-byte character */ + } + break; + + case OP_NOT_WHITESPACE: + for (i = 1; i <= min; i++) + { + pcre_uchar cc; + + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = RAWUCHAR(eptr); + if (cc < 128 && (md->ctypes[cc] & ctype_space) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); + } + break; + + case OP_WHITESPACE: + for (i = 1; i <= min; i++) + { + pcre_uchar cc; + + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = RAWUCHAR(eptr); + if (cc >= 128 || (md->ctypes[cc] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + /* No need to skip more bytes - we know it's a 1-byte character */ + } + break; + + case OP_NOT_WORDCHAR: + for (i = 1; i <= min; i++) + { + pcre_uchar cc; + + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = RAWUCHAR(eptr); + if (cc < 128 && (md->ctypes[cc] & ctype_word) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); + } + break; + + case OP_WORDCHAR: + for (i = 1; i <= min; i++) + { + pcre_uchar cc; + + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + cc = RAWUCHAR(eptr); + if (cc >= 128 || (md->ctypes[cc] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + /* No need to skip more bytes - we know it's a 1-byte character */ + } + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } /* End switch(ctype) */ + + else +#endif /* SUPPORT_UTF */ + + /* Code for the non-UTF-8 case for minimum matching of operators other + than OP_PROP and OP_NOTPROP. */ + + switch(ctype) + { + case OP_ANY: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + 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); + } + eptr++; + } + break; + + case OP_ALLANY: + if (eptr > md->end_subject - min) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr += min; + break; + + case OP_ANYBYTE: + if (eptr > md->end_subject - min) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr += min; + break; + + case OP_ANYNL: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + switch(*eptr++) + { + default: RRETURN(MATCH_NOMATCH); + + case CHAR_CR: + if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++; + break; + + case CHAR_LF: + break; + + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + case 0x2028: + case 0x2029: +#endif + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); + break; + } + } + break; + + case OP_NOT_HSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + switch(*eptr++) + { + default: break; + HSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + HSPACE_MULTIBYTE_CASES: +#endif + RRETURN(MATCH_NOMATCH); + } + } + break; + + case OP_HSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + switch(*eptr++) + { + default: RRETURN(MATCH_NOMATCH); + HSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + HSPACE_MULTIBYTE_CASES: +#endif + break; + } + } + break; + + case OP_NOT_VSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + switch(*eptr++) + { + VSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + VSPACE_MULTIBYTE_CASES: +#endif + RRETURN(MATCH_NOMATCH); + default: break; + } + } + break; + + case OP_VSPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + switch(*eptr++) + { + default: RRETURN(MATCH_NOMATCH); + VSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + VSPACE_MULTIBYTE_CASES: +#endif + break; + } + } + break; + + case OP_NOT_DIGIT: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + case OP_DIGIT: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + case OP_NOT_WHITESPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + case OP_WHITESPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + case OP_NOT_WORDCHAR: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + case OP_WORDCHAR: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; + } + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + } + + /* If min = max, continue at the same level without recursing */ + + if (min == max) continue; + + /* If minimizing, we have to test the rest of the pattern before each + subsequent match. Again, separate the UTF-8 case for speed, and also + separate the UCP cases. */ + + if (minimize) + { +#ifdef SUPPORT_UCP + if (prop_type >= 0) + { + switch(prop_type) + { + case PT_ANY: + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM36); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if (prop_fail_result) RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_LAMP: + for (fi = min;; fi++) + { + int chartype; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM37); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + 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, eptrb, RM38); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CATEGORY(c) == 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, eptrb, RM39); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_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, eptrb, RM40); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_ALNUM: + for (fi = min;; fi++) + { + int category; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM59); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + 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, eptrb, RM60); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || + c == CHAR_FF || c == CHAR_CR) + == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_PXSPACE: /* POSIX space */ + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM61); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || + c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) + == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_WORD: + for (fi = min;; fi++) + { + int category; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM62); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + category = UCD_CATEGORY(c); + if ((category == ucp_L || + category == ucp_N || + c == CHAR_UNDERSCORE) + == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + case PT_CLIST: + for (fi = min;; fi++) + { + const pcre_uint32 *cp; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM67); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + cp = PRIV(ucd_caseless_sets) + prop_value; + for (;;) + { + if (c < *cp) + { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } } + if (c == *cp++) + { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; } + } + } + /* Control never gets here */ + + /* This should never occur */ + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + } + + /* Match extended Unicode sequences. We will get here only if the + support is in the binary; otherwise a compile-time error occurs. */ + + else if (ctype == OP_EXTUNI) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM41); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + else + { + int lgb, rgb; + GETCHARINCTEST(c, eptr); + lgb = UCD_GRAPHBREAK(c); + while (eptr < md->end_subject) + { + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + rgb = UCD_GRAPHBREAK(c); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + lgb = rgb; + eptr += len; + } + } + CHECK_PARTIAL(); + } + } + else +#endif /* SUPPORT_UCP */ + +#ifdef SUPPORT_UTF + if (utf) + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM42); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (ctype == OP_ANY && IS_NEWLINE(eptr)) + RRETURN(MATCH_NOMATCH); + GETCHARINC(c, eptr); + switch(ctype) + { + 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; + + case OP_ANYNL: + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + case CHAR_CR: + if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++; + break; + + case CHAR_LF: + break; + + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); + break; + } + break; + + case OP_NOT_HSPACE: + switch(c) + { + HSPACE_CASES: RRETURN(MATCH_NOMATCH); + default: break; + } + break; + + case OP_HSPACE: + switch(c) + { + HSPACE_CASES: break; + default: RRETURN(MATCH_NOMATCH); + } + break; + + case OP_NOT_VSPACE: + switch(c) + { + VSPACE_CASES: RRETURN(MATCH_NOMATCH); + default: break; + } + break; + + case OP_VSPACE: + switch(c) + { + VSPACE_CASES: break; + default: RRETURN(MATCH_NOMATCH); + } + break; + + case OP_NOT_DIGIT: + if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_DIGIT: + if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WHITESPACE: + if (c < 256 && (md->ctypes[c] & ctype_space) != 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_WHITESPACE: + 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) + RRETURN(MATCH_NOMATCH); + break; + + case OP_WORDCHAR: + if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + } + } + else +#endif + /* Not UTF mode */ + { + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM43); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (ctype == OP_ANY && IS_NEWLINE(eptr)) + RRETURN(MATCH_NOMATCH); + c = *eptr++; + switch(ctype) + { + 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; + + case OP_ANYNL: + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + case CHAR_CR: + if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++; + break; + + case CHAR_LF: + break; + + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + case 0x2028: + case 0x2029: +#endif + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); + break; + } + break; + + case OP_NOT_HSPACE: + switch(c) + { + default: break; + HSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + HSPACE_MULTIBYTE_CASES: +#endif + RRETURN(MATCH_NOMATCH); + } + break; + + case OP_HSPACE: + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + HSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + HSPACE_MULTIBYTE_CASES: +#endif + break; + } + break; + + case OP_NOT_VSPACE: + switch(c) + { + default: break; + VSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + VSPACE_MULTIBYTE_CASES: +#endif + RRETURN(MATCH_NOMATCH); + } + break; + + case OP_VSPACE: + switch(c) + { + default: RRETURN(MATCH_NOMATCH); + VSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + VSPACE_MULTIBYTE_CASES: +#endif + break; + } + break; + + case OP_NOT_DIGIT: + if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_DIGIT: + if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WHITESPACE: + if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_WHITESPACE: + if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WORDCHAR: + if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_WORDCHAR: + if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + } + } + /* Control never gets here */ + } + + /* If maximizing, it is worth using inline code for speed, doing the type + test once at the start (i.e. keep it out of the loop). Again, keep the + UTF-8 and UCP stuff separate. */ + + else + { + pp = eptr; /* Remember where we started */ + +#ifdef SUPPORT_UCP + if (prop_type >= 0) + { + switch(prop_type) + { + case PT_ANY: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if (prop_fail_result) break; + eptr+= len; + } + break; + + case PT_LAMP: + for (i = min; i < max; i++) + { + int chartype; + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) + break; + eptr+= len; + } + break; + + case PT_GC: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break; + eptr+= len; + } + break; + + case PT_PC: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break; + eptr+= len; + } + break; + + case PT_SC: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break; + eptr+= len; + } + break; + + case PT_ALNUM: + for (i = min; i < max; i++) + { + int category; + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) + break; + eptr+= len; + } + break; + + case PT_SPACE: /* Perl space */ + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || + c == CHAR_FF || c == CHAR_CR) + == prop_fail_result) + break; + eptr+= len; + } + break; + + case PT_PXSPACE: /* POSIX space */ + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || + c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) + == prop_fail_result) + break; + eptr+= len; + } + break; + + case PT_WORD: + for (i = min; i < max; i++) + { + int category; + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N || + c == CHAR_UNDERSCORE) == prop_fail_result) + break; + eptr+= len; + } + break; + + case PT_CLIST: + for (i = min; i < max; i++) + { + const pcre_uint32 *cp; + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + cp = PRIV(ucd_caseless_sets) + prop_value; + for (;;) + { + if (c < *cp) + { if (prop_fail_result) break; else goto GOT_MAX; } + if (c == *cp++) + { if (prop_fail_result) goto GOT_MAX; else break; } + } + eptr += len; + } + GOT_MAX: + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + + /* eptr is now past the end of the maximum run */ + + if (possessive) continue; + for(;;) + { + 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 (utf) BACKCHAR(eptr); + } + } + + /* Match extended Unicode sequences. We will get here only if the + support is in the binary; otherwise a compile-time error occurs. */ + + else if (ctype == OP_EXTUNI) + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + else + { + int lgb, rgb; + GETCHARINCTEST(c, eptr); + lgb = UCD_GRAPHBREAK(c); + while (eptr < md->end_subject) + { + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + rgb = UCD_GRAPHBREAK(c); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + lgb = rgb; + eptr += len; + } + } + CHECK_PARTIAL(); + } + + /* eptr is now past the end of the maximum run */ + + if (possessive) continue; + + for(;;) + { + 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 */ + { + if (!utf) c = *eptr; else + { + BACKCHAR(eptr); + GETCHAR(c, eptr); + } + if (UCD_CATEGORY(c) != ucp_M) break; + eptr--; + } + } + } + + else +#endif /* SUPPORT_UCP */ + +#ifdef SUPPORT_UTF + if (utf) + { + switch(ctype) + { + case OP_ANY: + if (max < INT_MAX) + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + 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 && + RAWUCHAR(eptr) == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); + } + } + + /* Handle unlimited UTF-8 repeat */ + + else + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + 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 && + RAWUCHAR(eptr) == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); + } + } + break; + + case OP_ALLANY: + if (max < INT_MAX) + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); + } + } + else + { + eptr = md->end_subject; /* Unlimited UTF-8 repeat */ + SCHECK_PARTIAL(); + } + break; + + /* The byte case is the same as non-UTF8 */ + + case OP_ANYBYTE: + c = max - min; + if (c > (unsigned int)(md->end_subject - eptr)) + { + eptr = md->end_subject; + SCHECK_PARTIAL(); + } + else eptr += c; + break; + + case OP_ANYNL: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c == CHAR_CR) + { + if (++eptr >= md->end_subject) break; + if (RAWUCHAR(eptr) == CHAR_LF) eptr++; + } + else + { + if (c != CHAR_LF && + (md->bsr_anycrlf || + (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL +#ifndef EBCDIC + && c != 0x2028 && c != 0x2029 +#endif /* Not EBCDIC */ + ))) + break; + eptr += len; + } + } + break; + + case OP_NOT_HSPACE: + case OP_HSPACE: + for (i = min; i < max; i++) + { + BOOL gotspace; + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + switch(c) + { + HSPACE_CASES: gotspace = TRUE; break; + default: gotspace = FALSE; break; + } + if (gotspace == (ctype == OP_NOT_HSPACE)) break; + eptr += len; + } + break; + + case OP_NOT_VSPACE: + case OP_VSPACE: + for (i = min; i < max; i++) + { + BOOL gotspace; + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + switch(c) + { + VSPACE_CASES: gotspace = TRUE; break; + default: gotspace = FALSE; break; + } + if (gotspace == (ctype == OP_NOT_VSPACE)) break; + eptr += len; + } + break; + + case OP_NOT_DIGIT: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break; + eptr+= len; + } + break; + + case OP_DIGIT: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break; + eptr+= len; + } + break; + + case OP_NOT_WHITESPACE: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break; + eptr+= len; + } + break; + + case OP_WHITESPACE: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break; + eptr+= len; + } + break; + + case OP_NOT_WORDCHAR: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break; + eptr+= len; + } + break; + + case OP_WORDCHAR: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLEN(c, eptr, len); + if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break; + eptr+= len; + } + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + + /* eptr is now past the end of the maximum run. If possessive, we are + done (no backing up). Otherwise, match at this position; anything other + than no match is immediately returned. For nomatch, back up one + character, unless we are matching \R and the last thing matched was + \r\n, in which case, back up two bytes. */ + + if (possessive) continue; + for(;;) + { + 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 && RAWUCHAR(eptr) == CHAR_NL && + RAWUCHAR(eptr - 1) == CHAR_CR) eptr--; + } + } + else +#endif /* SUPPORT_UTF */ + /* Not UTF mode */ + { + switch(ctype) + { + case OP_ANY: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + 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; + + case OP_ALLANY: + case OP_ANYBYTE: + c = max - min; + if (c > (unsigned int)(md->end_subject - eptr)) + { + eptr = md->end_subject; + SCHECK_PARTIAL(); + } + else eptr += c; + break; + + case OP_ANYNL: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + c = *eptr; + if (c == CHAR_CR) + { + if (++eptr >= md->end_subject) break; + if (*eptr == CHAR_LF) eptr++; + } + else + { + if (c != CHAR_LF && (md->bsr_anycrlf || + (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + && c != 0x2028 && c != 0x2029 +#endif + ))) break; + eptr++; + } + } + break; + + case OP_NOT_HSPACE: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + switch(*eptr) + { + default: eptr++; break; + HSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + HSPACE_MULTIBYTE_CASES: +#endif + goto ENDLOOP00; + } + } + ENDLOOP00: + break; + + case OP_HSPACE: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + switch(*eptr) + { + default: goto ENDLOOP01; + HSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + HSPACE_MULTIBYTE_CASES: +#endif + eptr++; break; + } + } + ENDLOOP01: + break; + + case OP_NOT_VSPACE: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + switch(*eptr) + { + default: eptr++; break; + VSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + VSPACE_MULTIBYTE_CASES: +#endif + goto ENDLOOP02; + } + } + ENDLOOP02: + break; + + case OP_VSPACE: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + switch(*eptr) + { + default: goto ENDLOOP03; + VSPACE_BYTE_CASES: +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + VSPACE_MULTIBYTE_CASES: +#endif + eptr++; break; + } + } + ENDLOOP03: + break; + + case OP_NOT_DIGIT: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break; + eptr++; + } + break; + + case OP_DIGIT: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break; + eptr++; + } + break; + + case OP_NOT_WHITESPACE: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break; + eptr++; + } + break; + + case OP_WHITESPACE: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break; + eptr++; + } + break; + + case OP_NOT_WORDCHAR: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break; + eptr++; + } + break; + + case OP_WORDCHAR: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break; + eptr++; + } + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + + /* eptr is now past the end of the maximum run. If possessive, we are + done (no backing up). Otherwise, match at this position; anything other + than no match is immediately returned. For nomatch, back up one + character (byte), unless we are matching \R and the last thing matched + was \r\n, in which case, back up two bytes. */ + + if (possessive) continue; + while (eptr >= pp) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM47); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + if (ctype == OP_ANYNL && eptr > pp && *eptr == CHAR_LF && + eptr[-1] == CHAR_CR) eptr--; + } + } + + /* Get here if we can't make it match with any permitted repetitions */ + + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + /* There's been some horrible disaster. Arrival here can only mean there is + something seriously wrong in the code above or the OP_xxx definitions. */ + + default: + DPRINTF(("Unknown opcode %d\n", *ecode)); + RRETURN(PCRE_ERROR_UNKNOWN_OPCODE); + } + + /* Do not stick any code in here without much thought; it is assumed + that "continue" in the code above comes out to here to repeat the main + loop. */ + + } /* End of main loop */ +/* Control never reaches here */ + + +/* When compiling to use the heap rather than the stack for recursive calls to +match(), the RRETURN() macro jumps here. The number that is saved in +frame->Xwhere indicates which label we actually want to return to. */ + +#ifdef NO_RECURSE +#define LBL(val) case val: goto L_RM##val; +HEAP_RETURN: +switch (frame->Xwhere) + { + LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8) + LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17) + LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33) + LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52) + LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(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) LBL(67) +#endif /* SUPPORT_UCP */ +#endif /* SUPPORT_UTF */ + default: + DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere)); + return PCRE_ERROR_INTERNAL; + } +#undef LBL +#endif /* NO_RECURSE */ +} + + +/*************************************************************************** +**************************************************************************** + RECURSION IN THE match() FUNCTION + +Undefine all the macros that were defined above to handle this. */ + +#ifdef NO_RECURSE +#undef eptr +#undef ecode +#undef mstart +#undef offset_top +#undef eptrb +#undef flags + +#undef callpat +#undef charptr +#undef data +#undef next +#undef pp +#undef prev +#undef saved_eptr + +#undef new_recursive + +#undef cur_is_word +#undef condition +#undef prev_is_word + +#undef ctype +#undef length +#undef max +#undef min +#undef number +#undef offset +#undef op +#undef save_capture_last +#undef save_offset1 +#undef save_offset2 +#undef save_offset3 +#undef stacksave + +#undef newptrb + +#endif + +/* These two are defined as macros in both cases */ + +#undef fc +#undef fi + +/*************************************************************************** +***************************************************************************/ + + +#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 * +*************************************************/ + +/* This function applies a compiled re to a subject string and picks out +portions of the string if it matches. Two elements in the vector are set for +each substring: the offsets to the start and end of the substring. + +Arguments: + argument_re points to the compiled expression + extra_data points to extra data or is NULL + subject points to the subject string + length length of subject string (may contain binary zeros) + start_offset where to start in the subject string + options option bits + offsets points to a vector of ints to be filled in with offsets + offsetcount the number of elements in the vector + +Returns: > 0 => success; value is the number of elements filled in + = 0 => success, but offsets is not big enough + -1 => failed to match + < -1 => some kind of unexpected problem +*/ + +#if defined 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) +#elif defined COMPILE_PCRE16 +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) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_exec(const pcre32 *argument_re, const pcre32_extra *extra_data, + PCRE_SPTR32 subject, int length, int start_offset, int options, int *offsets, + int offsetcount) +#endif +{ +int rc, ocount, arg_offset_max; +int newline; +BOOL using_temporary_offsets = FALSE; +BOOL anchored; +BOOL startline; +BOOL firstline; +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 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; + +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. */ + +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 (offsetcount < 0) return PCRE_ERROR_BADCOUNT; +if (length < 0) return PCRE_ERROR_BADLENGTH; +if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; + +/* 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; + } +#if defined COMPILE_PCRE8 + return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)? + PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; +#elif defined COMPILE_PCRE16 + return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)? + PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16; +#elif defined COMPILE_PCRE32 + return PCRE_ERROR_BADUTF32; +#endif + } +#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 + /* 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 + } +#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 & ~PUBLIC_JIT_EXEC_OPTIONS) == 0) + { + rc = PRIV(jit_exec)(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_JIT_BADOPTION) return rc; + } +#endif + +/* Carry on with non-JIT matching. This information is for finding all the +numbers associated with a given name, for condition testing. */ + +md->name_table = (pcre_uchar *)re + re->name_table_offset; +md->name_count = re->name_count; +md->name_entry_size = re->name_entry_size; + +/* Fish out the optional data from the extra_data structure, first setting +the default values. */ + +study = NULL; +md->match_limit = MATCH_LIMIT; +md->match_limit_recursion = MATCH_LIMIT_RECURSION; +md->callout_data = NULL; + +/* The table pointer is always in native byte order. */ + +tables = re->tables; + +if (extra_data != NULL) + { + register unsigned int flags = extra_data->flags; + if ((flags & PCRE_EXTRA_STUDY_DATA) != 0) + study = (const pcre_study_data *)extra_data->study_data; + if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) + md->match_limit = extra_data->match_limit; + if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0) + md->match_limit_recursion = extra_data->match_limit_recursion; + if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0) + md->callout_data = extra_data->callout_data; + if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables; + } + +/* If the exec call supplied NULL for tables, use the inbuilt ones. This +is a feature that makes it possible to save compiled regex and re-use them +in other programs later. */ + +if (tables == NULL) tables = PRIV(default_tables); + +/* Set up other data */ + +anchored = ((re->options | options) & PCRE_ANCHORED) != 0; +startline = (re->flags & PCRE_STARTLINE) != 0; +firstline = (re->options & PCRE_FIRSTLINE) != 0; + +/* The code starts after the real_pcre block and the capture name table. */ + +md->start_code = (const pcre_uchar *)re + re->name_table_offset + + re->name_count * re->name_entry_size; + +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; +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->hitend = FALSE; +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. */ + +switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) + { + case 0: + if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0) + md->bsr_anycrlf = (re->options & PCRE_BSR_ANYCRLF) != 0; + else +#ifdef BSR_ANYCRLF + md->bsr_anycrlf = TRUE; +#else + md->bsr_anycrlf = FALSE; +#endif + break; + + case PCRE_BSR_ANYCRLF: + md->bsr_anycrlf = TRUE; + break; + + case PCRE_BSR_UNICODE: + md->bsr_anycrlf = FALSE; + break; + + default: return PCRE_ERROR_BADNEWLINE; + } + +/* Handle different types of newline. The three bits give eight cases. If +nothing is set at run time, whatever was used at compile time applies. */ + +switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : + (pcre_uint32)options) & PCRE_NEWLINE_BITS) + { + case 0: newline = NEWLINE; break; /* Compile-time default */ + case PCRE_NEWLINE_CR: newline = CHAR_CR; break; + case PCRE_NEWLINE_LF: newline = CHAR_NL; break; + case PCRE_NEWLINE_CR+ + PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break; + case PCRE_NEWLINE_ANY: newline = -1; break; + case PCRE_NEWLINE_ANYCRLF: newline = -2; break; + default: return PCRE_ERROR_BADNEWLINE; + } + +if (newline == -2) + { + md->nltype = NLTYPE_ANYCRLF; + } +else if (newline < 0) + { + md->nltype = NLTYPE_ANY; + } +else + { + md->nltype = NLTYPE_FIXED; + if (newline > 255) + { + md->nllen = 2; + md->nl[0] = (newline >> 8) & 255; + md->nl[1] = newline & 255; + } + else + { + md->nllen = 1; + md->nl[0] = newline; + } + } + +/* Partial matching was originally supported only for a restricted set of +regexes; from release 8.00 there are no restrictions, but the bits are still +defined (though never set). So there's no harm in leaving this code. */ + +if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0) + return PCRE_ERROR_BADPARTIAL; + +/* 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 *)(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")); + } +else md->offset_vector = offsets; + +md->offset_end = ocount; +md->offset_max = (2*ocount)/3; +md->offset_overflow = FALSE; +md->capture_last = -1; + +/* 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. 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 - 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_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 +studied, there may be a bitmap of possible first characters. */ + +if (!anchored) + { + if ((re->flags & PCRE_FIRSTSET) != 0) + { + 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 && + (study->flags & PCRE_STUDY_MAPPED) != 0) + start_bits = study->start_bits; + } + +/* For anchored or unanchored matches, there may be a "last known required +character" set. */ + +if ((re->flags & PCRE_REQCHSET) != 0) + { + 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 + } + } + + +/* ==========================================================================*/ + +/* Loop for handling unanchored repeated matching attempts; for anchored regexs +the loop runs just once. */ + +for(;;) + { + 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 + newline. Implement this by temporarily adjusting end_subject so that we stop + scanning at a newline. If the match fails at the newline, later code breaks + this loop. */ + + if (firstline) + { + PCRE_PUCHAR t = start_match; +#ifdef SUPPORT_UTF + if (utf) + { + while (t < md->end_subject && !IS_NEWLINE(t)) + { + t++; + ACROSSCHAR(t < end_subject, *t, t++); + } + } + else +#endif + while (t < md->end_subject && !IS_NEWLINE(t)) t++; + end_subject = t; + } + + /* There are some optimizations that avoid running the match if a known + starting point is not found, or if a known later character is not present. + However, there is an option that disables these, for testing and for ensuring + that all callouts do actually occur. The option can be set in the regex by + (*NO_START_OPT) or passed in match-time options. */ + + if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0) + { + /* Advance to a unique first char if there is one. */ + + if (has_first_char) + { + pcre_uchar smc; + + if (first_char != first_char2) + while (start_match < end_subject && + (smc = RAWUCHARTEST(start_match)) != first_char && smc != first_char2) + start_match++; + else + while (start_match < end_subject && RAWUCHARTEST(start_match) != first_char) + start_match++; + } + + /* Or to just after a linebreak for a multiline match */ + + else if (startline) + { + if (start_match > md->start_subject + start_offset) + { +#ifdef SUPPORT_UTF + if (utf) + { + while (start_match < end_subject && !WAS_NEWLINE(start_match)) + { + start_match++; + ACROSSCHAR(start_match < end_subject, *start_match, + start_match++); + } + } + else +#endif + while (start_match < end_subject && !WAS_NEWLINE(start_match)) + start_match++; + + /* If we have just passed a CR and the newline option is ANY or ANYCRLF, + and we are now at a LF, advance the match position by one more character. + */ + + if (start_match[-1] == CHAR_CR && + (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) && + start_match < end_subject && + RAWUCHARTEST(start_match) == CHAR_NL) + start_match++; + } + } + + /* Or to a non-unique first byte after study */ + + else if (start_bits != NULL) + { + while (start_match < end_subject) + { + register pcre_uint32 c = RAWUCHARTEST(start_match); +#ifndef COMPILE_PCRE8 + if (c > 255) c = 255; +#endif + if ((start_bits[c/8] & (1 << (c&7))) == 0) + { + 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; + } + } + } /* Starting optimizations */ + + /* Restore fudged end_subject */ + + end_subject = save_end_subject; + + /* The following two optimizations are disabled for partial matching or if + disabling is explicitly requested. */ + + 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 + pattern. Although the value is, strictly, in characters, we treat it as + bytes to avoid spending too much time in this optimization. */ + + if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 && + (pcre_uint32)(end_subject - start_match) < study->minlength) + { + rc = MATCH_NOMATCH; + break; + } + + /* 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 + for cased/caseless versions makes it go faster, as does using an + autoincrement and backing off on a match. + + HOWEVER: when the subject string is very, very long, searching to its end + can take a long time, and give bad performance on quite ordinary patterns. + This showed up when somebody was matching something like /^\d+C/ on a + 32-megabyte string... so we don't do this when the string is sufficiently + long. */ + + if (has_req_char && end_subject - start_match < REQ_BYTE_MAX) + { + 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_char_ptr) + { + if (req_char != req_char2) + { + while (p < end_subject) + { + register pcre_uint32 pp = RAWUCHARINCTEST(p); + if (pp == req_char || pp == req_char2) { p--; break; } + } + } + else + { + while (p < end_subject) + { + if (RAWUCHARINCTEST(p) == req_char) { p--; break; } + } + } + + /* If we can't find the required character, break the matching loop, + forcing a match failure. */ + + if (p >= end_subject) + { + rc = MATCH_NOMATCH; + break; + } + + /* If we have found the required character, save the point where we + found it, so that we don't search again next time round the loop if + the start hasn't passed this character yet. */ + + req_char_ptr = p; + } + } + } + +#ifdef PCRE_DEBUG /* Sigh. Some compilers never learn. */ + printf(">>>> Match against: "); + pchars(start_match, end_subject - start_match, TRUE, md); + printf("\n"); +#endif + + /* OK, we can now run the match. If "hitend" is set afterwards, remember the + first starting point for which a partial match was found. */ + + md->start_match_ptr = start_match; + md->start_used_ptr = start_match; + md->match_call_count = 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. */ + + case MATCH_SKIP: + if (md->start_match_ptr != start_match) + { + new_start_match = md->start_match_ptr; + break; + } + /* Fall through */ + + /* NOMATCH and PRUNE advance by one character. THEN at this level acts + 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_UTF + if (utf) + ACROSSCHAR(new_start_match < end_subject, *new_start_match, + new_start_match++); +#endif + break; + + /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */ + + case MATCH_COMMIT: + rc = MATCH_NOMATCH; + goto ENDLOOP; + + /* Any other return is either a match, or some kind of error. */ + + default: + goto ENDLOOP; + } + + /* Control reaches here for the various types of "no match at this point" + result. Reset the code to MATCH_NOMATCH for subsequent checking. */ + + rc = MATCH_NOMATCH; + + /* If PCRE_FIRSTLINE is set, the match must happen before or at the first + newline in the subject (though it may continue over the newline). Therefore, + if we have just failed to match, starting at a newline, do not continue. */ + + if (firstline && IS_NEWLINE(start_match)) break; + + /* Advance to new matching position */ + + start_match = new_start_match; + + /* Break the loop if the pattern is anchored or if we have passed the end of + the subject. */ + + if (anchored || start_match > end_subject) break; + + /* 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. 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 > (PCRE_PUCHAR)subject + start_offset && + start_match[-1] == CHAR_CR && + start_match < end_subject && + *start_match == CHAR_NL && + (re->flags & PCRE_HASCRORLF) == 0 && + (md->nltype == NLTYPE_ANY || + md->nltype == NLTYPE_ANYCRLF || + md->nllen == 2)) + start_match++; + + md->mark = NULL; /* Reset for start of next match attempt */ + } /* End of for(;;) "bumpalong" loop */ + +/* ==========================================================================*/ + +/* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping +conditions is true: + +(1) The pattern is anchored or the match was failed by (*COMMIT); + +(2) We are past the end of the subject; + +(3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because + this option requests that a match occur at or before the first newline in + the subject. + +When we have a match and the offset vector is big enough to deal with any +backreferences, captured substring offsets will already be set up. In the case +where we had to get some local store to hold offsets for backreference +processing, copy those that we can. In this case there need not be overflow if +certain parts of the pattern were not used, even though there are more +capturing parentheses than vector slots. */ + +ENDLOOP: + +if (rc == MATCH_MATCH || rc == MATCH_ACCEPT) + { + if (using_temporary_offsets) + { + if (arg_offset_max >= 4) + { + memcpy(offsets + 2, md->offset_vector + 2, + (arg_offset_max - 2) * sizeof(int)); + DPRINTF(("Copied offsets from temporary memory\n")); + } + if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE; + DPRINTF(("Freeing temporary memory\n")); + (PUBL(free))(md->offset_vector); + } + + /* Set the return code to the number of captured strings, or 0 if there were + too many to fit into the vector. */ + + rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)? + 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 + matching path. */ + + if (offsetcount < 2) rc = 0; else + { + offsets[0] = (int)(md->start_match_ptr - md->start_subject); + 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)); +#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 +attempt has failed at all permitted starting positions. */ + +if (using_temporary_offsets) + { + DPRINTF(("Freeing temporary memory\n")); + (PUBL(free))(md->offset_vector); + } + +/* For anything other than nomatch or partial match, just return the code. */ + +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; + } + +/* Handle partial matches - disable any mark data */ + +if (start_partial != NULL) + { + DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n")); + md->mark = NULL; + if (offsetcount > 1) + { + offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject); + offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject); + } + rc = PCRE_ERROR_PARTIAL; + } + +/* This is the classic nomatch case */ + +else + { + DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n")); + rc = PCRE_ERROR_NOMATCH; + } + +/* Return the MARK data if it has been requested. */ + +if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) + *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark; +#ifdef NO_RECURSE + release_match_heapframes(&frame_zero); +#endif +return rc; +} + +/* End of pcre_exec.c */ diff --git a/tools/pcre/pcre_fullinfo.c b/tools/pcre/pcre_fullinfo.c new file mode 100644 index 00000000..02c9df4a --- /dev/null +++ b/tools/pcre/pcre_fullinfo.c @@ -0,0 +1,231 @@ +/************************************************* +* 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 the external function pcre_fullinfo(), which returns +information about a compiled pattern. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + + +/************************************************* +* Return info about compiled pattern * +*************************************************/ + +/* This is a newer "info" function which has an extensible interface so +that additional items can be added compatibly. + +Arguments: + argument_re points to compiled code + extra_data points extra data, or NULL + what what information is required + where where to put the information + +Returns: 0 if data returned, negative on error +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, + int what, void *where) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data, + int what, void *where) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_fullinfo(const pcre32 *argument_re, const pcre32_extra *extra_data, + int what, void *where) +#endif +{ +const REAL_PCRE *re = (const REAL_PCRE *)argument_re; +const pcre_study_data *study = NULL; + +if (re == NULL || where == NULL) return PCRE_ERROR_NULL; + +if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) + study = (const pcre_study_data *)extra_data->study_data; + +/* Check that the first field in the block is the magic number. If it is not, +return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to +REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which +means that the pattern is likely compiled with different endianness. */ + +if (re->magic_number != MAGIC_NUMBER) + 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) + { + case PCRE_INFO_OPTIONS: + *((unsigned long int *)where) = re->options & PUBLIC_COMPILE_OPTIONS; + break; + + case PCRE_INFO_SIZE: + *((size_t *)where) = re->size; + break; + + case PCRE_INFO_STUDYSIZE: + *((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; + + case PCRE_INFO_BACKREFMAX: + *((int *)where) = re->top_backref; + break; + + case PCRE_INFO_FIRSTBYTE: + *((int *)where) = + ((re->flags & PCRE_FIRSTSET) != 0)? (int)re->first_char : + ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2; + break; + + case PCRE_INFO_FIRSTCHARACTER: + *((pcre_uint32 *)where) = + (re->flags & PCRE_FIRSTSET) != 0 ? re->first_char : 0; + break; + + case PCRE_INFO_FIRSTCHARACTERFLAGS: + *((int *)where) = + ((re->flags & PCRE_FIRSTSET) != 0) ? 1 : + ((re->flags & PCRE_STARTLINE) != 0) ? 2 : 0; + break; + + /* Make sure we pass back the pointer to the bit vector in the external + block, not the internal copy (with flipped integer fields). */ + + case PCRE_INFO_FIRSTTABLE: + *((const pcre_uint8 **)where) = + (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)? + ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL; + break; + + case PCRE_INFO_MINLENGTH: + *((int *)where) = + (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)? + (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)? (int)re->req_char : -1; + break; + + case PCRE_INFO_REQUIREDCHAR: + *((pcre_uint32 *)where) = + ((re->flags & PCRE_REQCHSET) != 0) ? re->req_char : 0; + break; + + case PCRE_INFO_REQUIREDCHARFLAGS: + *((int *)where) = + ((re->flags & PCRE_REQCHSET) != 0); + break; + + case PCRE_INFO_NAMEENTRYSIZE: + *((int *)where) = re->name_entry_size; + break; + + case PCRE_INFO_NAMECOUNT: + *((int *)where) = re->name_count; + break; + + case PCRE_INFO_NAMETABLE: + *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset; + break; + + case PCRE_INFO_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 + no longer ever set (the restrictions have been removed). */ + + case PCRE_INFO_OKPARTIAL: + *((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0; + break; + + case PCRE_INFO_JCHANGED: + *((int *)where) = (re->flags & PCRE_JCHANGED) != 0; + break; + + case PCRE_INFO_HASCRORLF: + *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0; + break; + + case PCRE_INFO_MAXLOOKBEHIND: + *((int *)where) = re->max_lookbehind; + break; + + default: return PCRE_ERROR_BADOPTION; + } + +return 0; +} + +/* End of pcre_fullinfo.c */ diff --git a/tools/pcre/pcre_get.c b/tools/pcre/pcre_get.c new file mode 100644 index 00000000..8094b34b --- /dev/null +++ b/tools/pcre/pcre_get.c @@ -0,0 +1,662 @@ +/************************************************* +* 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 some convenience functions for extracting substrings +from the subject string after a regex match has succeeded. The original idea +for these functions came from Scott Wimer. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + + +/************************************************* +* Find number for named string * +*************************************************/ + +/* This function is used by the get_first_set() function below, as well +as being generally available. It assumes that names are unique. + +Arguments: + code the compiled regex + stringname the name whose number is required + +Returns: the number of the named parentheses, or a negative number + (PCRE_ERROR_NOSUBSTRING) if not found +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre_get_stringnumber(const pcre *code, const char *stringname) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_get_stringnumber(const pcre32 *code, PCRE_SPTR32 stringname) +#endif +{ +int rc; +int entrysize; +int top, bot; +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; + +if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) + return rc; +#endif +#ifdef COMPILE_PCRE16 +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) + return rc; +if (top <= 0) return PCRE_ERROR_NOSUBSTRING; + +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) + return rc; +#endif +#ifdef COMPILE_PCRE32 +if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) + return rc; +if (top <= 0) return PCRE_ERROR_NOSUBSTRING; + +if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) + return rc; +#endif + +bot = 0; +while (top > bot) + { + int mid = (top + bot) / 2; + 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; + } + +return PCRE_ERROR_NOSUBSTRING; +} + + + +/************************************************* +* Find (multiple) entries for named string * +*************************************************/ + +/* This is used by the get_first_set() function below, as well as being +generally available. It is used when duplicated names are permitted. + +Arguments: + code the compiled regex + stringname the name whose entries required + firstptr where to put the pointer to the first entry + lastptr where to put the pointer to the last entry + +Returns: the length of each entry, or a negative number + (PCRE_ERROR_NOSUBSTRING) if not found +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre_get_stringtable_entries(const pcre *code, const char *stringname, + char **firstptr, char **lastptr) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname, + PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_get_stringtable_entries(const pcre32 *code, PCRE_SPTR32 stringname, + PCRE_UCHAR32 **firstptr, PCRE_UCHAR32 **lastptr) +#endif +{ +int rc; +int entrysize; +int top, bot; +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; + +if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) + return rc; +#endif +#ifdef COMPILE_PCRE16 +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) + return rc; +if (top <= 0) return PCRE_ERROR_NOSUBSTRING; + +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) + return rc; +#endif +#ifdef COMPILE_PCRE32 +if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) + return rc; +if (top <= 0) return PCRE_ERROR_NOSUBSTRING; + +if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre32_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; + pcre_uchar *entry = nametable + entrysize*mid; + int c = STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(entry + IMM2_SIZE)); + if (c == 0) + { + pcre_uchar *first = entry; + pcre_uchar *last = entry; + while (first > nametable) + { + if (STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(first - entrysize + IMM2_SIZE)) != 0) break; + first -= entrysize; + } + while (last < lastentry) + { + if (STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break; + last += entrysize; + } +#if defined COMPILE_PCRE8 + *firstptr = (char *)first; + *lastptr = (char *)last; +#elif defined COMPILE_PCRE16 + *firstptr = (PCRE_UCHAR16 *)first; + *lastptr = (PCRE_UCHAR16 *)last; +#elif defined COMPILE_PCRE32 + *firstptr = (PCRE_UCHAR32 *)first; + *lastptr = (PCRE_UCHAR32 *)last; +#endif + return entrysize; + } + if (c > 0) bot = mid + 1; else top = mid; + } + +return PCRE_ERROR_NOSUBSTRING; +} + + + +/************************************************* +* Find first set of multiple named strings * +*************************************************/ + +/* This function allows for duplicate names in the table of named substrings. +It returns the number of the first one that was set in a pattern match. + +Arguments: + code the compiled regex + stringname the name of the capturing substring + ovector the vector of matched substrings + +Returns: the number of the first that is set, + or the number of the last one if none are set, + or a negative number on error +*/ + +#if defined COMPILE_PCRE8 +static int +get_first_set(const pcre *code, const char *stringname, int *ovector) +#elif defined COMPILE_PCRE16 +static int +get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector) +#elif defined COMPILE_PCRE32 +static int +get_first_set(const pcre32 *code, PCRE_SPTR32 stringname, int *ovector) +#endif +{ +const REAL_PCRE *re = (const REAL_PCRE *)code; +int entrysize; +pcre_uchar *entry; +#if defined COMPILE_PCRE8 +char *first, *last; +#elif defined COMPILE_PCRE16 +PCRE_UCHAR16 *first, *last; +#elif defined COMPILE_PCRE32 +PCRE_UCHAR32 *first, *last; +#endif + +#if defined 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); +#elif defined COMPILE_PCRE16 +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); +#elif defined COMPILE_PCRE32 +if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0) + return pcre32_get_stringnumber(code, stringname); +entrysize = pcre32_get_stringtable_entries(code, stringname, &first, &last); +#endif +if (entrysize <= 0) return entrysize; +for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize) + { + int n = GET2(entry, 0); + if (ovector[n*2] >= 0) return n; + } +return GET2(entry, 0); +} + + + + +/************************************************* +* Copy captured string to given buffer * +*************************************************/ + +/* This function copies a single captured substring into a given buffer. +Note that we use memcpy() rather than strncpy() in case there are binary zeros +in the string. + +Arguments: + subject the subject string that was matched + ovector pointer to the offsets table + stringcount the number of substrings that were captured + (i.e. the yield of the pcre_exec call, unless + that was zero, in which case it should be 1/3 + of the offset table size) + stringnumber the number of the required substring + buffer where to put the substring + size the size of the buffer + +Returns: if successful: + the length of the copied string, not including the zero + that is put on the end; can be zero + if not successful: + PCRE_ERROR_NOMEMORY (-6) buffer too small + PCRE_ERROR_NOSUBSTRING (-7) no such captured substring +*/ + +#if defined 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) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, + int stringnumber, PCRE_UCHAR16 *buffer, int size) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_copy_substring(PCRE_SPTR32 subject, int *ovector, int stringcount, + int stringnumber, PCRE_UCHAR32 *buffer, int size) +#endif +{ +int yield; +if (stringnumber < 0 || stringnumber >= stringcount) + return PCRE_ERROR_NOSUBSTRING; +stringnumber *= 2; +yield = ovector[stringnumber+1] - ovector[stringnumber]; +if (size < yield + 1) return PCRE_ERROR_NOMEMORY; +memcpy(buffer, subject + ovector[stringnumber], IN_UCHARS(yield)); +buffer[yield] = 0; +return yield; +} + + + +/************************************************* +* Copy named captured string to given buffer * +*************************************************/ + +/* This function copies a single captured substring into a given buffer, +identifying it by name. If the regex permits duplicate names, the first +substring that is set is chosen. + +Arguments: + code the compiled regex + subject the subject string that was matched + ovector pointer to the offsets table + stringcount the number of substrings that were captured + (i.e. the yield of the pcre_exec call, unless + that was zero, in which case it should be 1/3 + of the offset table size) + stringname the name of the required substring + buffer where to put the substring + size the size of the buffer + +Returns: if successful: + the length of the copied string, not including the zero + that is put on the end; can be zero + if not successful: + PCRE_ERROR_NOMEMORY (-6) buffer too small + PCRE_ERROR_NOSUBSTRING (-7) no such captured substring +*/ + +#if defined 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) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject, + int *ovector, int stringcount, PCRE_SPTR16 stringname, + PCRE_UCHAR16 *buffer, int size) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_copy_named_substring(const pcre32 *code, PCRE_SPTR32 subject, + int *ovector, int stringcount, PCRE_SPTR32 stringname, + PCRE_UCHAR32 *buffer, int size) +#endif +{ +int n = get_first_set(code, stringname, ovector); +if (n <= 0) return n; +#if defined COMPILE_PCRE8 +return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); +#elif defined COMPILE_PCRE16 +return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size); +#elif defined COMPILE_PCRE32 +return pcre32_copy_substring(subject, ovector, stringcount, n, buffer, size); +#endif +} + + + +/************************************************* +* Copy all captured strings to new store * +*************************************************/ + +/* This function gets one chunk of store and builds a list of pointers and all +of the captured substrings in it. A NULL pointer is put on the end of the list. + +Arguments: + subject the subject string that was matched + ovector pointer to the offsets table + stringcount the number of substrings that were captured + (i.e. the yield of the pcre_exec call, unless + that was zero, in which case it should be 1/3 + of the offset table size) + listptr set to point to the list of pointers + +Returns: if successful: 0 + if not successful: + PCRE_ERROR_NOMEMORY (-6) failed to get store +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre_get_substring_list(const char *subject, int *ovector, int stringcount, + const char ***listptr) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount, + PCRE_SPTR16 **listptr) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_get_substring_list(PCRE_SPTR32 subject, int *ovector, int stringcount, + PCRE_SPTR32 **listptr) +#endif +{ +int i; +int size = sizeof(pcre_uchar *); +int double_count = stringcount * 2; +pcre_uchar **stringlist; +pcre_uchar *p; + +for (i = 0; i < double_count; i += 2) + size += sizeof(pcre_uchar *) + IN_UCHARS(ovector[i+1] - ovector[i] + 1); + +stringlist = (pcre_uchar **)(PUBL(malloc))(size); +if (stringlist == NULL) return PCRE_ERROR_NOMEMORY; + +#if defined COMPILE_PCRE8 +*listptr = (const char **)stringlist; +#elif defined COMPILE_PCRE16 +*listptr = (PCRE_SPTR16 *)stringlist; +#elif defined COMPILE_PCRE32 +*listptr = (PCRE_SPTR32 *)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], IN_UCHARS(len)); + *stringlist++ = p; + p += len; + *p++ = 0; + } + +*stringlist = NULL; +return 0; +} + + + +/************************************************* +* Free store obtained by get_substring_list * +*************************************************/ + +/* This function exists for the benefit of people calling PCRE from non-C +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 +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN void PCRE_CALL_CONVENTION +pcre_free_substring_list(const char **pointer) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN void PCRE_CALL_CONVENTION +pcre16_free_substring_list(PCRE_SPTR16 *pointer) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN void PCRE_CALL_CONVENTION +pcre32_free_substring_list(PCRE_SPTR32 *pointer) +#endif +{ +(PUBL(free))((void *)pointer); +} + + + +/************************************************* +* Copy captured string to new store * +*************************************************/ + +/* This function copies a single captured substring into a piece of new +store + +Arguments: + subject the subject string that was matched + ovector pointer to the offsets table + stringcount the number of substrings that were captured + (i.e. the yield of the pcre_exec call, unless + that was zero, in which case it should be 1/3 + of the offset table size) + stringnumber the number of the required substring + stringptr where to put a pointer to the substring + +Returns: if successful: + the length of the string, not including the zero that + is put on the end; can be zero + if not successful: + PCRE_ERROR_NOMEMORY (-6) failed to get store + PCRE_ERROR_NOSUBSTRING (-7) substring not present +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre_get_substring(const char *subject, int *ovector, int stringcount, + int stringnumber, const char **stringptr) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, + int stringnumber, PCRE_SPTR16 *stringptr) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_get_substring(PCRE_SPTR32 subject, int *ovector, int stringcount, + int stringnumber, PCRE_SPTR32 *stringptr) +#endif +{ +int yield; +pcre_uchar *substring; +if (stringnumber < 0 || stringnumber >= stringcount) + return PCRE_ERROR_NOSUBSTRING; +stringnumber *= 2; +yield = ovector[stringnumber+1] - ovector[stringnumber]; +substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1)); +if (substring == NULL) return PCRE_ERROR_NOMEMORY; +memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield)); +substring[yield] = 0; +#if defined COMPILE_PCRE8 +*stringptr = (const char *)substring; +#elif defined COMPILE_PCRE16 +*stringptr = (PCRE_SPTR16)substring; +#elif defined COMPILE_PCRE32 +*stringptr = (PCRE_SPTR32)substring; +#endif +return yield; +} + + + +/************************************************* +* Copy named captured string to new store * +*************************************************/ + +/* This function copies a single captured substring, identified by name, into +new store. If the regex permits duplicate names, the first substring that is +set is chosen. + +Arguments: + code the compiled regex + subject the subject string that was matched + ovector pointer to the offsets table + stringcount the number of substrings that were captured + (i.e. the yield of the pcre_exec call, unless + that was zero, in which case it should be 1/3 + of the offset table size) + stringname the name of the required substring + stringptr where to put the pointer + +Returns: if successful: + the length of the copied string, not including the zero + that is put on the end; can be zero + if not successful: + PCRE_ERROR_NOMEMORY (-6) couldn't get memory + PCRE_ERROR_NOSUBSTRING (-7) no such captured substring +*/ + +#if defined 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) +#elif defined COMPILE_PCRE16 +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) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_get_named_substring(const pcre32 *code, PCRE_SPTR32 subject, + int *ovector, int stringcount, PCRE_SPTR32 stringname, + PCRE_SPTR32 *stringptr) +#endif +{ +int n = get_first_set(code, stringname, ovector); +if (n <= 0) return n; +#if defined COMPILE_PCRE8 +return pcre_get_substring(subject, ovector, stringcount, n, stringptr); +#elif defined COMPILE_PCRE16 +return pcre16_get_substring(subject, ovector, stringcount, n, stringptr); +#elif defined COMPILE_PCRE32 +return pcre32_get_substring(subject, ovector, stringcount, n, stringptr); +#endif +} + + + + +/************************************************* +* Free store obtained by get_substring * +*************************************************/ + +/* This function exists for the benefit of people calling PCRE from non-C +programs that can call its functions, but not free() or (PUBL(free))() +directly. + +Argument: the result of a previous pcre_get_substring() +Returns: nothing +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN void PCRE_CALL_CONVENTION +pcre_free_substring(const char *pointer) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN void PCRE_CALL_CONVENTION +pcre16_free_substring(PCRE_SPTR16 pointer) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN void PCRE_CALL_CONVENTION +pcre32_free_substring(PCRE_SPTR32 pointer) +#endif +{ +(PUBL(free))((void *)pointer); +} + +/* End of pcre_get.c */ diff --git a/tools/pcre/pcre_globals.c b/tools/pcre/pcre_globals.c new file mode 100644 index 00000000..36e6ddb3 --- /dev/null +++ b/tools/pcre/pcre_globals.c @@ -0,0 +1,84 @@ +/************************************************* +* 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 global variables that are exported by the PCRE library. +PCRE is thread-clean and doesn't use any global variables in the normal sense. +However, it calls memory allocation and freeing functions via the four +indirections below, and it can optionally do callouts, using the fifth +indirection. These values can be changed by the caller, but are shared between +all threads. + +For MS Visual Studio and Symbian OS, there are problems in initializing these +variables to non-local functions. In these cases, therefore, an indirection via +a local function is used. + +Also, when compiling for Virtual Pascal, things are done differently, and +global variables are not used. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + +#if defined _MSC_VER || defined __SYMBIAN32__ +static void* LocalPcreMalloc(size_t aSize) + { + return malloc(aSize); + } +static void LocalPcreFree(void* aPtr) + { + free(aPtr); + } +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 *(*PUBL(malloc))(size_t) = malloc; +PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = free; +PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = malloc; +PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = free; +PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL; +#endif + +/* End of pcre_globals.c */ diff --git a/tools/pcre/pcre_internal.h b/tools/pcre/pcre_internal.h new file mode 100644 index 00000000..f3cb001f --- /dev/null +++ b/tools/pcre/pcre_internal.h @@ -0,0 +1,2744 @@ +/************************************************* +* 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 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_", "_pcre16_" or "_pcre32_" +depending on the PRIV macro. */ + +#ifndef PCRE_INTERNAL_H +#define PCRE_INTERNAL_H + +/* Define PCRE_DEBUG to get debugging output on stdout. */ + +#if 0 +#define PCRE_DEBUG +#endif + +/* PCRE is compiled as an 8 bit library if it is not requested otherwise. */ + +#if !defined COMPILE_PCRE16 && !defined COMPILE_PCRE32 +#define COMPILE_PCRE8 +#endif + +/* 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_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/32 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_UTF 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 +all, it had only been about 10 years then... + +It turns out that the Mac Debugging.h header also defines the macro DPRINTF, so +be absolutely sure we get our version. */ + +#undef DPRINTF +#ifdef PCRE_DEBUG +#define DPRINTF(p) printf p +#else +#define DPRINTF(p) /* Nothing */ +#endif + + +/* Standard C headers plus the external interface definition. The only time +setjmp and stdarg are used is when NO_RECURSE is set. */ + +#include +#include +#include +#include +#include +#include + +/* Valgrind (memcheck) support */ + +#ifdef SUPPORT_VALGRIND +#include +#endif + +/* When compiling a DLL for Windows, the exported symbols have to be declared +using some MS magic. I found some useful information on this web page: +http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the +information there, using __declspec(dllexport) without "extern" we have a +definition; with "extern" we have a declaration. The settings here override the +setting in pcre.h (which is included below); it defines only PCRE_EXP_DECL, +which is all that is needed for applications (they just import the symbols). We +use: + + PCRE_EXP_DECL for declarations + PCRE_EXP_DEFN for definitions of exported functions + PCRE_EXP_DATA_DEFN for definitions of exported variables + +The reason for the two DEFN macros is that in non-Windows environments, one +does not want to have "extern" before variable definitions because it leads to +compiler warnings. So we distinguish between functions and variables. In +Windows, the two should always be the same. + +The reason for wrapping this in #ifndef PCRE_EXP_DECL is so that pcretest, +which is an application, but needs to import this file in order to "peek" at +internals, can #include pcre.h first to get an application's-eye view. + +In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon, +special-purpose environments) might want to stick other stuff in front of +exported symbols. That's why, in the non-Windows case, we set PCRE_EXP_DEFN and +PCRE_EXP_DATA_DEFN only if they are not already set. */ + +#ifndef PCRE_EXP_DECL +# ifdef _WIN32 +# ifndef PCRE_STATIC +# define PCRE_EXP_DECL extern __declspec(dllexport) +# define PCRE_EXP_DEFN __declspec(dllexport) +# define PCRE_EXP_DATA_DEFN __declspec(dllexport) +# else +# define PCRE_EXP_DECL extern +# define PCRE_EXP_DEFN +# define PCRE_EXP_DATA_DEFN +# endif +# else +# ifdef __cplusplus +# define PCRE_EXP_DECL extern "C" +# else +# define PCRE_EXP_DECL extern +# endif +# ifndef PCRE_EXP_DEFN +# define PCRE_EXP_DEFN PCRE_EXP_DECL +# endif +# ifndef PCRE_EXP_DATA_DEFN +# define PCRE_EXP_DATA_DEFN +# endif +# endif +#endif + +/* When compiling with the MSVC compiler, it is sometimes necessary to include +a "calling convention" before exported function names. (This is secondhand +information; I know nothing about MSVC myself). For example, something like + + void __cdecl function(....) + +might be needed. In order so make this easy, all the exported functions have +PCRE_CALL_CONVENTION just before their names. It is rarely needed; if not +set, we ensure here that it has no effect. */ + +#ifndef PCRE_CALL_CONVENTION +#define PCRE_CALL_CONVENTION +#endif + +/* 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; +#elif UINT_MAX == 65535 + typedef unsigned int pcre_uint16; + typedef int pcre_int16; +#else +# error Cannot determine a type for 16-bit unsigned integers +#endif + +#if UINT_MAX == 4294967295 + typedef unsigned int pcre_uint32; + typedef int pcre_int32; +#elif ULONG_MAX == 4294967295 + typedef unsigned long int pcre_uint32; + typedef long int pcre_int32; +#else +# error Cannot determine a type for 32-bit unsigned integers +#endif + +/* When checking for integer overflow in pcre_compile(), we need to handle +large integers. If a 64-bit integer type is available, we can use that. +Otherwise we have to cast to double, which of course requires floating point +arithmetic. Handle this by defining a macro for the appropriate type. If +stdint.h is available, include it; it may define INT64_MAX. Systems that do not +have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set +by "configure". */ + +#if defined HAVE_STDINT_H +#include +#elif defined HAVE_INTTYPES_H +#include +#endif + +#if defined INT64_MAX || defined int64_t +#define INT64_OR_DOUBLE int64_t +#else +#define INT64_OR_DOUBLE double +#endif + +/* 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 * 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. +*/ + +#if defined 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]) + +#elif defined 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 UCHAR_SHIFT (1) +#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) +#define MAX_255(c) ((c) <= 255u) +#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) + +#elif defined COMPILE_PCRE32 + +typedef pcre_uint32 pcre_uchar; +#define UCHAR_SHIFT (2) +#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) +#define MAX_255(c) ((c) <= 255u) +#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) + +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE[8|16|32] */ + +/* 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 +0x0010ffff). */ + +#define NOTACHAR 0xffffffff + +/* PCRE is able to support several different kinds of newline (CR, LF, CRLF, +"any" and "anycrlf" at present). The following macros are used to package up +testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various +modules to indicate in which datablock the parameters exist, and what the +start/end of string field names are. */ + +#define NLTYPE_FIXED 0 /* Newline is a fixed length string */ +#define NLTYPE_ANY 1 /* Newline is any Unicode line ending */ +#define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */ + +/* This macro checks for a newline at the given position */ + +#define IS_NEWLINE(p) \ + ((NLBLOCK->nltype != NLTYPE_FIXED)? \ + ((p) < NLBLOCK->PSEND && \ + PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \ + &(NLBLOCK->nllen), utf)) \ + : \ + ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \ + RAWUCHARTEST(p) == NLBLOCK->nl[0] && \ + (NLBLOCK->nllen == 1 || RAWUCHARTEST(p+1) == NLBLOCK->nl[1]) \ + ) \ + ) + +/* This macro checks for a newline immediately preceding the given position */ + +#define WAS_NEWLINE(p) \ + ((NLBLOCK->nltype != NLTYPE_FIXED)? \ + ((p) > NLBLOCK->PSSTART && \ + PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \ + &(NLBLOCK->nllen), utf)) \ + : \ + ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \ + RAWUCHARTEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \ + (NLBLOCK->nllen == 1 || RAWUCHARTEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \ + ) \ + ) + +/* When PCRE is compiled as a C++ library, the subject pointer can be replaced +with a custom type. This makes it possible, for example, to allow pcre_exec() +to process subject strings that are discontinuous by using a smart pointer +class. It must always be possible to inspect all of the subject string in +pcre_exec() because of the way it backtracks. Two macros are required in the +normal case, for sign-unspecified and unsigned char pointers. The former is +used for the external interface and appears in pcre.h, which is why its name +must begin with PCRE_. */ + +#ifdef CUSTOM_SUBJECT_PTR +#define PCRE_PUCHAR CUSTOM_SUBJECT_PTR +#else +#define PCRE_PUCHAR const pcre_uchar * +#endif + +/* Include the public PCRE header and the definitions of UCP character property +values. */ + +#include "pcre.h" +#include "ucp.h" + +#ifdef COMPILE_PCRE32 +/* Assert that the public PCRE_UCHAR32 is a 32-bit type */ +typedef int __assert_pcre_uchar32_size[sizeof(PCRE_UCHAR32) == 4 ? 1 : -1]; +#endif + +/* When compiling for use with the Virtual Pascal compiler, these functions +need to have their names changed. PCRE must be compiled with the -DVPCOMPAT +option on the command line. */ + +#ifdef VPCOMPAT +#define strlen(s) _strlen(s) +#define strncmp(s1,s2,m) _strncmp(s1,s2,m) +#define memcmp(s,c,n) _memcmp(s,c,n) +#define memcpy(d,s,n) _memcpy(d,s,n) +#define memmove(d,s,n) _memmove(d,s,n) +#define memset(s,c,n) _memset(s,c,n) +#else /* VPCOMPAT */ + +/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(), +define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY +is set. Otherwise, include an emulating function for those systems that have +neither (there some non-Unix environments where this is the case). */ + +#ifndef HAVE_MEMMOVE +#undef memmove /* some systems may have a macro */ +#ifdef HAVE_BCOPY +#define memmove(a, b, c) bcopy(b, a, c) +#else /* HAVE_BCOPY */ +static void * +pcre_memmove(void *d, const void *s, size_t n) +{ +size_t i; +unsigned char *dest = (unsigned char *)d; +const unsigned char *src = (const unsigned char *)s; +if (dest > src) + { + dest += n; + src += n; + for (i = 0; i < n; ++i) *(--dest) = *(--src); + return (void *)dest; + } +else + { + for (i = 0; i < n; ++i) *dest++ = *src++; + return (void *)(dest - n); + } +} +#define memmove(a, b, c) pcre_memmove(a, b, c) +#endif /* not HAVE_BCOPY */ +#endif /* not HAVE_MEMMOVE */ +#endif /* not VPCOMPAT */ + + +/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored +in big-endian order) by default. These are used, for example, to link from the +start of a subpattern to its alternatives and its end. The use of 2 bytes per +offset limits the size of the compiled regex to around 64K, which is big enough +for almost everybody. However, I received a request for an even bigger limit. +For this reason, and also to make the code easier to maintain, the storing and +loading of offsets from the byte string is now handled by the macros that are +defined here. + +The macros are controlled by the value of LINK_SIZE. This defaults to 2 in +the config.h file, but can be overridden by using -D on the command line. This +is automated on Unix systems via the "configure" command. */ + +#if defined COMPILE_PCRE8 + +#if LINK_SIZE == 2 + +#define PUT(a,n,d) \ + (a[n] = (d) >> 8), \ + (a[(n)+1] = (d) & 255) + +#define GET(a,n) \ + (((a)[n] << 8) | (a)[(n)+1]) + +#define MAX_PATTERN_SIZE (1 << 16) + + +#elif LINK_SIZE == 3 + +#define PUT(a,n,d) \ + (a[n] = (d) >> 16), \ + (a[(n)+1] = (d) >> 8), \ + (a[(n)+2] = (d) & 255) + +#define GET(a,n) \ + (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2]) + +#define MAX_PATTERN_SIZE (1 << 24) + + +#elif LINK_SIZE == 4 + +#define PUT(a,n,d) \ + (a[n] = (d) >> 24), \ + (a[(n)+1] = (d) >> 16), \ + (a[(n)+2] = (d) >> 8), \ + (a[(n)+3] = (d) & 255) + +#define GET(a,n) \ + (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) + +/* Keep it positive */ +#define MAX_PATTERN_SIZE (1 << 30) + +#else +#error LINK_SIZE must be either 2, 3, or 4 +#endif + +#elif defined COMPILE_PCRE16 + +#if LINK_SIZE == 2 + +/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */ +#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 + +/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */ +#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 + +#elif defined COMPILE_PCRE32 + +/* Only supported LINK_SIZE is 4 */ +/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */ +#undef LINK_SIZE +#define LINK_SIZE 1 + +#define PUT(a,n,d) \ + (a[n] = (d)) + +#define GET(a,n) \ + (a[n]) + +/* Keep it positive */ +#define MAX_PATTERN_SIZE (1 << 30) + +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE[8|16|32] */ + +/* Convenience macro defined in terms of the others */ + +#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE + + +/* PCRE uses some other 2-byte quantities that do not change when the size of +offsets changes. There are used for repeat counts and for other things such as +capturing parenthesis numbers in back references. */ + +#if defined COMPILE_PCRE8 + +#define IMM2_SIZE 2 + +#define PUT2(a,n,d) \ + a[n] = (d) >> 8; \ + a[(n)+1] = (d) & 255 + +/* For reasons that I do not understand, the expression in this GET2 macro is +treated by gcc as a signed expression, even when a is declared as unsigned. It +seems that any kind of arithmetic results in a signed value. */ + +#define GET2(a,n) \ + (unsigned int)(((a)[n] << 8) | (a)[(n)+1]) + +#elif defined COMPILE_PCRE16 + +#define IMM2_SIZE 1 + +#define PUT2(a,n,d) \ + a[n] = d + +#define GET2(a,n) \ + a[n] + +#elif defined COMPILE_PCRE32 + +#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_PCRE[8|16|32] */ + +#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. */ + +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#define MAX_MARK ((1u << 16) - 1) +#else +#define MAX_MARK ((1u << 8) - 1) +#endif + +/* When UTF encoding is being used, a character is no longer just a single +byte. The macros for character handling generate simple sequences when used in +character-mode, and more complicated ones for UTF characters. GETCHARLENTEST +and other macros are not used when UTF is not supported, so they are not +defined. To make sure they can never even appear when UTF support is omitted, +we don't even define them. */ + +#ifndef SUPPORT_UTF + +/* #define MAX_VALUE_FOR_SINGLE_CHAR */ +/* #define HAS_EXTRALEN(c) */ +/* #define GET_EXTRALEN(c) */ +/* #define NOT_FIRSTCHAR(c) */ +#define GETCHAR(c, eptr) c = *eptr; +#define GETCHARTEST(c, eptr) c = *eptr; +#define GETCHARINC(c, eptr) c = *eptr++; +#define GETCHARINCTEST(c, eptr) c = *eptr++; +#define GETCHARLEN(c, eptr, len) c = *eptr; +#define RAWUCHAR(eptr) (*(eptr)) +#define RAWUCHARINC(eptr) (*(eptr)++) +#define RAWUCHARTEST(eptr) (*(eptr)) +#define RAWUCHARINCTEST(eptr) (*(eptr)++) +/* #define GETCHARLENTEST(c, eptr, len) */ +/* #define BACKCHAR(eptr) */ +/* #define FORWARDCHAR(eptr) */ +/* #define ACROSSCHAR(condition, eptr, action) */ + +#else /* SUPPORT_UTF */ + +/* Tests whether the code point needs extra characters to decode. */ + +#define HASUTF8EXTRALEN(c) ((c) >= 0xc0) + +/* Base macro to pick up the remaining bytes of a UTF-8 character, not +advancing the pointer. */ + +#define GETUTF8(c, eptr) \ + { \ + if ((c & 0x20) == 0) \ + c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \ + else if ((c & 0x10) == 0) \ + c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ + else if ((c & 0x08) == 0) \ + c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \ + ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \ + else if ((c & 0x04) == 0) \ + c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \ + ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \ + (eptr[4] & 0x3f); \ + else \ + c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \ + ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \ + ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ + } + +/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing +the pointer. */ + +#define GETUTF8INC(c, eptr) \ + { \ + if ((c & 0x20) == 0) \ + c = ((c & 0x1f) << 6) | (*eptr++ & 0x3f); \ + else if ((c & 0x10) == 0) \ + { \ + c = ((c & 0x0f) << 12) | ((*eptr & 0x3f) << 6) | (eptr[1] & 0x3f); \ + eptr += 2; \ + } \ + else if ((c & 0x08) == 0) \ + { \ + c = ((c & 0x07) << 18) | ((*eptr & 0x3f) << 12) | \ + ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ + eptr += 3; \ + } \ + else if ((c & 0x04) == 0) \ + { \ + c = ((c & 0x03) << 24) | ((*eptr & 0x3f) << 18) | \ + ((eptr[1] & 0x3f) << 12) | ((eptr[2] & 0x3f) << 6) | \ + (eptr[3] & 0x3f); \ + eptr += 4; \ + } \ + else \ + { \ + c = ((c & 0x01) << 30) | ((*eptr & 0x3f) << 24) | \ + ((eptr[1] & 0x3f) << 18) | ((eptr[2] & 0x3f) << 12) | \ + ((eptr[3] & 0x3f) << 6) | (eptr[4] & 0x3f); \ + eptr += 5; \ + } \ + } + +#if defined COMPILE_PCRE8 + +/* These macros were originally written in the form of loops that used data +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) + +/* Get the next UTF-8 character, not advancing the pointer. This is called when +we know we are in UTF-8 mode. */ + +#define GETCHAR(c, eptr) \ + c = *eptr; \ + if (c >= 0xc0) GETUTF8(c, eptr); + +/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the +pointer. */ + +#define GETCHARTEST(c, eptr) \ + c = *eptr; \ + if (utf && c >= 0xc0) GETUTF8(c, eptr); + +/* Get the next UTF-8 character, advancing the pointer. This is called when we +know we are in UTF-8 mode. */ + +#define GETCHARINC(c, eptr) \ + c = *eptr++; \ + if (c >= 0xc0) GETUTF8INC(c, eptr); + +/* Get the next character, testing for UTF-8 mode, and advancing the pointer. +This is called when we don't know if we are in UTF-8 mode. */ + +#define GETCHARINCTEST(c, eptr) \ + 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. */ + +#define GETUTF8LEN(c, eptr, len) \ + { \ + if ((c & 0x20) == 0) \ + { \ + c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \ + len++; \ + } \ + else if ((c & 0x10) == 0) \ + { \ + c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \ + len += 2; \ + } \ + else if ((c & 0x08) == 0) \ + {\ + c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \ + ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \ + len += 3; \ + } \ + else if ((c & 0x04) == 0) \ + { \ + c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \ + ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \ + (eptr[4] & 0x3f); \ + len += 4; \ + } \ + else \ + {\ + c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \ + ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \ + ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ + len += 5; \ + } \ + } + +/* Get the next UTF-8 character, not advancing the pointer, incrementing length +if there are extra bytes. This is called when we know we are in UTF-8 mode. */ + +#define GETCHARLEN(c, eptr, len) \ + c = *eptr; \ + if (c >= 0xc0) GETUTF8LEN(c, eptr, len); + +/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the +pointer, incrementing length if there are extra bytes. This is called when we +do not know if we are in UTF-8 mode. */ + +#define GETCHARLENTEST(c, eptr, len) \ + c = *eptr; \ + if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len); + +/* Returns the next uchar, not advancing the pointer. This is called when +we know we are in UTF mode. */ + +#define RAWUCHAR(eptr) \ + (*(eptr)) + +/* Returns the next uchar, advancing the pointer. This is called when +we know we are in UTF mode. */ + +#define RAWUCHARINC(eptr) \ + (*((eptr)++)) + +/* Returns the next uchar, testing for UTF mode, and not advancing the +pointer. */ + +#define RAWUCHARTEST(eptr) \ + (*(eptr)) + +/* Returns the next uchar, testing for UTF mode, advancing the +pointer. */ + +#define RAWUCHARINCTEST(eptr) \ + (*((eptr)++)) + +/* 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 +because almost all calls are already within a block of UTF-8 only code. */ + +#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr-- + +/* 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 + +#elif defined 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); + +/* Returns the next uchar, not advancing the pointer. This is called when +we know we are in UTF mode. */ + +#define RAWUCHAR(eptr) \ + (*(eptr)) + +/* Returns the next uchar, advancing the pointer. This is called when +we know we are in UTF mode. */ + +#define RAWUCHARINC(eptr) \ + (*((eptr)++)) + +/* Returns the next uchar, testing for UTF mode, and not advancing the +pointer. */ + +#define RAWUCHARTEST(eptr) \ + (*(eptr)) + +/* Returns the next uchar, testing for UTF mode, advancing the +pointer. */ + +#define RAWUCHARINCTEST(eptr) \ + (*((eptr)++)) + +/* 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 + +#elif defined COMPILE_PCRE32 + +/* These are trivial for the 32-bit library, since all UTF-32 characters fit +into one pcre_uchar unit. */ +#define MAX_VALUE_FOR_SINGLE_CHAR (0x10ffffu) +#define HAS_EXTRALEN(c) (0) +#define GET_EXTRALEN(c) (0) +#define NOT_FIRSTCHAR(c) (0) + +/* Get the next UTF-32 character, not advancing the pointer. This is called when +we know we are in UTF-32 mode. */ + +#define GETCHAR(c, eptr) \ + c = *(eptr); + +/* Get the next UTF-32 character, testing for UTF-32 mode, and not advancing the +pointer. */ + +#define GETCHARTEST(c, eptr) \ + c = *(eptr); + +/* Get the next UTF-32 character, advancing the pointer. This is called when we +know we are in UTF-32 mode. */ + +#define GETCHARINC(c, eptr) \ + c = *((eptr)++); + +/* Get the next character, testing for UTF-32 mode, and advancing the pointer. +This is called when we don't know if we are in UTF-32 mode. */ + +#define GETCHARINCTEST(c, eptr) \ + c = *((eptr)++); + +/* Get the next UTF-32 character, not advancing the pointer, not incrementing +length (since all UTF-32 is of length 1). This is called when we know we are in +UTF-32 mode. */ + +#define GETCHARLEN(c, eptr, len) \ + GETCHAR(c, eptr) + +/* Get the next UTF-32character, testing for UTF-32 mode, not advancing the +pointer, not incrementing the length (since all UTF-32 is of length 1). +This is called when we do not know if we are in UTF-32 mode. */ + +#define GETCHARLENTEST(c, eptr, len) \ + GETCHARTEST(c, eptr) + +/* Returns the next uchar, not advancing the pointer. This is called when +we know we are in UTF mode. */ + +#define RAWUCHAR(eptr) \ + (*(eptr)) + +/* Returns the next uchar, advancing the pointer. This is called when +we know we are in UTF mode. */ + +#define RAWUCHARINC(eptr) \ + (*((eptr)++)) + +/* Returns the next uchar, testing for UTF mode, and not advancing the +pointer. */ + +#define RAWUCHARTEST(eptr) \ + (*(eptr)) + +/* Returns the next uchar, testing for UTF mode, advancing the +pointer. */ + +#define RAWUCHARINCTEST(eptr) \ + (*((eptr)++)) + +/* If the pointer is not at the start of a character, move it back until +it is. This is called only in UTF-32 mode - we don't put a test within the +macro because almost all calls are already within a block of UTF-32 only +code. +These are all no-ops since all UTF-32 characters fit into one pcre_uchar. */ + +#define BACKCHAR(eptr) do { } while (0) + +/* Same as above, just in the other direction. */ +#define FORWARDCHAR(eptr) do { } while (0) + +/* Same as above, but it allows a fully customizable form. */ +#define ACROSSCHAR(condition, eptr, action) do { } while (0) + +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE[8|16|32] */ + +#endif /* SUPPORT_UTF */ + +/* Tests for Unicode horizontal and vertical whitespace characters must check a +number of different values. Using a switch statement for this generates the +fastest code (no loop, no memory access), and there are several places in the +interpreter code where this happens. In order to ensure that all the case lists +remain in step, we use macros so that there is only one place where the lists +are defined. + +These values are also required as lists in pcre_compile.c when processing \h, +\H, \v and \V in a character class. The lists are defined in pcre_tables.c, but +macros that define the values are here so that all the definitions are +together. The lists must be in ascending character order, terminated by +NOTACHAR (which is 0xffffffff). + +Any changes should ensure that the various macros are kept in step with each +other. NOTE: The values also appear in pcre_jit_compile.c. */ + +/* ------ ASCII/Unicode environments ------ */ + +#ifndef EBCDIC + +#define HSPACE_LIST \ + CHAR_HT, CHAR_SPACE, 0xa0, \ + 0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \ + 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \ + NOTACHAR + +#define HSPACE_MULTIBYTE_CASES \ + 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 */ + +#define HSPACE_BYTE_CASES \ + case CHAR_HT: \ + case CHAR_SPACE: \ + case 0xa0 /* NBSP */ + +#define HSPACE_CASES \ + HSPACE_BYTE_CASES: \ + HSPACE_MULTIBYTE_CASES + +#define VSPACE_LIST \ + CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, 0x2028, 0x2029, NOTACHAR + +#define VSPACE_MULTIBYTE_CASES \ + case 0x2028: /* LINE SEPARATOR */ \ + case 0x2029 /* PARAGRAPH SEPARATOR */ + +#define VSPACE_BYTE_CASES \ + case CHAR_LF: \ + case CHAR_VT: \ + case CHAR_FF: \ + case CHAR_CR: \ + case CHAR_NEL + +#define VSPACE_CASES \ + VSPACE_BYTE_CASES: \ + VSPACE_MULTIBYTE_CASES + +/* ------ EBCDIC environments ------ */ + +#else +#define HSPACE_LIST CHAR_HT, CHAR_SPACE + +#define HSPACE_BYTE_CASES \ + case CHAR_HT: \ + case CHAR_SPACE + +#define HSPACE_CASES HSPACE_BYTE_CASES + +#ifdef EBCDIC_NL25 +#define VSPACE_LIST \ + CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, CHAR_LF, NOTACHAR +#else +#define VSPACE_LIST \ + CHAR_VT, CHAR_FF, CHAR_CR, CHAR_LF, CHAR_NEL, NOTACHAR +#endif + +#define VSPACE_BYTE_CASES \ + case CHAR_LF: \ + case CHAR_VT: \ + case CHAR_FF: \ + case CHAR_CR: \ + case CHAR_NEL + +#define VSPACE_CASES VSPACE_BYTE_CASES +#endif /* EBCDIC */ + +/* ------ End of whitespace macros ------ */ + + + +/* 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_MODE8 0x0001 /* compiled in 8 bit mode */ +#define PCRE_MODE16 0x0002 /* compiled in 16 bit mode */ +#define PCRE_MODE32 0x0004 /* compiled in 32 bit mode */ +#define PCRE_FIRSTSET 0x0010 /* first_char is set */ +#define PCRE_FCH_CASELESS 0x0020 /* caseless first char */ +#define PCRE_REQCHSET 0x0040 /* req_byte is set */ +#define PCRE_RCH_CASELESS 0x0080 /* caseless requested char */ +#define PCRE_STARTLINE 0x0100 /* start after \n for multiline */ +#define PCRE_NOPARTIAL 0x0200 /* can't use partial with this regex */ +#define PCRE_JCHANGED 0x0400 /* j option used in regex */ +#define PCRE_HASCRORLF 0x0800 /* explicit \r or \n in pattern */ +#define PCRE_HASTHEN 0x1000 /* pattern contains (*THEN) */ + +#if defined COMPILE_PCRE8 +#define PCRE_MODE PCRE_MODE8 +#elif defined COMPILE_PCRE16 +#define PCRE_MODE PCRE_MODE16 +#elif defined COMPILE_PCRE32 +#define PCRE_MODE PCRE_MODE32 +#endif +#define PCRE_MODE_MASK (PCRE_MODE8 | PCRE_MODE16 | PCRE_MODE32) + +/* Flags for the "extra" block produced by pcre_study(). */ + +#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. */ + +#define PCRE_NEWLINE_BITS (PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_ANY| \ + PCRE_NEWLINE_ANYCRLF) + +#define PUBLIC_COMPILE_OPTIONS \ + (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \ + PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \ + PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \ + PCRE_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \ + PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE) + +#define PUBLIC_EXEC_OPTIONS \ + (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \ + PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_NEWLINE_BITS| \ + PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE|PCRE_NO_START_OPTIMIZE) + +#define PUBLIC_DFA_EXEC_OPTIONS \ + (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \ + PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_DFA_SHORTEST| \ + PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \ + PCRE_NO_START_OPTIMIZE) + +#define PUBLIC_STUDY_OPTIONS \ + (PCRE_STUDY_JIT_COMPILE|PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE| \ + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE|PCRE_STUDY_EXTRA_NEEDED) + +#define PUBLIC_JIT_EXEC_OPTIONS \ + (PCRE_NO_UTF8_CHECK|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|\ + PCRE_NOTEMPTY_ATSTART|PCRE_PARTIAL_SOFT|PCRE_PARTIAL_HARD) + +/* 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' */ + +/* The maximum remaining length of subject we are prepared to search for a +req_byte match. */ + +#define REQ_BYTE_MAX 1000 + +/* 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. */ + +typedef int BOOL; + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +/* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal +character constants like '*' because the compiler would emit their EBCDIC code, +which is different from their ASCII/UTF-8 code. Instead we define macros for +the characters so that they always use the ASCII/UTF-8 code when UTF-8 support +is enabled. When UTF-8 support is not enabled, the definitions use character +literals. Both character and string versions of each character are needed, and +there are some longer strings as well. + +This means that, on EBCDIC platforms, the PCRE library can handle either +EBCDIC, or UTF-8, but not both. To support both in the same compiled library +would need different lookups depending on whether PCRE_UTF8 was set or not. +This would make it impossible to use characters in switch/case statements, +which would reduce performance. For a theoretical use (which nobody has asked +for) in a minority area (EBCDIC platforms), this is not sensible. Any +application that did need both could compile two versions of the library, using +macros to give the functions distinct names. */ + +#ifndef SUPPORT_UTF + +/* UTF-8 support is not enabled; use the platform-dependent character literals +so that PCRE works in both ASCII and EBCDIC environments, but only in non-UTF +mode. Newline characters are problematic in EBCDIC. Though it has CR and LF +characters, a common practice has been to use its NL (0x15) character as the +line terminator in C-like processing environments. However, sometimes the LF +(0x25) character is used instead, according to this Unicode document: + +http://unicode.org/standard/reports/tr13/tr13-5.html + +PCRE defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25 +instead. Whichever is *not* chosen is defined as NEL. + +In both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the +same code point. */ + +#ifdef EBCDIC + +#ifndef EBCDIC_NL25 +#define CHAR_NL '\x15' +#define CHAR_NEL '\x25' +#define STR_NL "\x15" +#define STR_NEL "\x25" +#else +#define CHAR_NL '\x25' +#define CHAR_NEL '\x15' +#define STR_NL "\x25" +#define STR_NEL "\x15" +#endif + +#define CHAR_LF CHAR_NL +#define STR_LF STR_NL + +#define CHAR_ESC '\047' +#define CHAR_DEL '\007' +#define STR_ESC "\047" +#define STR_DEL "\007" + +#else /* Not EBCDIC */ + +/* In ASCII/Unicode, linefeed is '\n' and we equate this to NL for +compatibility. NEL is the Unicode newline character; make sure it is +a positive value. */ + +#define CHAR_LF '\n' +#define CHAR_NL CHAR_LF +#define CHAR_NEL ((unsigned char)'\x85') +#define CHAR_ESC '\033' +#define CHAR_DEL '\177' + +#define STR_LF "\n" +#define STR_NL STR_LF +#define STR_NEL "\x85" +#define STR_ESC "\033" +#define STR_DEL "\177" + +#endif /* EBCDIC */ + +/* The remaining definitions work in both environments. */ + +#define CHAR_NULL '\0' +#define CHAR_HT '\t' +#define CHAR_VT '\v' +#define CHAR_FF '\f' +#define CHAR_CR '\r' +#define CHAR_BS '\b' +#define CHAR_BEL '\a' + +#define CHAR_SPACE ' ' +#define CHAR_EXCLAMATION_MARK '!' +#define CHAR_QUOTATION_MARK '"' +#define CHAR_NUMBER_SIGN '#' +#define CHAR_DOLLAR_SIGN '$' +#define CHAR_PERCENT_SIGN '%' +#define CHAR_AMPERSAND '&' +#define CHAR_APOSTROPHE '\'' +#define CHAR_LEFT_PARENTHESIS '(' +#define CHAR_RIGHT_PARENTHESIS ')' +#define CHAR_ASTERISK '*' +#define CHAR_PLUS '+' +#define CHAR_COMMA ',' +#define CHAR_MINUS '-' +#define CHAR_DOT '.' +#define CHAR_SLASH '/' +#define CHAR_0 '0' +#define CHAR_1 '1' +#define CHAR_2 '2' +#define CHAR_3 '3' +#define CHAR_4 '4' +#define CHAR_5 '5' +#define CHAR_6 '6' +#define CHAR_7 '7' +#define CHAR_8 '8' +#define CHAR_9 '9' +#define CHAR_COLON ':' +#define CHAR_SEMICOLON ';' +#define CHAR_LESS_THAN_SIGN '<' +#define CHAR_EQUALS_SIGN '=' +#define CHAR_GREATER_THAN_SIGN '>' +#define CHAR_QUESTION_MARK '?' +#define CHAR_COMMERCIAL_AT '@' +#define CHAR_A 'A' +#define CHAR_B 'B' +#define CHAR_C 'C' +#define CHAR_D 'D' +#define CHAR_E 'E' +#define CHAR_F 'F' +#define CHAR_G 'G' +#define CHAR_H 'H' +#define CHAR_I 'I' +#define CHAR_J 'J' +#define CHAR_K 'K' +#define CHAR_L 'L' +#define CHAR_M 'M' +#define CHAR_N 'N' +#define CHAR_O 'O' +#define CHAR_P 'P' +#define CHAR_Q 'Q' +#define CHAR_R 'R' +#define CHAR_S 'S' +#define CHAR_T 'T' +#define CHAR_U 'U' +#define CHAR_V 'V' +#define CHAR_W 'W' +#define CHAR_X 'X' +#define CHAR_Y 'Y' +#define CHAR_Z 'Z' +#define CHAR_LEFT_SQUARE_BRACKET '[' +#define CHAR_BACKSLASH '\\' +#define CHAR_RIGHT_SQUARE_BRACKET ']' +#define CHAR_CIRCUMFLEX_ACCENT '^' +#define CHAR_UNDERSCORE '_' +#define CHAR_GRAVE_ACCENT '`' +#define CHAR_a 'a' +#define CHAR_b 'b' +#define CHAR_c 'c' +#define CHAR_d 'd' +#define CHAR_e 'e' +#define CHAR_f 'f' +#define CHAR_g 'g' +#define CHAR_h 'h' +#define CHAR_i 'i' +#define CHAR_j 'j' +#define CHAR_k 'k' +#define CHAR_l 'l' +#define CHAR_m 'm' +#define CHAR_n 'n' +#define CHAR_o 'o' +#define CHAR_p 'p' +#define CHAR_q 'q' +#define CHAR_r 'r' +#define CHAR_s 's' +#define CHAR_t 't' +#define CHAR_u 'u' +#define CHAR_v 'v' +#define CHAR_w 'w' +#define CHAR_x 'x' +#define CHAR_y 'y' +#define CHAR_z 'z' +#define CHAR_LEFT_CURLY_BRACKET '{' +#define CHAR_VERTICAL_LINE '|' +#define CHAR_RIGHT_CURLY_BRACKET '}' +#define CHAR_TILDE '~' + +#define STR_HT "\t" +#define STR_VT "\v" +#define STR_FF "\f" +#define STR_CR "\r" +#define STR_BS "\b" +#define STR_BEL "\a" + +#define STR_SPACE " " +#define STR_EXCLAMATION_MARK "!" +#define STR_QUOTATION_MARK "\"" +#define STR_NUMBER_SIGN "#" +#define STR_DOLLAR_SIGN "$" +#define STR_PERCENT_SIGN "%" +#define STR_AMPERSAND "&" +#define STR_APOSTROPHE "'" +#define STR_LEFT_PARENTHESIS "(" +#define STR_RIGHT_PARENTHESIS ")" +#define STR_ASTERISK "*" +#define STR_PLUS "+" +#define STR_COMMA "," +#define STR_MINUS "-" +#define STR_DOT "." +#define STR_SLASH "/" +#define STR_0 "0" +#define STR_1 "1" +#define STR_2 "2" +#define STR_3 "3" +#define STR_4 "4" +#define STR_5 "5" +#define STR_6 "6" +#define STR_7 "7" +#define STR_8 "8" +#define STR_9 "9" +#define STR_COLON ":" +#define STR_SEMICOLON ";" +#define STR_LESS_THAN_SIGN "<" +#define STR_EQUALS_SIGN "=" +#define STR_GREATER_THAN_SIGN ">" +#define STR_QUESTION_MARK "?" +#define STR_COMMERCIAL_AT "@" +#define STR_A "A" +#define STR_B "B" +#define STR_C "C" +#define STR_D "D" +#define STR_E "E" +#define STR_F "F" +#define STR_G "G" +#define STR_H "H" +#define STR_I "I" +#define STR_J "J" +#define STR_K "K" +#define STR_L "L" +#define STR_M "M" +#define STR_N "N" +#define STR_O "O" +#define STR_P "P" +#define STR_Q "Q" +#define STR_R "R" +#define STR_S "S" +#define STR_T "T" +#define STR_U "U" +#define STR_V "V" +#define STR_W "W" +#define STR_X "X" +#define STR_Y "Y" +#define STR_Z "Z" +#define STR_LEFT_SQUARE_BRACKET "[" +#define STR_BACKSLASH "\\" +#define STR_RIGHT_SQUARE_BRACKET "]" +#define STR_CIRCUMFLEX_ACCENT "^" +#define STR_UNDERSCORE "_" +#define STR_GRAVE_ACCENT "`" +#define STR_a "a" +#define STR_b "b" +#define STR_c "c" +#define STR_d "d" +#define STR_e "e" +#define STR_f "f" +#define STR_g "g" +#define STR_h "h" +#define STR_i "i" +#define STR_j "j" +#define STR_k "k" +#define STR_l "l" +#define STR_m "m" +#define STR_n "n" +#define STR_o "o" +#define STR_p "p" +#define STR_q "q" +#define STR_r "r" +#define STR_s "s" +#define STR_t "t" +#define STR_u "u" +#define STR_v "v" +#define STR_w "w" +#define STR_x "x" +#define STR_y "y" +#define STR_z "z" +#define STR_LEFT_CURLY_BRACKET "{" +#define STR_VERTICAL_LINE "|" +#define STR_RIGHT_CURLY_BRACKET "}" +#define STR_TILDE "~" + +#define STRING_ACCEPT0 "ACCEPT\0" +#define STRING_COMMIT0 "COMMIT\0" +#define STRING_F0 "F\0" +#define STRING_FAIL0 "FAIL\0" +#define STRING_MARK0 "MARK\0" +#define STRING_PRUNE0 "PRUNE\0" +#define STRING_SKIP0 "SKIP\0" +#define STRING_THEN "THEN" + +#define STRING_alpha0 "alpha\0" +#define STRING_lower0 "lower\0" +#define STRING_upper0 "upper\0" +#define STRING_alnum0 "alnum\0" +#define STRING_ascii0 "ascii\0" +#define STRING_blank0 "blank\0" +#define STRING_cntrl0 "cntrl\0" +#define STRING_digit0 "digit\0" +#define STRING_graph0 "graph\0" +#define STRING_print0 "print\0" +#define STRING_punct0 "punct\0" +#define STRING_space0 "space\0" +#define STRING_word0 "word\0" +#define STRING_xdigit "xdigit" + +#define STRING_DEFINE "DEFINE" + +#define STRING_CR_RIGHTPAR "CR)" +#define STRING_LF_RIGHTPAR "LF)" +#define STRING_CRLF_RIGHTPAR "CRLF)" +#define STRING_ANY_RIGHTPAR "ANY)" +#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)" +#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)" +#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)" +#define STRING_UTF8_RIGHTPAR "UTF8)" +#define STRING_UTF16_RIGHTPAR "UTF16)" +#define STRING_UTF32_RIGHTPAR "UTF32)" +#define STRING_UTF_RIGHTPAR "UTF)" +#define STRING_UCP_RIGHTPAR "UCP)" +#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" + +#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 +only. */ + +#define CHAR_HT '\011' +#define CHAR_VT '\013' +#define CHAR_FF '\014' +#define CHAR_CR '\015' +#define CHAR_LF '\012' +#define CHAR_NL CHAR_LF +#define CHAR_NEL ((unsigned char)'\x85') +#define CHAR_BS '\010' +#define CHAR_BEL '\007' +#define CHAR_ESC '\033' +#define CHAR_DEL '\177' + +#define CHAR_NULL '\0' +#define CHAR_SPACE '\040' +#define CHAR_EXCLAMATION_MARK '\041' +#define CHAR_QUOTATION_MARK '\042' +#define CHAR_NUMBER_SIGN '\043' +#define CHAR_DOLLAR_SIGN '\044' +#define CHAR_PERCENT_SIGN '\045' +#define CHAR_AMPERSAND '\046' +#define CHAR_APOSTROPHE '\047' +#define CHAR_LEFT_PARENTHESIS '\050' +#define CHAR_RIGHT_PARENTHESIS '\051' +#define CHAR_ASTERISK '\052' +#define CHAR_PLUS '\053' +#define CHAR_COMMA '\054' +#define CHAR_MINUS '\055' +#define CHAR_DOT '\056' +#define CHAR_SLASH '\057' +#define CHAR_0 '\060' +#define CHAR_1 '\061' +#define CHAR_2 '\062' +#define CHAR_3 '\063' +#define CHAR_4 '\064' +#define CHAR_5 '\065' +#define CHAR_6 '\066' +#define CHAR_7 '\067' +#define CHAR_8 '\070' +#define CHAR_9 '\071' +#define CHAR_COLON '\072' +#define CHAR_SEMICOLON '\073' +#define CHAR_LESS_THAN_SIGN '\074' +#define CHAR_EQUALS_SIGN '\075' +#define CHAR_GREATER_THAN_SIGN '\076' +#define CHAR_QUESTION_MARK '\077' +#define CHAR_COMMERCIAL_AT '\100' +#define CHAR_A '\101' +#define CHAR_B '\102' +#define CHAR_C '\103' +#define CHAR_D '\104' +#define CHAR_E '\105' +#define CHAR_F '\106' +#define CHAR_G '\107' +#define CHAR_H '\110' +#define CHAR_I '\111' +#define CHAR_J '\112' +#define CHAR_K '\113' +#define CHAR_L '\114' +#define CHAR_M '\115' +#define CHAR_N '\116' +#define CHAR_O '\117' +#define CHAR_P '\120' +#define CHAR_Q '\121' +#define CHAR_R '\122' +#define CHAR_S '\123' +#define CHAR_T '\124' +#define CHAR_U '\125' +#define CHAR_V '\126' +#define CHAR_W '\127' +#define CHAR_X '\130' +#define CHAR_Y '\131' +#define CHAR_Z '\132' +#define CHAR_LEFT_SQUARE_BRACKET '\133' +#define CHAR_BACKSLASH '\134' +#define CHAR_RIGHT_SQUARE_BRACKET '\135' +#define CHAR_CIRCUMFLEX_ACCENT '\136' +#define CHAR_UNDERSCORE '\137' +#define CHAR_GRAVE_ACCENT '\140' +#define CHAR_a '\141' +#define CHAR_b '\142' +#define CHAR_c '\143' +#define CHAR_d '\144' +#define CHAR_e '\145' +#define CHAR_f '\146' +#define CHAR_g '\147' +#define CHAR_h '\150' +#define CHAR_i '\151' +#define CHAR_j '\152' +#define CHAR_k '\153' +#define CHAR_l '\154' +#define CHAR_m '\155' +#define CHAR_n '\156' +#define CHAR_o '\157' +#define CHAR_p '\160' +#define CHAR_q '\161' +#define CHAR_r '\162' +#define CHAR_s '\163' +#define CHAR_t '\164' +#define CHAR_u '\165' +#define CHAR_v '\166' +#define CHAR_w '\167' +#define CHAR_x '\170' +#define CHAR_y '\171' +#define CHAR_z '\172' +#define CHAR_LEFT_CURLY_BRACKET '\173' +#define CHAR_VERTICAL_LINE '\174' +#define CHAR_RIGHT_CURLY_BRACKET '\175' +#define CHAR_TILDE '\176' + +#define STR_HT "\011" +#define STR_VT "\013" +#define STR_FF "\014" +#define STR_CR "\015" +#define STR_NL "\012" +#define STR_BS "\010" +#define STR_BEL "\007" +#define STR_ESC "\033" +#define STR_DEL "\177" + +#define STR_SPACE "\040" +#define STR_EXCLAMATION_MARK "\041" +#define STR_QUOTATION_MARK "\042" +#define STR_NUMBER_SIGN "\043" +#define STR_DOLLAR_SIGN "\044" +#define STR_PERCENT_SIGN "\045" +#define STR_AMPERSAND "\046" +#define STR_APOSTROPHE "\047" +#define STR_LEFT_PARENTHESIS "\050" +#define STR_RIGHT_PARENTHESIS "\051" +#define STR_ASTERISK "\052" +#define STR_PLUS "\053" +#define STR_COMMA "\054" +#define STR_MINUS "\055" +#define STR_DOT "\056" +#define STR_SLASH "\057" +#define STR_0 "\060" +#define STR_1 "\061" +#define STR_2 "\062" +#define STR_3 "\063" +#define STR_4 "\064" +#define STR_5 "\065" +#define STR_6 "\066" +#define STR_7 "\067" +#define STR_8 "\070" +#define STR_9 "\071" +#define STR_COLON "\072" +#define STR_SEMICOLON "\073" +#define STR_LESS_THAN_SIGN "\074" +#define STR_EQUALS_SIGN "\075" +#define STR_GREATER_THAN_SIGN "\076" +#define STR_QUESTION_MARK "\077" +#define STR_COMMERCIAL_AT "\100" +#define STR_A "\101" +#define STR_B "\102" +#define STR_C "\103" +#define STR_D "\104" +#define STR_E "\105" +#define STR_F "\106" +#define STR_G "\107" +#define STR_H "\110" +#define STR_I "\111" +#define STR_J "\112" +#define STR_K "\113" +#define STR_L "\114" +#define STR_M "\115" +#define STR_N "\116" +#define STR_O "\117" +#define STR_P "\120" +#define STR_Q "\121" +#define STR_R "\122" +#define STR_S "\123" +#define STR_T "\124" +#define STR_U "\125" +#define STR_V "\126" +#define STR_W "\127" +#define STR_X "\130" +#define STR_Y "\131" +#define STR_Z "\132" +#define STR_LEFT_SQUARE_BRACKET "\133" +#define STR_BACKSLASH "\134" +#define STR_RIGHT_SQUARE_BRACKET "\135" +#define STR_CIRCUMFLEX_ACCENT "\136" +#define STR_UNDERSCORE "\137" +#define STR_GRAVE_ACCENT "\140" +#define STR_a "\141" +#define STR_b "\142" +#define STR_c "\143" +#define STR_d "\144" +#define STR_e "\145" +#define STR_f "\146" +#define STR_g "\147" +#define STR_h "\150" +#define STR_i "\151" +#define STR_j "\152" +#define STR_k "\153" +#define STR_l "\154" +#define STR_m "\155" +#define STR_n "\156" +#define STR_o "\157" +#define STR_p "\160" +#define STR_q "\161" +#define STR_r "\162" +#define STR_s "\163" +#define STR_t "\164" +#define STR_u "\165" +#define STR_v "\166" +#define STR_w "\167" +#define STR_x "\170" +#define STR_y "\171" +#define STR_z "\172" +#define STR_LEFT_CURLY_BRACKET "\173" +#define STR_VERTICAL_LINE "\174" +#define STR_RIGHT_CURLY_BRACKET "\175" +#define STR_TILDE "\176" + +#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0" +#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0" +#define STRING_F0 STR_F "\0" +#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0" +#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0" +#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0" +#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0" +#define STRING_THEN STR_T STR_H STR_E STR_N + +#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0" +#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0" +#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0" +#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0" +#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0" +#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0" +#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0" +#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0" +#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0" +#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0" +#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0" +#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0" +#define STRING_word0 STR_w STR_o STR_r STR_d "\0" +#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t + +#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E + +#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS +#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS +#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS +#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS +#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS +#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS +#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS +#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS +#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS + +#endif /* SUPPORT_UTF */ + +/* Escape items that are just an encoding of a particular data value. */ + +#ifndef ESC_e +#define ESC_e CHAR_ESC +#endif + +#ifndef ESC_f +#define ESC_f CHAR_FF +#endif + +#ifndef ESC_n +#define ESC_n CHAR_LF +#endif + +#ifndef ESC_r +#define ESC_r CHAR_CR +#endif + +/* We can't officially use ESC_t because it is a POSIX reserved identifier +(presumably because of all the others like size_t). */ + +#ifndef ESC_tee +#define ESC_tee CHAR_HT +#endif + +/* Codes for different types of Unicode property */ + +#define PT_ANY 0 /* Any property - matches all chars */ +#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */ +#define PT_GC 2 /* Specified general characteristic (e.g. L) */ +#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */ +#define PT_SC 4 /* Script (e.g. Han) */ +#define PT_ALNUM 5 /* Alphanumeric - the union of L and N */ +#define PT_SPACE 6 /* Perl space - Z plus 9,10,12,13 */ +#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */ +#define PT_WORD 8 /* Word - L plus N plus underscore */ +#define PT_CLIST 9 /* Pseudo-property: match character list */ + +/* Flag bits and data types for the extended class (OP_XCLASS) for classes that +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 */ + +#define XCL_END 0 /* Marks end of individual items */ +#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */ +#define XCL_RANGE 2 /* A range (two multibyte chars) follows */ +#define XCL_PROP 3 /* Unicode property (2-byte property code follows) */ +#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ + +/* These are escaped items that aren't just an encoding of a particular data +value such as \n. They must have non-zero values, as check_escape() returns +0 for a data character. Also, they must appear in the same order as in the opcode +definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it +corresponds to "." in DOTALL mode rather than an escape sequence. It is also +used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In +non-DOTALL mode, "." behaves like \N. + +The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc. +when PCRE_UCP is set and replacement of \d etc by \p sequences is required. +They must be contiguous, and remain in order so that the replacements can be +looked up from a table. + +Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in +check_escape(). There are two tests in the code for an escape +greater than ESC_b and less than ESC_Z to detect the types that may be +repeated. These are the types that consume characters. If any new escapes are +put in between that don't consume a character, that code will have to change. +*/ + +enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, + ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H, + ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z, + ESC_E, ESC_Q, ESC_g, ESC_k, + ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu }; + +/* Opcode table: Starting from 1 (i.e. after OP_END), the values up to +OP_EOD must correspond in order to the list of escapes immediately above. + +*** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions +that follow must also be updated to match. There are also tables called +"coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */ + +enum { + OP_END, /* 0 End of pattern */ + + /* Values corresponding to backslashed metacharacters */ + + OP_SOD, /* 1 Start of data: \A */ + OP_SOM, /* 2 Start of match (subject + offset): \G */ + OP_SET_SOM, /* 3 Set start of match (\K) */ + OP_NOT_WORD_BOUNDARY, /* 4 \B */ + OP_WORD_BOUNDARY, /* 5 \b */ + OP_NOT_DIGIT, /* 6 \D */ + OP_DIGIT, /* 7 \d */ + OP_NOT_WHITESPACE, /* 8 \S */ + OP_WHITESPACE, /* 9 \s */ + OP_NOT_WORDCHAR, /* 10 \W */ + OP_WORDCHAR, /* 11 \w */ + + OP_ANY, /* 12 Match any character except newline (\N) */ + OP_ALLANY, /* 13 Match any character */ + OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */ + OP_NOTPROP, /* 15 \P (not Unicode property) */ + OP_PROP, /* 16 \p (Unicode property) */ + OP_ANYNL, /* 17 \R (any newline sequence) */ + OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */ + OP_HSPACE, /* 19 \h (horizontal whitespace) */ + OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */ + OP_VSPACE, /* 21 \v (vertical whitespace) */ + OP_EXTUNI, /* 22 \X (extended Unicode sequence */ + OP_EODN, /* 23 End of data or \n at end of data (\Z) */ + OP_EOD, /* 24 End of data (\z) */ + + OP_CIRC, /* 25 Start of line - not multiline */ + OP_CIRCM, /* 26 Start of line - multiline */ + OP_DOLL, /* 27 End of line - not multiline */ + OP_DOLLM, /* 28 End of line - multiline */ + 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 five must follow the previous five, in the same order. There's a + check for >= SBRA to distinguish the two sets. */ + + OP_SBRA, /* 130 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 131 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 132 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 133 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 134 Conditional group, check empty */ + + /* The next two pairs must (respectively) be kept together. */ + + OP_CREF, /* 135 Used to hold a capture number as condition */ + OP_NCREF, /* 136 Same, but generated by a name reference*/ + OP_RREF, /* 137 Used to hold a recursion number as condition */ + OP_NRREF, /* 138 Same, but generated by a name reference*/ + OP_DEF, /* 139 The DEFINE condition */ + + OP_BRAZERO, /* 140 These two must remain together and in this */ + OP_BRAMINZERO, /* 141 order. */ + OP_BRAPOSZERO, /* 142 */ + + /* These are backtracking control verbs */ + + OP_MARK, /* 143 always has an argument */ + OP_PRUNE, /* 144 */ + OP_PRUNE_ARG, /* 145 same, but with argument */ + OP_SKIP, /* 146 */ + OP_SKIP_ARG, /* 147 same, but with argument */ + OP_THEN, /* 148 */ + OP_THEN_ARG, /* 149 same, but with argument */ + OP_COMMIT, /* 150 */ + + /* These are forced failure and success verbs */ + + OP_FAIL, /* 151 */ + OP_ACCEPT, /* 152 */ + OP_ASSERT_ACCEPT, /* 153 Used inside assertions */ + OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */ + + /* This is used to skip a subpattern with a {0} quantifier */ + + 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 + some in the past. */ + + OP_TABLE_LENGTH +}; + +/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro +definitions that follow must also be updated to match. There are also tables +called "coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */ + + +/* This macro defines textual names for all the opcodes. These are used only +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", \ + "^", "^", "$", "$", "char", "chari", "not", "noti", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", "{", "{", \ + "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", "Braposzero", \ + "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ + "*THEN", "*THEN", "*COMMIT", "*FAIL", \ + "*ACCEPT", "*ASSERT_ACCEPT", \ + "Close", "Skip zero" + + +/* This macro defines the length of fixed length operations in the compiled +regex. The lengths are used when searching for specific things, and also in the +debugging printing of a compiled regex. We use a macro so that it can be +defined close to the definitions of the opcodes themselves. + +As things have been extended, some of these are no longer fixed lenths, but are +minima instead. For example, the length of a single-character repeat may vary +in UTF-8 mode. The code that uses this table must know about such things. */ + +#define OP_LENGTHS \ + 1, /* End */ \ + 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \ + 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \ + 1, 1, 1, /* Any, AllAny, Anybyte */ \ + 3, 3, /* \P, \p */ \ + 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \ + 1, /* \X */ \ + 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \ + 2, /* Char - the minimum length */ \ + 2, /* Chari - the minimum length */ \ + 2, /* not */ \ + 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 *, *?, +, +?, ?, ?? */ \ + 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 *, *?, +, +?, ?, ?? */ \ + 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, /* *, *?, +, +?, ?, ?? */ \ + 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 */ \ + 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, /* ONCE */ \ + 1+LINK_SIZE, /* ONCE_NC */ \ + 1+LINK_SIZE, /* BRA */ \ + 1+LINK_SIZE, /* BRAPOS */ \ + 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \ + 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \ + 1+LINK_SIZE, /* COND */ \ + 1+LINK_SIZE, /* SBRA */ \ + 1+LINK_SIZE, /* SBRAPOS */ \ + 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \ + 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \ + 1+LINK_SIZE, /* SCOND */ \ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \ + 1, /* DEF */ \ + 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \ + 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \ + 1, 3, /* SKIP, SKIP_ARG */ \ + 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. */ + +#define RREF_ANY 0xffff + +/* Compile time error code numbers. They are given names so that they can more +easily be tracked. When a new number is added, the table called eint in +pcreposix.c must be updated. */ + +enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, + ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, + ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, + 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, ERR69, + ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, 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 +offset to the name table so that if a regex is compiled on one host, saved, and +then run on another where the size of pointers is different, all might still +be well. For the case of compiled-on-4 and run-on-8, we include an extra +pointer that is always NULL. For future-proofing, a few dummy fields were +originally included - even though you can never get this planning right - but +there is only one left now. + +NOTE NOTE NOTE: +Because people can now save and re-use compiled patterns, any additions to this +structure should be made at the end, and something earlier (e.g. a new +flag in the options or one of the dummy fields) should indicate that the new +fields are present. Currently PCRE always sets the dummy fields to zero. +NOTE NOTE NOTE +*/ + +#if defined COMPILE_PCRE8 +#define REAL_PCRE real_pcre +#elif defined COMPILE_PCRE16 +#define REAL_PCRE real_pcre16 +#elif defined COMPILE_PCRE32 +#define REAL_PCRE real_pcre32 +#endif + +/* It is necessary to fork the struct for 32 bit, since it needs to use + * pcre_uchar for first_char and req_char. Can't put an ifdef inside the + * typedef since pcretest needs access to the struct of the 8-, 16- + * and 32-bit variants. */ + +typedef struct real_pcre8_or_16 { + pcre_uint32 magic_number; + pcre_uint32 size; /* Total that was malloced */ + pcre_uint32 options; /* Public options */ + pcre_uint16 flags; /* Private flags */ + pcre_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 pcre_uint8 *tables; /* Pointer to tables or NULL for std */ + const pcre_uint8 *nullpad; /* NULL padding */ +} real_pcre8_or_16; + +typedef struct real_pcre8_or_16 real_pcre; +typedef struct real_pcre8_or_16 real_pcre16; + +typedef struct real_pcre32 { + pcre_uint32 magic_number; + pcre_uint32 size; /* Total that was malloced */ + pcre_uint32 options; /* Public options */ + pcre_uint16 flags; /* Private flags */ + pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */ + pcre_uint16 top_bracket; /* Highest numbered group */ + pcre_uint16 top_backref; /* Highest numbered back reference */ + pcre_uint32 first_char; /* Starting character */ + pcre_uint32 req_char; /* This character must be seen */ + pcre_uint16 name_table_offset; /* Offset to name table that follows */ + pcre_uint16 name_entry_size; /* Size of any name items */ + pcre_uint16 name_count; /* Number of name items */ + pcre_uint16 ref_count; /* Reference count */ + pcre_uint16 dummy1; /* for later expansion */ + pcre_uint16 dummy2; /* for later expansion */ + const pcre_uint8 *tables; /* Pointer to tables or NULL for std */ + void *nullpad; /* for later expansion */ +} real_pcre32; + +/* Assert that the size of REAL_PCRE is divisible by 8 */ +typedef int __assert_real_pcre_size_divisible_8[(sizeof(REAL_PCRE) % 8) == 0 ? 1 : -1]; + +/* Needed in pcretest to access some fields in the real_pcre* structures + * directly. They're unified for 8/16/32 bits since the structs only differ + * after these fields; if that ever changes, need to fork those defines into + * 8/16 and 32 bit versions. */ +#define REAL_PCRE_MAGIC(re) (((REAL_PCRE*)re)->magic_number) +#define REAL_PCRE_SIZE(re) (((REAL_PCRE*)re)->size) +#define REAL_PCRE_OPTIONS(re) (((REAL_PCRE*)re)->options) +#define REAL_PCRE_FLAGS(re) (((REAL_PCRE*)re)->flags) + +/* The format of the block used to store data from pcre_study(). The same +remark (see NOTE above) about extending this structure applies. */ + +typedef struct pcre_study_data { + pcre_uint32 size; /* Total that was malloced */ + pcre_uint32 flags; /* Private flags */ + pcre_uint8 start_bits[32]; /* Starting char bits */ + pcre_uint32 minlength; /* Minimum subject length */ +} pcre_study_data; + +/* Structure for building a chain of open capturing subpatterns during +compiling, so that instructions to close them can be compiled when (*ACCEPT) is +encountered. This is also used to identify subpatterns that contain recursive +back references to themselves, so that they can be made atomic. */ + +typedef struct open_capitem { + struct open_capitem *next; /* Chain link */ + pcre_uint16 number; /* Capture number */ + pcre_uint16 flag; /* Set TRUE if recursive back ref */ +} open_capitem; + +/* Structure for passing "static" information around between the functions +doing the compiling, so that they are thread-safe. */ + +typedef struct compile_data { + 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 */ + unsigned int bracount; /* Count of capturing parens as we compile */ + int final_bracount; /* Saved value after first pass */ + int max_lookbehind; /* Maximum lookbehind (characters) */ + int top_backref; /* Maximum back reference */ + unsigned int backref_map; /* Bitmap of low back refs */ + 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 had_pruneorskip; /* (*PRUNE) or (*SKIP) 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 while compiling. */ + +typedef struct branch_chain { + struct branch_chain *outer; + pcre_uchar *current_branch; +} branch_chain; + +/* Structure for items in a linked list that represents an explicit recursive +call within the pattern; used by pcre_exec(). */ + +typedef struct recursion_info { + struct recursion_info *prevrec; /* Previous recursion record (or NULL) */ + unsigned int group_num; /* Number of group that was called */ + int *offset_save; /* Pointer to start of saved offsets */ + int saved_max; /* Number of saved offsets */ + 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; used by +pcre_exec(). */ + +typedef struct eptrblock { + struct eptrblock *epb_prev; + PCRE_PUCHAR epb_saved_eptr; +} eptrblock; + + +/* Structure for passing "static" information around between the functions +doing traditional NFA matching, so that they are thread-safe. */ + +typedef struct match_data { + unsigned long int match_call_count; /* As it says */ + unsigned long int match_limit; /* As it says */ + unsigned long int match_limit_recursion; /* As it says */ + int *offset_vector; /* Offset vector */ + int offset_end; /* One past the end */ + int offset_max; /* The maximum usable for return data */ + int nltype; /* Newline type */ + int nllen; /* Newline string length */ + int name_count; /* Number of names in name table */ + int name_entry_size; /* Size of entry in names table */ + 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 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. */ + +#define ctype_space 0x01 +#define ctype_letter 0x02 +#define ctype_digit 0x04 +#define ctype_xdigit 0x08 +#define ctype_word 0x10 /* alphanumeric or '_' */ +#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ + +/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set +of bits for a class map. Some classes are built by combining these tables. */ + +#define cbit_space 0 /* [:space:] or \s */ +#define cbit_xdigit 32 /* [:xdigit:] */ +#define cbit_digit 64 /* [:digit:] or \d */ +#define cbit_upper 96 /* [:upper:] */ +#define cbit_lower 128 /* [:lower:] */ +#define cbit_word 160 /* [:word:] or \w */ +#define cbit_graph 192 /* [:graph:] */ +#define cbit_print 224 /* [:print:] */ +#define cbit_punct 256 /* [:punct:] */ +#define cbit_cntrl 288 /* [:cntrl:] */ +#define cbit_length 320 /* Length of the cbits table */ + +/* Offsets of the various tables from the base tables pointer, and +total length. */ + +#define lcc_offset 0 +#define fcc_offset 256 +#define cbits_offset 512 +#define ctypes_offset (cbits_offset + cbit_length) +#define tables_length (ctypes_offset + 256) + +/* Internal function and data prefixes. */ + +#if defined COMPILE_PCRE8 +#ifndef PUBL +#define PUBL(name) pcre_##name +#endif +#ifndef PRIV +#define PRIV(name) _pcre_##name +#endif +#elif defined COMPILE_PCRE16 +#ifndef PUBL +#define PUBL(name) pcre16_##name +#endif +#ifndef PRIV +#define PRIV(name) _pcre16_##name +#endif +#elif defined COMPILE_PCRE32 +#ifndef PUBL +#define PUBL(name) pcre32_##name +#endif +#ifndef PRIV +#define PRIV(name) _pcre32_##name +#endif +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE[8|16|32] */ + +/* 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 +instead. */ + +typedef struct { + pcre_uint16 name_offset; + pcre_uint16 type; + pcre_uint16 value; +} ucp_type_table; + + +/* Internal shared data tables. These are tables 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. The data for these tables is in the +pcre_tables.c module. */ + +#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)[]; +#endif /* COMPILE_PCRE8 */ + +extern const char PRIV(utt_names)[]; +extern const ucp_type_table PRIV(utt)[]; +extern const int PRIV(utt_size); + +extern const pcre_uint8 PRIV(OP_lengths)[]; +extern const pcre_uint8 PRIV(default_tables)[]; + +extern const pcre_uint32 PRIV(hspace_list)[]; +extern const pcre_uint32 PRIV(vspace_list)[]; + + +/* 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. */ + +/* String comparison functions. */ +#if defined 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) + +#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + +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_PCRE[8|16|32] */ + +#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 + +#define STRCMP_UC_UC_TEST(str1, str2) STRCMP_UC_UC(str1, str2) +#define STRCMP_UC_C8_TEST(str1, str2) STRCMP_UC_C8(str1, str2) + +#elif defined COMPILE_PCRE32 + +extern int PRIV(strcmp_uc_uc_utf)(const pcre_uchar *, + const pcre_uchar *); +extern int PRIV(strcmp_uc_c8_utf)(const pcre_uchar *, + const char *); + +#define STRCMP_UC_UC_TEST(str1, str2) \ + (utf ? PRIV(strcmp_uc_uc_utf)((str1), (str2)) : PRIV(strcmp_uc_uc)((str1), (str2))) +#define STRCMP_UC_C8_TEST(str1, str2) \ + (utf ? PRIV(strcmp_uc_c8_utf)((str1), (str2)) : PRIV(strcmp_uc_c8)((str1), (str2))) + +#endif /* COMPILE_PCRE[8|16|32] */ + +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 unsigned 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)(pcre_uint32, const pcre_uchar *, BOOL); + +#ifdef SUPPORT_JIT +extern void PRIV(jit_compile)(const REAL_PCRE *, + PUBL(extra) *, int); +extern int PRIV(jit_exec)(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 { + pcre_uint8 script; /* ucp_Arabic, etc. */ + pcre_uint8 chartype; /* ucp_Cc, etc. (general categories) */ + pcre_uint8 gbprop; /* ucp_gbControl, etc. (grapheme break property) */ + pcre_uint8 caseset; /* offset to multichar other cases or zero */ + pcre_int32 other_case; /* offset to other case, or zero if none */ +} ucd_record; + +extern const pcre_uint32 PRIV(ucd_caseless_sets)[]; +extern const ucd_record PRIV(ucd_records)[]; +extern const pcre_uint8 PRIV(ucd_stage1)[]; +extern const pcre_uint16 PRIV(ucd_stage2)[]; +extern const pcre_uint32 PRIV(ucp_gentype)[]; +extern const pcre_uint32 PRIV(ucp_gbtable)[]; +#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) (PRIV(ucd_records) + \ + PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \ + UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE]) + +#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype +#define UCD_SCRIPT(ch) GET_UCD(ch)->script +#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)] +#define UCD_GRAPHBREAK(ch) GET_UCD(ch)->gbprop +#define UCD_CASESET(ch) GET_UCD(ch)->caseset +#define UCD_OTHERCASE(ch) ((pcre_uint32)((int)ch + (int)(GET_UCD(ch)->other_case))) + +#endif /* SUPPORT_UCP */ + +#endif + +/* End of pcre_internal.h */ diff --git a/tools/pcre/pcre_jit_compile.c b/tools/pcre/pcre_jit_compile.c new file mode 100644 index 00000000..cc9f0976 --- /dev/null +++ b/tools/pcre/pcre_jit_compile.c @@ -0,0 +1,8560 @@ +/************************************************* +* 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" + +#if defined 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 for the regex stack on the real machine stack. +Fast, but limited size. */ +#define MACHINE_STACK_SIZE 32768 + +/* Growth rate for stack allocated by the OS. Should be the multiply +of page size. */ +#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 matching 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 matching path. + + Greedy star operator (*) : + Matching path: match happens. + Backtrack path: match failed. + Non-greedy star operator (*?) : + Matching 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 matching path + '(' matching path (pushing arguments to the stack) + B matching path + ')' matching path (pushing arguments to the stack) + D matching 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 matching 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 matching 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 private data +when the backtrack mechanism performed. Because of OP_RECURSE, the data +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 private data 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; + pcre_uint32 top_bracket; + 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 *quit; + 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_matchingpath, and contains +the aguments for compile_backtrackingpath. 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 private_data_ptr; + /* For iterators. */ + struct sljit_label *matchingpath; +} assert_backtrack; + +typedef struct bracket_backtrack { + backtrack_common common; + /* Where to coninue if an alternative is successfully matched. */ + struct sljit_label *alternative_matchingpath; + /* For rmin and rmax iterators. */ + struct sljit_label *recursive_matchingpath; + /* For greedy ? operator. */ + struct sljit_label *zero_matchingpath; + /* 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 private_data_ptr; +} bracket_backtrack; + +typedef struct bracketpos_backtrack { + backtrack_common common; + /* Points to our private memory word on the stack. */ + int private_data_ptr; + /* Reverting stack is needed. */ + int framesize; + /* Allocated stack size. */ + int stacksize; +} bracketpos_backtrack; + +typedef struct braminzero_backtrack { + backtrack_common common; + struct sljit_label *matchingpath; +} braminzero_backtrack; + +typedef struct iterator_backtrack { + backtrack_common common; + /* Next iteration. */ + struct sljit_label *matchingpath; +} 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; + +#define MAX_RANGE_SIZE 6 + +typedef struct compiler_common { + struct sljit_compiler *compiler; + pcre_uchar *start; + + /* Maps private data offset to each opcode. */ + int *private_data_ptrs; + /* Tells whether the capturing bracket is optimized. */ + pcre_uint8 *optimized_cbracket; + /* Starting offset of private data for capturing brackets. */ + 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; + + /* Flipped and lower case tables. */ + const pcre_uint8 *fcc; + sljit_sw lcc; + /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */ + int mode; + /* Newline control. */ + int nltype; + int newline; + int bsr_nltype; + /* Dollar endonly. */ + int endonly; + BOOL has_set_som; + /* Tables. */ + sljit_sw ctypes; + int digits[2 + MAX_RANGE_SIZE]; + /* Named capturing brackets. */ + sljit_uw name_table; + sljit_sw name_count; + sljit_sw name_entry_size; + + /* Labels and jump lists. */ + struct sljit_label *partialmatchlabel; + struct sljit_label *quitlabel; + struct sljit_label *acceptlabel; + stub_list *stubs; + recurse_entry *entries; + recurse_entry *currententry; + jump_list *partialmatch; + jump_list *quit; + 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 +#ifndef COMPILE_PCRE32 + jump_list *utfreadchar; +#endif +#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_si asint; + sljit_uh asushort; +#if defined COMPILE_PCRE8 + sljit_ub asbyte; + sljit_ub asuchars[4]; +#elif defined COMPILE_PCRE16 + sljit_uh asuchars[2]; +#elif defined COMPILE_PCRE32 + sljit_ui asuchars[1]; +#endif + } c; + union { + sljit_si asint; + sljit_uh asushort; +#if defined COMPILE_PCRE8 + sljit_ub asbyte; + sljit_ub asuchars[4]; +#elif defined COMPILE_PCRE16 + sljit_uh asuchars[2]; +#elif defined COMPILE_PCRE32 + sljit_ui asuchars[1]; +#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_sw)) + +#define TMP1 SLJIT_SCRATCH_REG1 +#define TMP2 SLJIT_SCRATCH_REG3 +#define TMP3 SLJIT_TEMPORARY_EREG2 +#define STR_PTR SLJIT_SAVED_REG1 +#define STR_END SLJIT_SAVED_REG2 +#define STACK_TOP SLJIT_SCRATCH_REG2 +#define STACK_LIMIT SLJIT_SAVED_REG3 +#define ARGUMENTS SLJIT_SAVED_EREG1 +#define CALL_COUNT SLJIT_SAVED_EREG2 +#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 + +/* Local space layout. */ +/* These two locals can be used by the current opcode. */ +#define LOCALS0 (0 * sizeof(sljit_sw)) +#define LOCALS1 (1 * sizeof(sljit_sw)) +/* Two local variables for possessive quantifiers (char1 cannot use them). */ +#define POSSESSIVE0 (2 * sizeof(sljit_sw)) +#define POSSESSIVE1 (3 * sizeof(sljit_sw)) +/* Max limit of recursions. */ +#define CALL_LIMIT (4 * sizeof(sljit_sw)) +/* 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_sw)) +#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_sw)) +#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start]) + +#if defined COMPILE_PCRE8 +#define MOV_UCHAR SLJIT_MOV_UB +#define MOVU_UCHAR SLJIT_MOVU_UB +#elif defined COMPILE_PCRE16 +#define MOV_UCHAR SLJIT_MOV_UH +#define MOVU_UCHAR SLJIT_MOVU_UH +#elif defined COMPILE_PCRE32 +#define MOV_UCHAR SLJIT_MOV_UI +#define MOVU_UCHAR SLJIT_MOVU_UI +#else +#error Unsupported compiling mode +#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 OP_FLAGS(op, dst, dstw, src, srcw, type) \ + sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (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_private_data_length + set_private_data_ptrs + get_framesize + init_frame + get_private_data_length_for_copy + copy_private_data + compile_matchingpath + compile_backtrackingpath +*/ + +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; + } +} + +#define CASE_ITERATOR_PRIVATE_DATA_1 \ + case OP_MINSTAR: \ + case OP_MINPLUS: \ + case OP_QUERY: \ + case OP_MINQUERY: \ + case OP_MINSTARI: \ + case OP_MINPLUSI: \ + case OP_QUERYI: \ + case OP_MINQUERYI: \ + case OP_NOTMINSTAR: \ + case OP_NOTMINPLUS: \ + case OP_NOTQUERY: \ + case OP_NOTMINQUERY: \ + case OP_NOTMINSTARI: \ + case OP_NOTMINPLUSI: \ + case OP_NOTQUERYI: \ + case OP_NOTMINQUERYI: + +#define CASE_ITERATOR_PRIVATE_DATA_2A \ + case OP_STAR: \ + case OP_PLUS: \ + case OP_STARI: \ + case OP_PLUSI: \ + case OP_NOTSTAR: \ + case OP_NOTPLUS: \ + case OP_NOTSTARI: \ + case OP_NOTPLUSI: + +#define CASE_ITERATOR_PRIVATE_DATA_2B \ + case OP_UPTO: \ + case OP_MINUPTO: \ + case OP_UPTOI: \ + case OP_MINUPTOI: \ + case OP_NOTUPTO: \ + case OP_NOTMINUPTO: \ + case OP_NOTUPTOI: \ + case OP_NOTMINUPTOI: + +#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \ + case OP_TYPEMINSTAR: \ + case OP_TYPEMINPLUS: \ + case OP_TYPEQUERY: \ + case OP_TYPEMINQUERY: + +#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \ + case OP_TYPESTAR: \ + case OP_TYPEPLUS: + +#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \ + case OP_TYPEUPTO: \ + case OP_TYPEMINUPTO: + +static int get_class_iterator_size(pcre_uchar *cc) +{ +switch(*cc) + { + case OP_CRSTAR: + case OP_CRPLUS: + return 2; + + case OP_CRMINSTAR: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + return 1; + + case OP_CRRANGE: + case OP_CRMINRANGE: + if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE)) + return 0; + return 2; + + default: + return 0; + } +} + +static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) +{ +int private_data_length = 0; +pcre_uchar *alternative; +pcre_uchar *name; +pcre_uchar *end = NULL; +int space, size, i; +pcre_uint32 bracketlen; + +/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ +while (cc < ccend) + { + space = 0; + size = 0; + bracketlen = 0; + switch(*cc) + { + case OP_SET_SOM: + common->has_set_som = TRUE; + cc += 1; + break; + + case OP_REF: + case OP_REFI: + common->optimized_cbracket[GET2(cc, 1)] = 0; + cc += 1 + IMM2_SIZE; + 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: + private_data_length += sizeof(sljit_sw); + bracketlen = 1 + LINK_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + private_data_length += sizeof(sljit_sw); + common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; + bracketlen = 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_COND: + case OP_SCOND: + bracketlen = cc[1 + LINK_SIZE]; + if (bracketlen == OP_CREF) + { + bracketlen = GET2(cc, 1 + LINK_SIZE + 1); + common->optimized_cbracket[bracketlen] = 0; + } + else if (bracketlen == OP_NCREF) + { + bracketlen = GET2(cc, 1 + LINK_SIZE + 1); + name = (pcre_uchar *)common->name_table; + alternative = name; + for (i = 0; i < common->name_count; i++) + { + if (GET2(name, 0) == bracketlen) break; + name += common->name_entry_size; + } + SLJIT_ASSERT(i != common->name_count); + + for (i = 0; i < common->name_count; i++) + { + if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0) + common->optimized_cbracket[GET2(alternative, 0)] = 0; + alternative += common->name_entry_size; + } + } + + if (*cc == OP_COND) + { + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + private_data_length += sizeof(sljit_sw); + } + else + private_data_length += sizeof(sljit_sw); + bracketlen = 1 + LINK_SIZE; + break; + + case OP_BRA: + bracketlen = 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + bracketlen = 1 + LINK_SIZE + IMM2_SIZE; + break; + + CASE_ITERATOR_PRIVATE_DATA_1 + space = 1; + size = -2; + break; + + CASE_ITERATOR_PRIVATE_DATA_2A + space = 2; + size = -2; + break; + + CASE_ITERATOR_PRIVATE_DATA_2B + space = 2; + size = -(2 + IMM2_SIZE); + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_1 + space = 1; + size = 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2A + if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) + space = 2; + size = 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2B + if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) + space = 2; + size = 1 + IMM2_SIZE; + break; + + case OP_CLASS: + case OP_NCLASS: + size += 1 + 32 / sizeof(pcre_uchar); + space = get_class_iterator_size(cc + size); + break; + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + size = GET(cc, 1); + space = get_class_iterator_size(cc + size); + break; +#endif + + case OP_RECURSE: + /* Set its value only once. */ + if (common->recursive_head == 0) + { + common->recursive_head = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + cc += 1 + LINK_SIZE; + break; + + case OP_MARK: + if (common->mark_ptr == 0) + { + common->mark_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + cc += 1 + 2 + cc[1]; + break; + + default: + cc = next_opcode(common, cc); + if (cc == NULL) + return -1; + break; + } + + if (space > 0 && cc >= end) + private_data_length += sizeof(sljit_sw) * space; + + if (size != 0) + { + if (size < 0) + { + cc += -size; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + } + else + cc += size; + } + + if (bracketlen != 0) + { + if (cc >= end) + { + end = bracketend(cc); + if (end[-1 - LINK_SIZE] == OP_KET) + end = NULL; + } + cc += bracketlen; + } + } +return private_data_length; +} + +static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend) +{ +pcre_uchar *cc = common->start; +pcre_uchar *alternative; +pcre_uchar *end = NULL; +int space, size, bracketlen; + +while (cc < ccend) + { + space = 0; + size = 0; + bracketlen = 0; + 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->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw); + bracketlen = 1 + LINK_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw); + bracketlen = 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->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw); + } + bracketlen = 1 + LINK_SIZE; + break; + + case OP_BRA: + bracketlen = 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + bracketlen = 1 + LINK_SIZE + IMM2_SIZE; + break; + + CASE_ITERATOR_PRIVATE_DATA_1 + space = 1; + size = -2; + break; + + CASE_ITERATOR_PRIVATE_DATA_2A + space = 2; + size = -2; + break; + + CASE_ITERATOR_PRIVATE_DATA_2B + space = 2; + size = -(2 + IMM2_SIZE); + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_1 + space = 1; + size = 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2A + if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) + space = 2; + size = 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2B + if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) + space = 2; + size = 1 + IMM2_SIZE; + break; + + case OP_CLASS: + case OP_NCLASS: + size += 1 + 32 / sizeof(pcre_uchar); + space = get_class_iterator_size(cc + size); + break; + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + size = GET(cc, 1); + space = get_class_iterator_size(cc + size); + break; +#endif + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + + if (space > 0 && cc >= end) + { + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw) * space; + } + + if (size != 0) + { + if (size < 0) + { + cc += -size; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + } + else + cc += size; + } + + if (bracketlen > 0) + { + if (cc >= end) + { + end = bracketend(cc); + if (end[-1 - LINK_SIZE] == OP_KET) + end = NULL; + } + cc += bracketlen; + } + } +} + +/* 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_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + 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_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + 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_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + 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_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + 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_sw); + 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_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0); + stackpos += (int)sizeof(sljit_sw); + + 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_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) +{ +int private_data_length = 2; +int size; +pcre_uchar *alternative; +/* Calculate the sum of the private machine words. */ +while (cc < ccend) + { + size = 0; + 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: + private_data_length++; + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) + private_data_length++; + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + private_data_length += 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) + private_data_length++; + cc += 1 + LINK_SIZE; + break; + + CASE_ITERATOR_PRIVATE_DATA_1 + if (PRIVATE_DATA(cc)) + private_data_length++; + cc += 2; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_PRIVATE_DATA_2A + if (PRIVATE_DATA(cc)) + private_data_length += 2; + cc += 2; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_PRIVATE_DATA_2B + if (PRIVATE_DATA(cc)) + private_data_length += 2; + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_1 + if (PRIVATE_DATA(cc)) + private_data_length++; + cc += 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2A + if (PRIVATE_DATA(cc)) + private_data_length += 2; + cc += 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2B + if (PRIVATE_DATA(cc)) + private_data_length += 2; + cc += 1 + IMM2_SIZE; + break; + + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar); +#else + size = 1 + 32 / (int)sizeof(pcre_uchar); +#endif + if (PRIVATE_DATA(cc)) + private_data_length += get_class_iterator_size(cc + size); + cc += size; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + } +SLJIT_ASSERT(cc == ccend); +return private_data_length; +} + +static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, + BOOL save, int stackptr, int stacktop) +{ +DEFINE_COMPILER; +int srcw[2]; +int count, size; +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_sw); + if (stackptr < stacktop) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_sw); + tmp1empty = FALSE; + } + if (stackptr < stacktop) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_sw); + 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] = PRIVATE_DATA(cc); + SLJIT_ASSERT(srcw[0] != 0); + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) + { + 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[0] = PRIVATE_DATA(cc); + srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); + SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 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] = PRIVATE_DATA(cc); + SLJIT_ASSERT(srcw[0] != 0); + } + cc += 1 + LINK_SIZE; + break; + + CASE_ITERATOR_PRIVATE_DATA_1 + if (PRIVATE_DATA(cc)) + { + count = 1; + srcw[0] = PRIVATE_DATA(cc); + } + cc += 2; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_PRIVATE_DATA_2A + if (PRIVATE_DATA(cc)) + { + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw); + } + cc += 2; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_PRIVATE_DATA_2B + if (PRIVATE_DATA(cc)) + { + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw); + } + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_1 + if (PRIVATE_DATA(cc)) + { + count = 1; + srcw[0] = PRIVATE_DATA(cc); + } + cc += 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2A + if (PRIVATE_DATA(cc)) + { + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = srcw[0] + sizeof(sljit_sw); + } + cc += 1; + break; + + CASE_ITERATOR_TYPE_PRIVATE_DATA_2B + if (PRIVATE_DATA(cc)) + { + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = srcw[0] + sizeof(sljit_sw); + } + cc += 1 + IMM2_SIZE; + break; + + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar); +#else + size = 1 + 32 / (int)sizeof(pcre_uchar); +#endif + if (PRIVATE_DATA(cc)) + switch(get_class_iterator_size(cc + size)) + { + case 1: + count = 1; + srcw[0] = PRIVATE_DATA(cc); + break; + + case 2: + count = 2; + srcw[0] = PRIVATE_DATA(cc); + srcw[1] = srcw[0] + sizeof(sljit_sw); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + cc += 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_sw); + } + 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_sw); + } + 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_sw); + } + 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_sw); + } + tmp1next = TRUE; + } + } + } + } + +if (save) + { + if (tmp1next) + { + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_sw); + } + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_sw); + } + } + else + { + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_sw); + } + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_sw); + } + } + } +SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); +} + +#undef CASE_ITERATOR_PRIVATE_DATA_1 +#undef CASE_ITERATOR_PRIVATE_DATA_2A +#undef CASE_ITERATOR_PRIVATE_DATA_2B +#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1 +#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A +#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B + +static SLJIT_INLINE BOOL is_powerof2(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->quit = 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->quit); + 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_sw)); +#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_sw)); +} + +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_SCRATCH_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_SCRATCH_REG1, 0); + } +else + { + GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length); + loop = LABEL(); + OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_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_SCRATCH_REG1, 0, ARGUMENTS, 0); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); +OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0); +OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); +OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); +GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START); +/* Unlikely, but possible */ +earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0); +loop = LABEL(); +OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0); +OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw)); +/* Copy the integer value to the output buffer */ +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif +OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_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_SCRATCH_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1); + + /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */ + loop = LABEL(); + OP1(SLJIT_MOVU, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), -(2 * (sljit_sw)sizeof(sljit_sw))); + OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1); + CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop); + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_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 *quit) +{ +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_SCRATCH_REG2, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); +OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); +CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit); + +/* Store match begin and end. */ +OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); +OP1(SLJIT_MOV, SLJIT_SCRATCH_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); +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif +OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0); + +OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0); +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif +OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0); + +JUMPTO(SLJIT_JUMP, quit); +} + +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 (!is_powerof2(bit)) + return 0; + +#if defined 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; + +#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + +#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_PCRE[8|16|32] */ +} + +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; +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +struct sljit_jump *jump; +#endif + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +if (common->utf) + { +#if defined COMPILE_PCRE8 + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); +#elif defined COMPILE_PCRE16 + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); +#endif /* COMPILE_PCRE[8|16] */ + add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); + JUMPHERE(jump); + } +#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ +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; +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +struct sljit_jump *jump; +#endif + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +if (common->utf) + { +#if defined COMPILE_PCRE8 + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); +#elif defined COMPILE_PCRE16 + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); +#endif /* COMPILE_PCRE[8|16] */ + add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + JUMPHERE(jump); + } +#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ +} + +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 || defined COMPILE_PCRE32 +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)); +#if defined 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); +#elif defined 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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 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); +#elif defined COMPILE_PCRE32 + 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); +#endif /* COMPILE_PCRE[8|16|32] */ + return; + } +#endif /* SUPPORT_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)); +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +/* 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); +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +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_PCRE32 +#if 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; + } +#elif 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); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 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 /* COMPILE_PCRE[8|16] */ +#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ +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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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 + +#if defined 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_sw)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); +} + +#elif defined 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_PCRE[8|16] */ + +#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_sw)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_sw)PRIV(ucd_stage2)); +OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)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; +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +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, TMP3, 0, STR_PTR, 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); + JUMPHERE(end); + 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); + JUMPHERE(end); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0); + set_jumps(newline, LABEL()); + } + + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + } + +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); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); +#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_PCRE32 +#if 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_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(singlechar); + } +#elif 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); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 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 /* COMPILE_PCRE[8|16] */ +#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ +JUMPHERE(start); + +if (newlinecheck) + { + JUMPHERE(end); + JUMPHERE(nl); + } + +return mainloop; +} + +#define MAX_N_CHARS 3 + +static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit; +pcre_uint32 chars[MAX_N_CHARS * 2]; +pcre_uchar *cc = common->start + 1 + IMM2_SIZE; +int location = 0; +pcre_int32 len, c, bit, caseless; +int must_stop; + +/* We do not support alternatives now. */ +if (*(common->start + GET(common->start, 1)) == OP_ALT) + return FALSE; + +while (TRUE) + { + caseless = 0; + must_stop = 1; + switch(*cc) + { + case OP_CHAR: + must_stop = 0; + cc++; + break; + + case OP_CHARI: + caseless = 1; + must_stop = 0; + cc++; + break; + + case OP_SOD: + case OP_SOM: + case OP_SET_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + /* Zero width assertions. */ + cc++; + continue; + + case OP_PLUS: + case OP_MINPLUS: + case OP_POSPLUS: + cc++; + break; + + case OP_EXACT: + cc += 1 + IMM2_SIZE; + break; + + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + caseless = 1; + cc++; + break; + + case OP_EXACTI: + caseless = 1; + cc += 1 + IMM2_SIZE; + break; + + default: + must_stop = 2; + break; + } + + if (must_stop == 2) + break; + + len = 1; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]); +#endif + + if (caseless && char_has_othercase(common, cc)) + { + caseless = char_get_othercase_bit(common, cc); + if (caseless == 0) + return FALSE; +#ifdef COMPILE_PCRE8 + caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8)); +#else + if ((caseless & 0x100) != 0) + caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9)); + else + caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9)); +#endif + } + else + caseless = 0; + + while (len > 0 && location < MAX_N_CHARS * 2) + { + c = *cc; + bit = 0; + if (len == (caseless & 0xff)) + { + bit = caseless >> 8; + c |= bit; + } + + chars[location] = c; + chars[location + 1] = bit; + + len--; + location += 2; + cc++; + } + + if (location >= MAX_N_CHARS * 2 || must_stop != 0) + break; + } + +/* At least two characters are required. */ +if (location < 2 * 2) + return FALSE; + +if (firstline) + { + SLJIT_ASSERT(common->first_line_end != 0); + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1); + } +else + OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1); + +start = LABEL(); +quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +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)); +if (chars[1] != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]); +CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start); +if (location > 2 * 2) + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +if (chars[3] != 0) + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]); +CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start); +if (location > 2 * 2) + { + if (chars[5] != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start); + } +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +JUMPHERE(quit); + +if (firstline) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); +else + OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1); +return TRUE; +} + +#undef MAX_N_CHARS + +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 *quit; +struct sljit_jump *found; +pcre_uchar oc, bit; + +if (firstline) + { + SLJIT_ASSERT(common->first_line_end != 0); + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); + } + +start = LABEL(); +quit = 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 (is_powerof2(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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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)); +JUMPTO(SLJIT_JUMP, start); +JUMPHERE(found); +JUMPHERE(quit); + +if (firstline) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); +} + +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 *quit; +struct sljit_jump *foundcr = NULL; +struct sljit_jump *notfoundnl; +jump_list *newline = NULL; + +if (firstline) + { + SLJIT_ASSERT(common->first_line_end != 0); + OP1(SLJIT_MOV, TMP3, 0, 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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL); +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT); +#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)); + quit = 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(quit); + 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) + { + quit = 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); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(notfoundnl); + JUMPHERE(quit); + } +JUMPHERE(lastchar); +JUMPHERE(firstchar); + +if (firstline) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); +} + +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 *quit; +struct sljit_jump *found; +#ifndef COMPILE_PCRE8 +struct sljit_jump *jump; +#endif + +if (firstline) + { + SLJIT_ASSERT(common->first_line_end != 0); + OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); + } + +start = LABEL(); +quit = 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)); +#ifdef SUPPORT_UTF +#if 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_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#elif 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); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 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_PCRE[8|16] */ +#endif /* SUPPORT_UTF */ +JUMPTO(SLJIT_JUMP, start); +JUMPHERE(found); +JUMPHERE(quit); + +if (firstline) + OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0); +} + +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_uint32 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 (is_powerof2(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_sw)); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw)); +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_sw)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); +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_sw)); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); + 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_sw)); +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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 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); + OP_FLAGS(SLJIT_OR, TMP2, 0, 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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 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); + OP_FLAGS(SLJIT_OR, TMP2, 0, 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); +} + +/* + range format: + + ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range). + ranges[1] = first bit (0 or 1) + ranges[2-length] = position of the bit change (when the current bit is not equal to the previous) +*/ + +static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; + +if (ranges[0] < 0) + return FALSE; + +switch(ranges[0]) + { + case 1: + if (readch) + read_char(common); + add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); + return TRUE; + + case 2: + if (readch) + read_char(common); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]); + add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); + return TRUE; + + case 4: + if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5]) + { + if (readch) + read_char(common); + if (ranges[1] != 0) + { + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4])); + } + else + { + jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4])); + JUMPHERE(jump); + } + return TRUE; + } + if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2])) + { + if (readch) + read_char(common); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]); + add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4])); + return TRUE; + } + return FALSE; + + default: + return FALSE; + } +} + +static void get_ctype_ranges(compiler_common *common, int flag, int *ranges) +{ +int i, bit, length; +const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes; + +bit = ctypes[0] & flag; +ranges[0] = -1; +ranges[1] = bit != 0 ? 1 : 0; +length = 0; + +for (i = 1; i < 256; i++) + if ((ctypes[i] & flag) != bit) + { + if (length >= MAX_RANGE_SIZE) + return; + ranges[2 + length] = i; + length++; + bit ^= flag; + } + +if (bit != 0) + { + if (length >= MAX_RANGE_SIZE) + return; + ranges[2 + length] = 256; + length++; + } +ranges[0] = length; +} + +static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks) +{ +int ranges[2 + MAX_RANGE_SIZE]; +pcre_uint8 bit, cbit, all; +int i, byte, length = 0; + +bit = bits[0] & 0x1; +ranges[1] = bit; +/* Can be 0 or 255. */ +all = -bit; + +for (i = 0; i < 256; ) + { + byte = i >> 3; + if ((i & 0x7) == 0 && bits[byte] == all) + i += 8; + else + { + cbit = (bits[byte] >> (i & 0x7)) & 0x1; + if (cbit != bit) + { + if (length >= MAX_RANGE_SIZE) + return FALSE; + ranges[2 + length] = i; + length++; + bit = cbit; + all = -cbit; + } + i++; + } + } + +if (((bit == 0) && nclass) || ((bit == 1) && !nclass)) + { + if (length >= MAX_RANGE_SIZE) + return FALSE; + ranges[2 + length] = 256; + length++; + } +ranges[0] = length; + +return check_ranges(common, ranges, backtracks, FALSE); +} + +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); +OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 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 || defined COMPILE_PCRE32 +#ifdef COMPILE_PCRE8 +if (common->utf) + { +#endif + OP_FLAGS(SLJIT_OR, TMP2, 0, 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 || COMPILE_PCRE32 */ +OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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); +OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); +OP_FLAGS(SLJIT_OR, TMP2, 0, 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 || defined COMPILE_PCRE32 +#ifdef COMPILE_PCRE8 +if (common->utf) + { +#endif + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); + OP_FLAGS(SLJIT_OR, TMP2, 0, 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); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); + OP_FLAGS(SLJIT_OR, TMP2, 0, 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 || COMPILE_PCRE32 */ +OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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); +OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 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 || defined COMPILE_PCRE32 +#ifdef COMPILE_PCRE8 +if (common->utf) + { +#endif + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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 || COMPILE_PCRE32 */ +OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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. */ +pcre_uint32 c1, c2; +const pcre_uchar *src2 = args->uchar_ptr; +const pcre_uchar *end2 = args->end; +const ucd_record *ur; +const pcre_uint32 *pp; + +while (src1 < end1) + { + if (src2 >= end2) + return (pcre_uchar*)1; + GETCHARINC(c1, src1); + GETCHARINC(c2, src2); + ur = GET_UCD(c2); + if (c1 != c2 && c1 != c2 + ur->other_case) + { + pp = PRIV(ucd_caseless_sets) + ur->caseset; + for (;;) + { + if (c1 < *pp) return NULL; + if (c1 == *pp++) break; + } + } + } +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. */ +#if defined COMPILE_PCRE8 + othercasechar = cc + (othercasebit >> 8); + othercasebit &= 0xff; +#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + /* Note that this code only handles characters in the BMP. If there + ever are characters outside the BMP whose othercase differs in only one + bit from itself (there currently are none), this code will need to be + revised for COMPILE_PCRE32. */ + othercasechar = cc + (othercasebit >> 9); + if ((othercasebit & 0x100) != 0) + othercasebit = (othercasebit & 0xff) << 8; + else + othercasebit &= 0xff; +#endif /* COMPILE_PCRE[8|16|32] */ + } + +if (context->sourcereg == -1) + { +#if defined 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); +#elif defined 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(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#elif defined COMPILE_PCRE32 + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif /* COMPILE_PCRE[8|16|32] */ + 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++; + +#if defined COMPILE_PCRE8 + if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) +#elif defined COMPILE_PCRE16 + if (context->ucharptr >= 2 || context->length == 0) +#elif defined COMPILE_PCRE32 + if (1 /* context->ucharptr >= 1 || context->length == 0 */) +#endif + { +#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 + if (context->length >= 4) + OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#if defined 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); +#elif defined COMPILE_PCRE16 + else if (context->length >= 2) + OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif /* COMPILE_PCRE[8|16] */ +#elif defined COMPILE_PCRE32 + OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif /* COMPILE_PCRE[8|16|32] */ + 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; + +#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 + 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 + +#endif /* COMPILE_PCRE[8|16] */ + + default: + SLJIT_ASSERT_STOP(); + break; + } + context->ucharptr = 0; + } + +#else + + /* Unaligned read is unsupported. */ + if (context->length > 0) + OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + + 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_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +jump_list *found = NULL; +jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks; +pcre_int32 c, charoffset; +const pcre_uint32 *other_cases; +struct sljit_jump *jump = NULL; +pcre_uchar *ccbegin; +int compares, invertcmp, numberofcmps; +#ifdef SUPPORT_UCP +BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; +BOOL charsaved = FALSE; +int typereg = TMP1, scriptreg = TMP1; +pcre_int32 typeoffset; +#endif + +/* Although SUPPORT_UTF must be defined, we are + not necessary in utf mode even in 8 bit 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 + + if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list)) + { + 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_sw)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; + + case PT_CLIST: + 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_sw)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_sw)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); + OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : 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); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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); + OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : 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); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 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); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 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); + OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : 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); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + break; + + case PT_CLIST: + other_cases = PRIV(ucd_caseless_sets) + cc[1]; + + /* At least three characters are required. + Otherwise this case would be handled by the normal code path. */ + SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR); + SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]); + + /* Optimizing character pairs, if their difference is power of 2. */ + if (is_powerof2(other_cases[1] ^ other_cases[0])) + { + if (charoffset == 0) + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); + else + { + OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); + } + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + other_cases += 2; + } + else if (is_powerof2(other_cases[2] ^ other_cases[1])) + { + if (charoffset == 0) + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]); + else + { + OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); + } + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset); + OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + + other_cases += 3; + } + else + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + } + + while (*other_cases != NOTACHAR) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset); + OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_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_matchingpath(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: + /* Digits are usually 0-9, so it is worth to optimize them. */ + if (common->digits[0] == -2) + get_ctype_ranges(common, ctype_digit, common->digits); + detect_partial_match(common, backtracks); + /* Flip the starting bit in the negative case. */ + if (type == OP_NOT_DIGIT) + common->digits[1] ^= 1; + if (!check_ranges(common, common->digits, backtracks, TRUE)) + { + 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)); + } + if (type == OP_NOT_DIGIT) + common->digits[1] ^= 1; + 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)); +#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 +#if defined COMPILE_PCRE8 + jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +#elif defined 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); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 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 + JUMPHERE(jump[0]); +#endif /* COMPILE_PCRE[8|16] */ + 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_matchingpath(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)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); + /* Optimize register allocation: use a real register. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); + OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); + + 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)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3); + + OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2); + OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable)); + OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + JUMPTO(SLJIT_C_NOT_ZERO, label); + + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + JUMPHERE(jump[0]); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); + + 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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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_matchingpath(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 (is_powerof2(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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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_sw)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 (is_powerof2(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 (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks)) + return cc + 32 / sizeof(pcre_uchar); + +#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_sw)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 || defined COMPILE_PCRE32 + case OP_XCLASS: + compile_xclass_matchingpath(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_matchingpath(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_matchingpath(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)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *); +static void compile_backtrackingpath(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_matchingpath(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_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_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_SCRATCH_REG2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_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_matchingpath(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_sw)); + 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_sw)); + } + 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_matchingpath(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)->matchingpath = 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)->matchingpath = 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_matchingpath(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)->matchingpath); + } +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_matchingpath(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_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) +{ +DEFINE_COMPILER; +int framesize; +int private_data_ptr; +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_quitlabel = common->quitlabel; +struct sljit_label *save_acceptlabel = common->acceptlabel; +jump_list *save_quit = common->quit; +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++; + } +private_data_ptr = PRIVATE_DATA(cc); +SLJIT_ASSERT(private_data_ptr != 0); +framesize = get_framesize(common, cc, FALSE); +backtrack->framesize = framesize; +backtrack->private_data_ptr = private_data_ptr; +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), private_data_ptr, 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), private_data_ptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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->quitlabel = NULL; +common->quit = 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_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + common->quitlabel = save_quitlabel; + common->acceptlabel = save_acceptlabel; + common->quit = save_quit; + 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), private_data_ptr); + else { + if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional) + { + /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); + } + else + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + 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_sw)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); + } + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + 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), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); + } + } + add_jump(compiler, found, JUMP(SLJIT_JUMP)); + + compile_backtrackingpath(common, altbacktrack.top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + common->quitlabel = save_quitlabel; + common->acceptlabel = save_acceptlabel; + common->quit = save_quit; + 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->quit != NULL) + set_jumps(common->quit, 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), private_data_ptr, 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_sw)); + else if (bra == OP_BRAMINZERO) + { + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + 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 private_data_ptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + } + else + { + /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw)); + 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->matchingpath = LABEL(); + sljit_set_label(jump, backtrack->matchingpath); + } + else if (bra == OP_BRAMINZERO) + { + JUMPTO(SLJIT_JUMP, backtrack->matchingpath); + JUMPHERE(brajump); + if (framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); + } + 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), private_data_ptr, TMP1, 0); + } + + if (bra == OP_BRAZERO) + backtrack->matchingpath = LABEL(); + else if (bra == OP_BRAMINZERO) + { + JUMPTO(SLJIT_JUMP, backtrack->matchingpath); + JUMPHERE(brajump); + } + + if (bra != OP_BRA) + { + SLJIT_ASSERT(found == &backtrack->common.topbacktracks); + set_jumps(backtrack->common.topbacktracks, LABEL()); + backtrack->common.topbacktracks = NULL; + } + } + +common->quitlabel = save_quitlabel; +common->acceptlabel = save_acceptlabel; +common->quit = save_quit; +common->accept = save_accept; +return cc + 1 + LINK_SIZE; +} + +static sljit_sw SLJIT_CALL do_searchovector(sljit_uw refno, sljit_sw* locals, pcre_uchar *name_table) +{ +int condition = FALSE; +pcre_uchar *slotA = name_table; +pcre_uchar *slotB; +sljit_sw name_count = locals[LOCALS0 / sizeof(sljit_sw)]; +sljit_sw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)]; +sljit_sw 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_sw SLJIT_CALL do_searchgroups(sljit_uw recno, sljit_uw* locals, pcre_uchar *name_table) +{ +int condition = FALSE; +pcre_uchar *slotA = name_table; +pcre_uchar *slotB; +sljit_uw name_count = locals[LOCALS0 / sizeof(sljit_sw)]; +sljit_uw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)]; +sljit_uw group_num = locals[POSSESSIVE0 / sizeof(sljit_sw)]; +sljit_uw 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_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +pcre_uchar opcode; +int private_data_ptr = 0; +int offset = 0; +int stacksize; +pcre_uchar *ccbegin; +pcre_uchar *matchingpath; +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; +matchingpath = 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 = (*matchingpath == OP_RREF) ? FALSE : TRUE; + if (*matchingpath == OP_NRREF) + { + stacksize = GET2(matchingpath, 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 != (int)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); + if (common->optimized_cbracket[offset] == 0) + { + private_data_ptr = OVECTOR_PRIV(offset); + offset <<= 1; + } + else + { + offset <<= 1; + private_data_ptr = OVECTOR(offset); + } + BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; + matchingpath += IMM2_SIZE; + } +else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) + { + /* Other brackets simply allocate the next entry. */ + private_data_ptr = PRIVATE_DATA(ccbegin); + SLJIT_ASSERT(private_data_ptr != 0); + BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; + 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, private_data_ptr contains the previous STR_PTR. */ + braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + } + else + { + /* Except when the whole stack frame must be saved. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); + } + 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)->recursive_matchingpath = LABEL(); + +if (ket == OP_KETRMAX) + { + rmaxlabel = LABEL(); + if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA) + BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = 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), private_data_ptr); + 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), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + } + else if (ket == OP_KETRMAX || has_alternatives) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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), private_data_ptr, 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), private_data_ptr); + 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), private_data_ptr, 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), private_data_ptr); + 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), private_data_ptr, 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. */ + if (common->optimized_cbracket[offset >> 1] == 0) + { + 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, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); + } + else + { + SLJIT_ASSERT(private_data_ptr == OVECTOR(offset)); + allocate_stack(common, 2); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + } + } +else if (opcode == OP_SBRA || opcode == OP_SCOND) + { + /* Saving the previous value. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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 (*matchingpath == 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(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); + matchingpath += 1 + IMM2_SIZE; + } + else if (*matchingpath == OP_NCREF) + { + SLJIT_ASSERT(has_alternatives); + stacksize = GET2(matchingpath, 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_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw))); + GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0); + OP1(SLJIT_MOV, SLJIT_SCRATCH_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_SCRATCH_REG1, 0, SLJIT_IMM, 0)); + + JUMPHERE(jump); + matchingpath += 1 + IMM2_SIZE; + } + else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF) + { + /* Never has other case. */ + BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; + + stacksize = GET2(matchingpath, 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 == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + + if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL) + { + SLJIT_ASSERT(!has_alternatives); + if (stacksize != 0) + matchingpath += 1 + IMM2_SIZE; + else + { + if (*cc == OP_ALT) + { + matchingpath = cc + 1 + LINK_SIZE; + cc += GET(cc, 1); + } + else + matchingpath = cc; + } + } + else + { + SLJIT_ASSERT(has_alternatives); + + stacksize = GET2(matchingpath, 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_SCRATCH_REG1, 0, SLJIT_IMM, stacksize); + GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0); + OP1(SLJIT_MOV, SLJIT_SCRATCH_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_SCRATCH_REG1, 0, SLJIT_IMM, 0)); + matchingpath += 1 + IMM2_SIZE; + } + } + else + { + SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= 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 = matchingpath; + BACKTRACK_AS(bracket_backtrack)->u.assert = assert; + matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE); + } + } + +compile_matchingpath(common, matchingpath, 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), private_data_ptr); + /* 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 private_data_ptr. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_sw)); + 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)->alternative_matchingpath = LABEL(); + } + +/* Must be after the matchingpath label. */ +if (offset != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + 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)->alternative_matchingpath = LABEL(); + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE) + { + CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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)->recursive_matchingpath = LABEL(); + } + +if (bra == OP_BRAZERO) + BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL(); + +if (bra == OP_BRAMINZERO) + { + /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ + JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath); + 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), private_data_ptr); + 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_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +pcre_uchar opcode; +int private_data_ptr; +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; +private_data_ptr = PRIVATE_DATA(cc); +SLJIT_ASSERT(private_data_ptr != 0); +BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr; +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); + /* This case cannot be optimized in the same was as + normal capturing brackets. */ + SLJIT_ASSERT(common->optimized_cbracket[offset] == 0); + 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), private_data_ptr, 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), private_data_ptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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_matchingpath(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), private_data_ptr); + + 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), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw)); + 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), private_data_ptr); + OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw)); + if (opcode == OP_SBRAPOS) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), 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_backtrackingpath(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), private_data_ptr); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw)); + } + } + + 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 [private_data_ptr] above. */ + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), 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_matchingpath(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; +int private_data_ptr = PRIVATE_DATA(cc); +int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG); +int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; +int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); +int tmp_base, tmp_offset; + +PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); + +cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end); + +switch (type) + { + 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_ANYNL: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_CLASS: + case OP_NCLASS: + tmp_base = TMP3; + tmp_offset = 0; + break; + + default: + SLJIT_ASSERT_STOP(); + /* Fall through. */ + + case OP_EXTUNI: + case OP_XCLASS: + case OP_NOTPROP: + case OP_PROP: + tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG); + tmp_offset = POSSESSIVE0; + break; + } + +switch(opcode) + { + case OP_STAR: + case OP_PLUS: + case OP_UPTO: + case OP_CRRANGE: + if (type == OP_ANYNL || type == OP_EXTUNI) + { + SLJIT_ASSERT(private_data_ptr == 0); + 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_matchingpath(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); + } + + /* We cannot use TMP3 because of this allocate_stack. */ + 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_matchingpath(common, type, cc, &backtrack->topbacktracks); + if (private_data_ptr == 0) + allocate_stack(common, 2); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (opcode <= OP_PLUS) + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + else + OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (opcode <= OP_PLUS) + JUMPTO(SLJIT_JUMP, label); + else if (opcode == OP_CRRANGE && arg1 == 0) + { + OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1); + JUMPTO(SLJIT_JUMP, label); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, base, offset1); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, base, offset1, 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, base, offset1, SLJIT_IMM, arg2 + 1)); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + } + BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + break; + + case OP_MINSTAR: + case OP_MINPLUS: + if (opcode == OP_MINPLUS) + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); + if (private_data_ptr == 0) + allocate_stack(common, 1); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + break; + + case OP_MINUPTO: + case OP_CRMINRANGE: + if (private_data_ptr == 0) + allocate_stack(common, 2); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1); + if (opcode == OP_CRMINRANGE) + add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); + BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + break; + + case OP_QUERY: + case OP_MINQUERY: + if (private_data_ptr == 0) + allocate_stack(common, 1); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (opcode == OP_QUERY) + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); + BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + break; + + case OP_EXACT: + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, label); + break; + + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSUPTO: + if (opcode == OP_POSPLUS) + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); + if (opcode == OP_POSUPTO) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + if (opcode != OP_POSUPTO) + JUMPTO(SLJIT_JUMP, label); + else + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, label); + } + set_jumps(nomatch, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); + break; + + case OP_POSQUERY: + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + compile_char1_matchingpath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + set_jumps(nomatch, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + +decrease_call_count(common); +return end; +} + +static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(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_matchingpath(compiler_common *common, pcre_uchar *cc) +{ +DEFINE_COMPILER; +int offset = GET2(cc, 1); +BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0; + +/* Data will be discarded anyway... */ +if (common->currententry != NULL) + return cc + 1 + IMM2_SIZE; + +if (!optimized_cbracket) + 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); +if (!optimized_cbracket) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); +return cc + 1 + IMM2_SIZE; +} + +static void compile_matchingpath(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_matchingpath(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_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + else + cc = compile_char1_matchingpath(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_matchingpath(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_matchingpath(common, cc, parent); + else + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + break; + +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + case OP_XCLASS: + if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE) + cc = compile_iterator_matchingpath(common, cc, parent); + else + cc = compile_char1_matchingpath(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_matchingpath(common, cc, parent); + else + cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + break; + + case OP_RECURSE: + cc = compile_recurse_matchingpath(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_matchingpath(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)->matchingpath = 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_matchingpath(common, cc, parent); + break; + + case OP_BRAZERO: + if (cc[1] > OP_ASSERTBACK_NOT) + cc = compile_bracket_matchingpath(common, cc, parent); + else + { + PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); + cc = compile_assert_matchingpath(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_matchingpath(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_sw)(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_matchingpath(common, cc, parent); + break; + + case OP_CLOSE: + cc = compile_close_matchingpath(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_BACKTRACKINGPATH(current) \ + do \ + { \ + compile_backtrackingpath(common, (current)); \ + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ + return; \ + } \ + while (0) + +#define CURRENT_AS(type) ((type *)current) + +static void compile_iterator_backtrackingpath(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; +int private_data_ptr = PRIVATE_DATA(cc); +int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG); +int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; +int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); + +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) + { + SLJIT_ASSERT(private_data_ptr == 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)->matchingpath); + } + else + { + if (opcode == OP_UPTO) + arg2 = 0; + if (opcode <= OP_PLUS) + { + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + jump = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, base, offset1); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, base, offset1); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1); + OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1); + } + skip_char_back(common); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + if (opcode == OP_CRRANGE) + set_jumps(current->topbacktracks, LABEL()); + JUMPHERE(jump); + if (private_data_ptr == 0) + 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, base, offset0); + compile_char1_matchingpath(common, type, cc, &jumplist); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + set_jumps(jumplist, LABEL()); + if (private_data_ptr == 0) + 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, base, offset0); + compile_char1_matchingpath(common, type, cc, &jumplist); + + OP1(SLJIT_MOV, TMP1, 0, base, offset1); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, base, offset1, 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)->matchingpath); + else + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath); + + set_jumps(jumplist, LABEL()); + if (private_data_ptr == 0) + free_stack(common, 2); + break; + + case OP_QUERY: + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); + jump = JUMP(SLJIT_JUMP); + set_jumps(current->topbacktracks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + JUMPHERE(jump); + if (private_data_ptr == 0) + free_stack(common, 1); + break; + + case OP_MINQUERY: + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + compile_char1_matchingpath(common, type, cc, &jumplist); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + set_jumps(jumplist, LABEL()); + JUMPHERE(jump); + if (private_data_ptr == 0) + 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_backtrackingpath(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)->matchingpath); + 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)->matchingpath); +set_jumps(current->topbacktracks, LABEL()); +free_stack(common, 2); +} + +static void compile_recurse_backtrackingpath(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_backtrackingpath(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)->matchingpath); + 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)->matchingpath); + 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)->private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_sw)); + + 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_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath); + JUMPHERE(brajump); + } +} + +static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +int opcode; +int offset = 0; +int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr; +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), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + } + if (opcode != OP_ONCE) + free_stack(common, 1); + } + else + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + } + 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), private_data_ptr); + 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_BACKTRACKINGPATH(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->private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw)); + } + 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 (private_data_ptr != 0 && opcode != OP_ONCE) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + compile_matchingpath(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_matchingpath. */ + if (opcode == OP_ONCE) + { + if (CURRENT_AS(bracket_backtrack)->u.framesize < 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + /* 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 private_data_ptr. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); + } + } + else + { + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_sw)); + 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_sw)); + } + } + + 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), private_data_ptr); + 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)->alternative_matchingpath); + + if (opcode != OP_ONCE) + { + SLJIT_ASSERT(jumplist); + JUMPHERE(jumplist->jump); + jumplist = jumplist->next; + } + + COMPILE_BACKTRACKINGPATH(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->private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw)); + } + JUMPHERE(cond); + } + + /* Free the STR_PTR. */ + if (private_data_ptr == 0) + free_stack(common, 1); + } + +if (offset != 0) + { + /* Using both tmp register is better for instruction scheduling. */ + if (common->optimized_cbracket[offset >> 1] == 0) + { + 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, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); + free_stack(common, 3); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + free_stack(common, 2); + 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); + } + } +else if (opcode == OP_SBRA || opcode == OP_SCOND) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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 private_data_ptr */ + if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_sw)); + 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), private_data_ptr, 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)->recursive_matchingpath); + if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath); + 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)->zero_matchingpath); + JUMPHERE(brazero); + } +} + +static void compile_bracketpos_backtrackingpath(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)->private_data_ptr); +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)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw)); +} + +static void compile_braminzero_backtrackingpath(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_matchingpath and compile_bracket_backtrackingpath. */ + compile_bracket_matchingpath(common, current->cc, current); + compile_bracket_backtrackingpath(common, current->top); + } +else + { + memset(&backtrack, 0, sizeof(backtrack)); + backtrack.common.cc = current->cc; + backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath; + /* Manual call of compile_assert_matchingpath. */ + compile_assert_matchingpath(common, current->cc, &backtrack, FALSE); + } +SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); +} + +static void compile_backtrackingpath(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_backtrackingpath(common, current); + break; + + case OP_REF: + case OP_REFI: + compile_ref_iterator_backtrackingpath(common, current); + break; + + case OP_RECURSE: + compile_recurse_backtrackingpath(common, current); + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + compile_assert_backtrackingpath(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_backtrackingpath(common, current); + break; + + case OP_BRAZERO: + if (current->cc[1] > OP_ASSERTBACK_NOT) + compile_bracket_backtrackingpath(common, current); + else + compile_assert_backtrackingpath(common, current); + break; + + case OP_BRAPOS: + case OP_CBRAPOS: + case OP_SBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOSZERO: + compile_bracketpos_backtrackingpath(common, current); + break; + + case OP_BRAMINZERO: + compile_braminzero_backtrackingpath(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->quitlabel == NULL) + add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); + else + JUMPTO(SLJIT_JUMP, common->quitlabel); + 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 private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend); +int framesize = get_framesize(common, cc, TRUE); +int alternativesize; +BOOL needsframe; +backtrack_common altbacktrack; +struct sljit_label *save_quitlabel = common->quitlabel; +jump_list *save_quit = common->quit; +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, private_data_size + framesize + alternativesize); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0); +copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + 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->quitlabel = NULL; +common->acceptlabel = NULL; +common->quit = 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_matchingpath(common, altbacktrack.cc, cc, &altbacktrack); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + common->quitlabel = save_quitlabel; + common->quit = save_quit; + return; + } + + add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); + + compile_backtrackingpath(common, altbacktrack.top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + common->quitlabel = save_quitlabel; + common->quit = save_quit; + 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->quit != NULL) + set_jumps(common->quit, 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_sw)); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); + } +OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); + +JUMPHERE(jump); +copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize); +free_stack(common, private_data_size + framesize + alternativesize); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); +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->quitlabel = save_quitlabel; +common->quit = save_quit; +} + +#undef COMPILE_BACKTRACKINGPATH +#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 private_data_size; +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_sw)(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_sw)(tables + ctypes_offset); +common->digits[0] = -2; +common->name_table = (sljit_sw)((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_UTF[16|32] have 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_sw); +common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1); +if (!common->optimized_cbracket) + return; +memset(common->optimized_cbracket, 1, re->top_bracket + 1); + +SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); +private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend); +if (private_data_size < 0) + { + SLJIT_FREE(common->optimized_cbracket); + 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_sw); + } +if (mode != JIT_COMPILE) + { + common->start_used_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + if (mode == JIT_PARTIAL_SOFT_COMPILE) + { + common->hit_start = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + } +if ((re->options & PCRE_FIRSTLINE) != 0) + { + common->first_line_end = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + +/* Aligning ovector to even number of sljit words. */ +if ((common->ovector_start & sizeof(sljit_sw)) != 0) + common->ovector_start += sizeof(sljit_sw); + +SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); +common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); +private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw); +if (private_data_size > SLJIT_MAX_LOCAL_SIZE) + { + SLJIT_FREE(common->optimized_cbracket); + return; + } +common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); +if (!common->private_data_ptrs) + { + SLJIT_FREE(common->optimized_cbracket); + return; + } +memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); +set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend); + +compiler = sljit_create_compiler(); +if (!compiler) + { + SLJIT_FREE(common->optimized_cbracket); + SLJIT_FREE(common->private_data_ptrs); + return; + } +common->compiler = compiler; + +/* Main pcre_jit_exec entry. */ +sljit_emit_enter(compiler, 1, 5, 5, private_data_size); + +/* 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_SCRATCH_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 (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0)) + { /* Do nothing */ } + else 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_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->optimized_cbracket); + SLJIT_FREE(common->private_data_ptrs); + 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->quitlabel = LABEL(); +if (common->quit != NULL) + set_jumps(common->quit, common->quitlabel); +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->quitlabel); + } + +empty_match_backtrack = LABEL(); +compile_backtrackingpath(common, rootbacktrack.top); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->optimized_cbracket); + SLJIT_FREE(common->private_data_ptrs); + 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); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 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); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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->quitlabel); + +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->optimized_cbracket); + SLJIT_FREE(common->private_data_ptrs); + 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->quitlabel); + +/* Call limit reached. */ +set_jumps(common->calllimit, LABEL()); +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); +JUMPTO(SLJIT_JUMP, common->quitlabel); + +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 +#ifndef COMPILE_PCRE32 +if (common->utfreadchar != NULL) + { + set_jumps(common->utfreadchar, LABEL()); + do_utfreadchar(common); + } +#endif /* !COMPILE_PCRE32 */ +#ifdef COMPILE_PCRE8 +if (common->utfreadtype8 != NULL) + { + set_jumps(common->utfreadtype8, LABEL()); + do_utfreadtype8(common); + } +#endif /* COMPILE_PCRE8 */ +#endif /* SUPPORT_UTF */ +#ifdef SUPPORT_UCP +if (common->getucd != NULL) + { + set_jumps(common->getucd, LABEL()); + do_getucd(common); + } +#endif + +SLJIT_FREE(common->optimized_cbracket); +SLJIT_FREE(common->private_data_ptrs); +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 + { + /* Note: If your memory-checker has flagged the allocation below as a + * memory leak, it is probably because you either forgot to call + * pcre_free_study() (or pcre16_free_study()) on the pcre_extra (or + * pcre16_extra) object, or you called said function after having + * cleared the PCRE_EXTRA_EXECUTABLE_JIT bit from the "flags" field + * of the object. (The function will only free the JIT data if the + * bit remains set, as the bit indicates that the pointer to the data + * is valid.) + */ + 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)); + functions->top_bracket = (re->top_bracket + 1) * 2; + 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_space[MACHINE_STACK_SIZE]; +struct sljit_stack local_stack; + +local_stack.top = (sljit_sw)&local_space; +local_stack.base = local_stack.top; +local_stack.limit = local_stack.base + MACHINE_STACK_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 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_JIT_BADOPTION; + +/* Sanity checks should be handled by pcre_exec. */ +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 = functions->top_bracket; +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; +} + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data, + PCRE_SPTR subject, int length, int start_offset, int options, + int *offsets, int offsetcount, pcre_jit_stack *stack) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, + PCRE_SPTR16 subject, int length, int start_offset, int options, + int *offsets, int offsetcount, pcre16_jit_stack *stack) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data, + PCRE_SPTR32 subject, int length, int start_offset, int options, + int *offsets, int offsetcount, pcre32_jit_stack *stack) +#endif +{ +pcre_uchar *subject_ptr = (pcre_uchar *)subject; +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; + +SLJIT_UNUSED_ARG(argument_re); + +/* Plausibility checks */ +if ((options & ~PUBLIC_JIT_EXEC_OPTIONS) != 0) return PCRE_ERROR_JIT_BADOPTION; + +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_JIT_BADOPTION; + +/* Sanity checks should be handled by pcre_exec. */ +arguments.stack = (struct sljit_stack *)stack; +arguments.str = subject_ptr + start_offset; +arguments.begin = subject_ptr; +arguments.end = subject_ptr + 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 = functions->top_bracket; +if (offsetcount > maxoffsetcount) + offsetcount = maxoffsetcount; +arguments.offsetcount = offsetcount; + +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(); +} + +#if defined COMPILE_PCRE8 +PCRE_EXP_DECL pcre_jit_stack * +pcre_jit_stack_alloc(int startsize, int maxsize) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DECL pcre16_jit_stack * +pcre16_jit_stack_alloc(int startsize, int maxsize) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DECL pcre32_jit_stack * +pcre32_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); +} + +#if defined COMPILE_PCRE8 +PCRE_EXP_DECL void +pcre_jit_stack_free(pcre_jit_stack *stack) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DECL void +pcre16_jit_stack_free(pcre16_jit_stack *stack) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DECL void +pcre32_jit_stack_free(pcre32_jit_stack *stack) +#endif +{ +sljit_free_stack((struct sljit_stack *)stack); +} + +#if defined COMPILE_PCRE8 +PCRE_EXP_DECL void +pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DECL void +pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DECL void +pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_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. */ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DECL pcre_jit_stack * +pcre_jit_stack_alloc(int startsize, int maxsize) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DECL pcre16_jit_stack * +pcre16_jit_stack_alloc(int startsize, int maxsize) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DECL pcre32_jit_stack * +pcre32_jit_stack_alloc(int startsize, int maxsize) +#endif +{ +(void)startsize; +(void)maxsize; +return NULL; +} + +#if defined COMPILE_PCRE8 +PCRE_EXP_DECL void +pcre_jit_stack_free(pcre_jit_stack *stack) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DECL void +pcre16_jit_stack_free(pcre16_jit_stack *stack) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DECL void +pcre32_jit_stack_free(pcre32_jit_stack *stack) +#endif +{ +(void)stack; +} + +#if defined COMPILE_PCRE8 +PCRE_EXP_DECL void +pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DECL void +pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DECL void +pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata) +#endif +{ +(void)extra; +(void)callback; +(void)userdata; +} + +#endif + +/* End of pcre_jit_compile.c */ diff --git a/tools/pcre/pcre_jit_test.c b/tools/pcre/pcre_jit_test.c new file mode 100644 index 00000000..e8a297c9 --- /dev/null +++ b/tools/pcre/pcre_jit_test.c @@ -0,0 +1,1614 @@ +/************************************************* +* 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" + + +#include "pcre_internal.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; +#if defined SUPPORT_PCRE8 + pcre_config(PCRE_CONFIG_JIT, &jit); +#elif defined SUPPORT_PCRE16 + pcre16_config(PCRE_CONFIG_JIT, &jit); +#elif defined SUPPORT_PCRE32 + pcre32_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) && !(defined SUPPORT_PCRE32) +#error SUPPORT_PCRE8 or SUPPORT_PCRE16 or SUPPORT_PCRE32 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_NO32 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_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" }, + { MUA | PCRE_FIRSTLINE, 0, "\xf0\x90\x90\x80", "\xf0\x90\x90\x80" }, + { 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" }, + { PCRE_FIRSTLINE | PCRE_NEWLINE_LF | PCRE_DOTALL, 0 | F_NOMATCH, "ab.", "ab" }, + + /* 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; +#if defined SUPPORT_PCRE8 + pcre *regex; + char null_str[1] = { 0 }; +#elif defined SUPPORT_PCRE16 + pcre16 *regex; + PCRE_UCHAR16 null_str[1] = { 0 }; +#elif defined SUPPORT_PCRE32 + pcre32 *regex; + PCRE_UCHAR32 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; +#if defined 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); + } +#elif defined SUPPORT_PCRE16 + regex = pcre16_compile(null_str, 0, &errorptr, &erroroffset, NULL); + if (regex) { + pcre16_fullinfo(regex, NULL, PCRE_INFO_DEFAULT_TABLES, &default_tables); + pcre16_free(regex); + } +#elif defined SUPPORT_PCRE32 + regex = pcre32_compile(null_str, 0, &errorptr, &erroroffset, NULL); + if (regex) { + pcre32_fullinfo(regex, NULL, PCRE_INFO_DEFAULT_TABLES, &default_tables); + pcre32_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_PCRE32 +static pcre32_jit_stack* callback32(void *arg) +{ + return (pcre32_jit_stack *)arg; +} +#endif + +#ifdef SUPPORT_PCRE8 +static pcre_jit_stack *stack8; + +static pcre_jit_stack *getstack8(void) +{ + if (!stack8) + stack8 = pcre_jit_stack_alloc(1, 1024 * 1024); + return stack8; +} + +static void setstack8(pcre_extra *extra) +{ + if (!extra) { + if (stack8) + pcre_jit_stack_free(stack8); + stack8 = NULL; + return; + } + + pcre_assign_jit_stack(extra, callback8, getstack8()); +} +#endif /* SUPPORT_PCRE8 */ + +#ifdef SUPPORT_PCRE16 +static pcre16_jit_stack *stack16; + +static pcre16_jit_stack *getstack16(void) +{ + if (!stack16) + stack16 = pcre16_jit_stack_alloc(1, 1024 * 1024); + return stack16; +} + +static void setstack16(pcre16_extra *extra) +{ + if (!extra) { + if (stack16) + pcre16_jit_stack_free(stack16); + stack16 = NULL; + return; + } + + pcre16_assign_jit_stack(extra, callback16, getstack16()); +} +#endif /* SUPPORT_PCRE8 */ + +#ifdef SUPPORT_PCRE32 +static pcre32_jit_stack *stack32; + +static pcre32_jit_stack *getstack32(void) +{ + if (!stack32) + stack32 = pcre32_jit_stack_alloc(1, 1024 * 1024); + return stack32; +} + +static void setstack32(pcre32_extra *extra) +{ + if (!extra) { + if (stack32) + pcre32_jit_stack_free(stack32); + stack32 = NULL; + return; + } + + pcre32_assign_jit_stack(extra, callback32, getstack32()); +} +#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; + PCRE_UCHAR16 *optr = 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 - 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 - output); +} + +static int copy_char8_to_char16(const char *input, PCRE_UCHAR16 *output, int max_length) +{ + unsigned char *iptr = (unsigned char*)input; + PCRE_UCHAR16 *optr = output; + + if (max_length == 0) + return 0; + + while (*iptr && max_length > 1) { + *optr++ = *iptr++; + max_length--; + } + *optr = '\0'; + return (int)(optr - output); +} + +#define REGTEST_MAX_LENGTH16 4096 +static PCRE_UCHAR16 regtest_buf16[REGTEST_MAX_LENGTH16]; +static int regtest_offsetmap16[REGTEST_MAX_LENGTH16]; + +#endif /* SUPPORT_PCRE16 */ + +#ifdef SUPPORT_PCRE32 + +static int convert_utf8_to_utf32(const char *input, PCRE_UCHAR32 *output, int *offsetmap, int max_length) +{ + unsigned char *iptr = (unsigned char*)input; + PCRE_UCHAR32 *optr = 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; + } + + *optr++ = c; + max_length--; + } + if (offsetmap) + *offsetmap = (int)(iptr - (unsigned char*)input); + *optr = 0; + return (int)(optr - output); +} + +static int copy_char8_to_char32(const char *input, PCRE_UCHAR32 *output, int max_length) +{ + unsigned char *iptr = (unsigned char*)input; + PCRE_UCHAR32 *optr = output; + + if (max_length == 0) + return 0; + + while (*iptr && max_length > 1) { + *optr++ = *iptr++; + max_length--; + } + *optr = '\0'; + return (int)(optr - output); +} + +#define REGTEST_MAX_LENGTH32 4096 +static PCRE_UCHAR32 regtest_buf32[REGTEST_MAX_LENGTH32]; +static int regtest_offsetmap32[REGTEST_MAX_LENGTH32]; + +#endif /* SUPPORT_PCRE32 */ + +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; + int utf = 0, ucp = 0; + int disabled_flags = 0; +#ifdef SUPPORT_PCRE8 + pcre *re8; + pcre_extra *extra8; + pcre_extra dummy_extra8; + int ovector8_1[32]; + int ovector8_2[32]; + int return_value8[2]; + unsigned char *mark8_1, *mark8_2; +#endif +#ifdef SUPPORT_PCRE16 + pcre16 *re16; + pcre16_extra *extra16; + pcre16_extra dummy_extra16; + int ovector16_1[32]; + int ovector16_2[32]; + int return_value16[2]; + PCRE_UCHAR16 *mark16_1, *mark16_2; + int length16; +#endif +#ifdef SUPPORT_PCRE32 + pcre32 *re32; + pcre32_extra *extra32; + pcre32_extra dummy_extra32; + int ovector32_1[32]; + int ovector32_2[32]; + int return_value32[2]; + PCRE_UCHAR32 *mark32_1, *mark32_2; + int length32; +#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. */ + +#if defined SUPPORT_PCRE8 + pcre_config(PCRE_CONFIG_JITTARGET, &cpu_info); +#elif defined SUPPORT_PCRE16 + pcre16_config(PCRE_CONFIG_JITTARGET, &cpu_info); +#elif defined SUPPORT_PCRE32 + pcre32_config(PCRE_CONFIG_JITTARGET, &cpu_info); +#endif + + printf("Running JIT regression tests\n"); + printf(" target CPU of SLJIT compiler: %s\n", cpu_info); + +#if defined SUPPORT_PCRE8 + pcre_config(PCRE_CONFIG_UTF8, &utf); + pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp); +#elif defined SUPPORT_PCRE16 + pcre16_config(PCRE_CONFIG_UTF16, &utf); + pcre16_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp); +#elif defined SUPPORT_PCRE16 + pcre32_config(PCRE_CONFIG_UTF32, &utf); + pcre32_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp); +#endif + + if (!utf) + disabled_flags |= PCRE_UTF8 | PCRE_UTF16 | PCRE_UTF32; + if (!ucp) + disabled_flags |= PCRE_UCP; +#ifdef SUPPORT_PCRE8 + printf(" in 8 bit mode with UTF-8 %s and ucp %s:\n", utf ? "enabled" : "disabled", ucp ? "enabled" : "disabled"); +#endif +#ifdef SUPPORT_PCRE16 + printf(" in 16 bit mode with UTF-16 %s and ucp %s:\n", utf ? "enabled" : "disabled", ucp ? "enabled" : "disabled"); +#endif +#ifdef SUPPORT_PCRE32 + printf(" in 32 bit mode with UTF-32 %s and ucp %s:\n", utf ? "enabled" : "disabled", ucp ? "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_flags), + &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; + } + else 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 (((utf && ucp) || is_ascii_pattern) && !(current->start_offset & F_NO8)) + printf("\n8 bit: Cannot compile pattern \"%s\": %s\n", current->pattern, error); +#endif +#ifdef SUPPORT_PCRE16 + if ((current->flags & PCRE_UTF16) || (current->start_offset & F_FORCECONV)) + convert_utf8_to_utf16(current->pattern, regtest_buf16, NULL, REGTEST_MAX_LENGTH16); + else + copy_char8_to_char16(current->pattern, regtest_buf16, REGTEST_MAX_LENGTH16); + + re16 = NULL; + if (!(current->start_offset & F_NO16)) + re16 = pcre16_compile(regtest_buf16, + current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | disabled_flags), + &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; + } + else 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 (((utf && ucp) || is_ascii_pattern) && !(current->start_offset & F_NO16)) + printf("\n16 bit: Cannot compile pattern \"%s\": %s\n", current->pattern, error); +#endif +#ifdef SUPPORT_PCRE32 + if ((current->flags & PCRE_UTF32) || (current->start_offset & F_FORCECONV)) + convert_utf8_to_utf32(current->pattern, regtest_buf32, NULL, REGTEST_MAX_LENGTH32); + else + copy_char8_to_char32(current->pattern, regtest_buf32, REGTEST_MAX_LENGTH32); + + re32 = NULL; + if (!(current->start_offset & F_NO32)) + re32 = pcre32_compile(regtest_buf32, + current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | disabled_flags), + &error, &err_offs, tables(0)); + + extra32 = NULL; + if (re32) { + error = NULL; + extra32 = pcre32_study(re32, study_mode, &error); + if (!extra32) { + printf("\n32 bit: Cannot study pattern: %s\n", current->pattern); + pcre32_free(re32); + re32 = NULL; + } + if (!(extra32->flags & PCRE_EXTRA_EXECUTABLE_JIT)) { + printf("\n32 bit: JIT compiler does not support: %s\n", current->pattern); + pcre32_free_study(extra32); + pcre32_free(re32); + re32 = NULL; + } + extra32->flags |= PCRE_EXTRA_MARK; + } else if (((utf && ucp) || is_ascii_pattern) && !(current->start_offset & F_NO32)) + printf("\n32 bit: Cannot compile pattern \"%s\": %s\n", current->pattern, error); +#endif + + counter++; + if ((counter & 0x3) != 0) { +#ifdef SUPPORT_PCRE8 + setstack8(NULL); +#endif +#ifdef SUPPORT_PCRE16 + setstack16(NULL); +#endif +#ifdef SUPPORT_PCRE32 + setstack32(NULL); +#endif + } + +#ifdef SUPPORT_PCRE8 + return_value8[0] = -1000; + return_value8[1] = -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; + extra8->mark = &mark8_1; + + if ((counter & 0x1) != 0) { + setstack8(extra8); + return_value8[0] = 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); + } else + return_value8[0] = pcre_jit_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, getstack8()); + memset(&dummy_extra8, 0, sizeof(pcre_extra)); + dummy_extra8.flags = PCRE_EXTRA_MARK; + dummy_extra8.mark = &mark8_2; + return_value8[1] = 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[0] = -1000; + return_value16[1] = -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; + if ((current->flags & PCRE_UTF16) || (current->start_offset & F_FORCECONV)) + length16 = convert_utf8_to_utf16(current->input, regtest_buf16, regtest_offsetmap16, REGTEST_MAX_LENGTH16); + else + length16 = copy_char8_to_char16(current->input, regtest_buf16, REGTEST_MAX_LENGTH16); + extra16->mark = &mark16_1; + if ((counter & 0x1) != 0) { + setstack16(extra16); + return_value16[0] = pcre16_exec(re16, extra16, regtest_buf16, 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); + } else + return_value16[0] = pcre16_jit_exec(re16, extra16, regtest_buf16, 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, getstack16()); + memset(&dummy_extra16, 0, sizeof(pcre16_extra)); + dummy_extra16.flags = PCRE_EXTRA_MARK; + dummy_extra16.mark = &mark16_2; + return_value16[1] = pcre16_exec(re16, &dummy_extra16, regtest_buf16, 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 + +#ifdef SUPPORT_PCRE32 + return_value32[0] = -1000; + return_value32[1] = -1000; + for (i = 0; i < 32; ++i) + ovector32_1[i] = -2; + for (i = 0; i < 32; ++i) + ovector32_2[i] = -2; + if (re32) { + mark32_1 = NULL; + mark32_2 = NULL; + if ((current->flags & PCRE_UTF32) || (current->start_offset & F_FORCECONV)) + length32 = convert_utf8_to_utf32(current->input, regtest_buf32, regtest_offsetmap32, REGTEST_MAX_LENGTH32); + else + length32 = copy_char8_to_char32(current->input, regtest_buf32, REGTEST_MAX_LENGTH32); + extra32->mark = &mark32_1; + if ((counter & 0x1) != 0) { + setstack32(extra32); + return_value32[0] = pcre32_exec(re32, extra32, regtest_buf32, length32, current->start_offset & OFFSET_MASK, + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector32_1, 32); + } else + return_value32[0] = pcre32_jit_exec(re32, extra32, regtest_buf32, length32, current->start_offset & OFFSET_MASK, + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector32_1, 32, getstack32()); + memset(&dummy_extra32, 0, sizeof(pcre32_extra)); + dummy_extra32.flags = PCRE_EXTRA_MARK; + dummy_extra32.mark = &mark32_2; + return_value32[1] = pcre32_exec(re32, &dummy_extra32, regtest_buf32, length32, current->start_offset & OFFSET_MASK, + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector32_2, 32); + } +#endif + + /* printf("[%d-%d-%d|%d-%d|%d-%d|%d-%d]%s", + return_value8[0], return_value16[0], + ovector8_1[0], ovector8_1[1], + ovector16_1[0], ovector16_1[1], + ovector32_1[0], ovector32_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_UTF && ((defined(SUPPORT_PCRE8) + defined(SUPPORT_PCRE16) + defined(SUPPORT_PCRE32)) >= 2) + if (!(current->start_offset & F_FORCECONV)) { + int return_value; + + /* All results must be the same. */ +#ifdef SUPPORT_PCRE8 + if ((return_value = return_value8[0]) != return_value8[1]) { + printf("\n8 bit: Return value differs(J8:%d,I8:%d): [%d] '%s' @ '%s'\n", + return_value8[0], return_value8[1], total, current->pattern, current->input); + is_successful = 0; + } else +#endif +#ifdef SUPPORT_PCRE16 + if ((return_value = return_value16[0]) != return_value16[1]) { + printf("\n16 bit: Return value differs(J16:%d,I16:%d): [%d] '%s' @ '%s'\n", + return_value16[0], return_value16[1], total, current->pattern, current->input); + is_successful = 0; + } else +#endif +#ifdef SUPPORT_PCRE32 + if ((return_value = return_value32[0]) != return_value32[1]) { + printf("\n32 bit: Return value differs(J32:%d,I32:%d): [%d] '%s' @ '%s'\n", + return_value32[0], return_value32[1], total, current->pattern, current->input); + is_successful = 0; + } else +#endif +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 + if (return_value8[0] != return_value16[0]) { + printf("\n8 and 16 bit: Return value differs(J8:%d,J16:%d): [%d] '%s' @ '%s'\n", + return_value8[0], return_value16[0], + total, current->pattern, current->input); + is_successful = 0; + } else +#endif +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE32 + if (return_value8[0] != return_value32[0]) { + printf("\n8 and 32 bit: Return value differs(J8:%d,J32:%d): [%d] '%s' @ '%s'\n", + return_value8[0], return_value32[0], + total, current->pattern, current->input); + is_successful = 0; + } else +#endif +#if defined SUPPORT_PCRE16 && defined SUPPORT_PCRE32 + if (return_value16[0] != return_value32[0]) { + printf("\n16 and 32 bit: Return value differs(J16:%d,J32:%d): [%d] '%s' @ '%s'\n", + return_value16[0], return_value32[0], + total, current->pattern, current->input); + is_successful = 0; + } else +#endif + if (return_value >= 0 || return_value == PCRE_ERROR_PARTIAL) { + if (return_value == PCRE_ERROR_PARTIAL) { + return_value = 2; + } else { + return_value *= 2; + } +#ifdef SUPPORT_PCRE8 + return_value8[0] = return_value; +#endif +#ifdef SUPPORT_PCRE16 + return_value16[0] = return_value; +#endif +#ifdef SUPPORT_PCRE32 + return_value32[0] = return_value; +#endif + /* Transform back the results. */ + if (current->flags & PCRE_UTF8) { +#ifdef SUPPORT_PCRE16 + for (i = 0; i < return_value; ++i) { + if (ovector16_1[i] >= 0) + ovector16_1[i] = regtest_offsetmap16[ovector16_1[i]]; + if (ovector16_2[i] >= 0) + ovector16_2[i] = regtest_offsetmap16[ovector16_2[i]]; + } +#endif +#ifdef SUPPORT_PCRE32 + for (i = 0; i < return_value; ++i) { + if (ovector32_1[i] >= 0) + ovector32_1[i] = regtest_offsetmap32[ovector32_1[i]]; + if (ovector32_2[i] >= 0) + ovector32_2[i] = regtest_offsetmap32[ovector32_2[i]]; + } +#endif + } + + for (i = 0; i < return_value; ++i) { +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 + 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(J8:%d,I8:%d,J16:%d,I16:%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; + } +#endif +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE32 + if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector32_1[i] || ovector8_1[i] != ovector32_2[i]) { + printf("\n8 and 32 bit: Ovector[%d] value differs(J8:%d,I8:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n", + i, ovector8_1[i], ovector8_2[i], ovector32_1[i], ovector32_2[i], + total, current->pattern, current->input); + is_successful = 0; + } +#endif +#if defined SUPPORT_PCRE16 && defined SUPPORT_PCRE16 + if (ovector16_1[i] != ovector16_2[i] || ovector16_1[i] != ovector16_1[i] || ovector16_1[i] != ovector16_2[i]) { + printf("\n16 and 16 bit: Ovector[%d] value differs(J16:%d,I16:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n", + i, ovector16_1[i], ovector16_2[i], ovector16_1[i], ovector16_2[i], + total, current->pattern, current->input); + is_successful = 0; + } +#endif + } + } + } else +#endif /* more than one of SUPPORT_PCRE8, SUPPORT_PCRE16 and SUPPORT_PCRE32 */ + { + /* Only the 8 bit and 16 bit results must be equal. */ +#ifdef SUPPORT_PCRE8 + if (return_value8[0] != return_value8[1]) { + printf("\n8 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", + return_value8[0], return_value8[1], total, current->pattern, current->input); + is_successful = 0; + } else if (return_value8[0] >= 0 || return_value8[0] == PCRE_ERROR_PARTIAL) { + if (return_value8[0] == PCRE_ERROR_PARTIAL) + return_value8[0] = 2; + else + return_value8[0] *= 2; + + for (i = 0; i < return_value8[0]; ++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[0] != return_value16[1]) { + printf("\n16 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", + return_value16[0], return_value16[1], total, current->pattern, current->input); + is_successful = 0; + } else if (return_value16[0] >= 0 || return_value16[0] == PCRE_ERROR_PARTIAL) { + if (return_value16[0] == PCRE_ERROR_PARTIAL) + return_value16[0] = 2; + else + return_value16[0] *= 2; + + for (i = 0; i < return_value16[0]; ++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 + +#ifdef SUPPORT_PCRE32 + if (return_value32[0] != return_value32[1]) { + printf("\n32 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", + return_value32[0], return_value32[1], total, current->pattern, current->input); + is_successful = 0; + } else if (return_value32[0] >= 0 || return_value32[0] == PCRE_ERROR_PARTIAL) { + if (return_value32[0] == PCRE_ERROR_PARTIAL) + return_value32[0] = 2; + else + return_value32[0] *= 2; + + for (i = 0; i < return_value32[0]; ++i) + if (ovector32_1[i] != ovector32_2[i]) { + printf("\n32 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", + i, ovector32_1[i], ovector32_2[i], total, current->pattern, current->input); + is_successful = 0; + } + } +#endif + } + } + + if (is_successful) { +#ifdef SUPPORT_PCRE8 + if (!(current->start_offset & F_NO8) && ((utf && ucp) || is_ascii_input)) { + if (return_value8[0] < 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[0] >= 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) && ((utf && ucp) || is_ascii_input)) { + if (return_value16[0] < 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[0] >= 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 +#ifdef SUPPORT_PCRE32 + if (!(current->start_offset & F_NO32) && ((utf && ucp) || is_ascii_input)) { + if (return_value32[0] < 0 && !(current->start_offset & F_NOMATCH)) { + printf("32 bit: Test should match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + + if (return_value32[0] >= 0 && (current->start_offset & F_NOMATCH)) { + printf("32 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_PCRE32 + if (mark32_1 != mark32_2) { + printf("32 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 +#ifdef SUPPORT_PCRE32 + if (re32) { + pcre32_free_study(extra32); + pcre32_free(re32); + } +#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 +#ifdef SUPPORT_PCRE32 + setstack32(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 --git a/tools/pcre/pcre_maketables.c b/tools/pcre/pcre_maketables.c new file mode 100644 index 00000000..610a6695 --- /dev/null +++ b/tools/pcre/pcre_maketables.c @@ -0,0 +1,151 @@ +/************************************************* +* 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 the external function pcre_maketables(), which builds +character tables for PCRE in the current locale. The file is compiled on its +own as part of the PCRE library. However, it is also included in the +compilation of dftables.c, in which case the macro DFTABLES is defined. */ + + +#ifndef DFTABLES +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif +# include "pcre_internal.h" +#endif + + +/************************************************* +* Create PCRE character tables * +*************************************************/ + +/* 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 PUBL(malloc)(), but when +compiled inside dftables, use malloc(). + +Arguments: none +Returns: pointer to the contiguous block of data +*/ + +#if defined COMPILE_PCRE8 +const unsigned char * +pcre_maketables(void) +#elif defined COMPILE_PCRE16 +const unsigned char * +pcre16_maketables(void) +#elif defined COMPILE_PCRE32 +const unsigned char * +pcre32_maketables(void) +#endif +{ +unsigned char *yield, *p; +int i; + +#ifndef DFTABLES +yield = (unsigned char*)(PUBL(malloc))(tables_length); +#else +yield = (unsigned char*)malloc(tables_length); +#endif + +if (yield == NULL) return NULL; +p = yield; + +/* First comes the lower casing table */ + +for (i = 0; i < 256; i++) *p++ = tolower(i); + +/* Next the case-flipping table */ + +for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i); + +/* Then the character class tables. Don't try to be clever and save effort on +exclusive ones - in some locales things may be different. Note that the table +for "space" includes everything "isspace" gives, including VT in the default +locale. This makes it work for the POSIX class [:space:]. Note also that it is +possible for a character to be alnum or alpha without being lower or upper, +such as "male and female ordinals" (\xAA and \xBA) in the fr_FR locale (at +least under Debian Linux's locales as of 12/2005). So we must test for alnum +specially. */ + +memset(p, 0, cbit_length); +for (i = 0; i < 256; i++) + { + if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7); + if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7); + if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7); + if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7); + if (i == '_') p[cbit_word + i/8] |= 1 << (i&7); + if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7); + if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7); + if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7); + if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7); + if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7); + if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7); + } +p += cbit_length; + +/* Finally, the character type table. In this, we exclude VT from the white +space chars, because Perl doesn't recognize it as such for \s and for comments +within regexes. */ + +for (i = 0; i < 256; i++) + { + int x = 0; + if (i != CHAR_VT && isspace(i)) x += ctype_space; + if (isalpha(i)) x += ctype_letter; + if (isdigit(i)) x += ctype_digit; + if (isxdigit(i)) x += ctype_xdigit; + if (isalnum(i) || i == '_') x += ctype_word; + + /* Note: strchr includes the terminating zero in the characters it considers. + In this instance, that is ok because we want binary zero to be flagged as a + meta-character, which in this sense is any character that terminates a run + of data characters. */ + + if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta; + *p++ = x; + } + +return yield; +} + +/* End of pcre_maketables.c */ diff --git a/tools/pcre/pcre_newline.c b/tools/pcre/pcre_newline.c new file mode 100644 index 00000000..b8f5a4de --- /dev/null +++ b/tools/pcre/pcre_newline.c @@ -0,0 +1,210 @@ +/************************************************* +* 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 internal functions for testing newlines when more than +one kind of newline is to be recognized. When a newline is found, its length is +returned. In principle, we could implement several newline "types", each +referring to a different set of newline characters. At present, PCRE supports +only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF, +and NLTYPE_ANY. The full list of Unicode newline characters is taken from +http://unicode.org/unicode/reports/tr18/. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + + + +/************************************************* +* Check for newline at given position * +*************************************************/ + +/* It is guaranteed that the initial value of ptr is less than the end of the +string that is being processed. + +Arguments: + ptr pointer to possible newline + type the newline type + endptr pointer to the end of the string + lenptr where to return the length + utf TRUE if in utf mode + +Returns: TRUE or FALSE +*/ + +BOOL +PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr, + BOOL utf) +{ +pcre_uint32 c; +(void)utf; +#ifdef SUPPORT_UTF +if (utf) + { + GETCHAR(c, ptr); + } +else +#endif /* SUPPORT_UTF */ + c = *ptr; + +/* Note that this function is called only for ANY or ANYCRLF. */ + +if (type == NLTYPE_ANYCRLF) switch(c) + { + case CHAR_LF: *lenptr = 1; return TRUE; + case CHAR_CR: *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1; + return TRUE; + default: return FALSE; + } + +/* NLTYPE_ANY */ + +else switch(c) + { +#ifdef EBCDIC + case CHAR_NEL: +#endif + case CHAR_LF: + case CHAR_VT: + case CHAR_FF: *lenptr = 1; return TRUE; + + case CHAR_CR: + *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1; + return TRUE; + +#ifndef EBCDIC +#ifdef COMPILE_PCRE8 + case CHAR_NEL: *lenptr = utf? 2 : 1; return TRUE; + case 0x2028: /* LS */ + case 0x2029: *lenptr = 3; return TRUE; /* PS */ +#else /* COMPILE_PCRE16 || COMPILE_PCRE32 */ + case CHAR_NEL: + case 0x2028: /* LS */ + case 0x2029: *lenptr = 1; return TRUE; /* PS */ +#endif /* COMPILE_PCRE8 */ +#endif /* Not EBCDIC */ + + default: return FALSE; + } +} + + + +/************************************************* +* Check for newline at previous position * +*************************************************/ + +/* It is guaranteed that the initial value of ptr is greater than the start of +the string that is being processed. + +Arguments: + ptr pointer to possible newline + type the newline type + startptr pointer to the start of the string + lenptr where to return the length + utf TRUE if in utf mode + +Returns: TRUE or FALSE +*/ + +BOOL +PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr, + BOOL utf) +{ +pcre_uint32 c; +(void)utf; +ptr--; +#ifdef SUPPORT_UTF +if (utf) + { + BACKCHAR(ptr); + GETCHAR(c, ptr); + } +else +#endif /* SUPPORT_UTF */ + c = *ptr; + +/* Note that this function is called only for ANY or ANYCRLF. */ + +if (type == NLTYPE_ANYCRLF) switch(c) + { + case CHAR_LF: + *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1; + return TRUE; + + case CHAR_CR: *lenptr = 1; return TRUE; + default: return FALSE; + } + +/* NLTYPE_ANY */ + +else switch(c) + { + case CHAR_LF: + *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1; + return TRUE; + +#ifdef EBCDIC + case CHAR_NEL: +#endif + case CHAR_VT: + case CHAR_FF: + case CHAR_CR: *lenptr = 1; return TRUE; + +#ifndef EBCDIC +#ifdef COMPILE_PCRE8 + case CHAR_NEL: *lenptr = utf? 2 : 1; return TRUE; + case 0x2028: /* LS */ + case 0x2029: *lenptr = 3; return TRUE; /* PS */ +#else /* COMPILE_PCRE16 || COMPILE_PCRE32 */ + case CHAR_NEL: + case 0x2028: /* LS */ + case 0x2029: *lenptr = 1; return TRUE; /* PS */ +#endif /* COMPILE_PCRE8 */ +#endif /* NotEBCDIC */ + + default: return FALSE; + } +} + +/* End of pcre_newline.c */ diff --git a/tools/pcre/pcre_ord2utf8.c b/tools/pcre/pcre_ord2utf8.c new file mode 100644 index 00000000..95f1beb9 --- /dev/null +++ b/tools/pcre/pcre_ord2utf8.c @@ -0,0 +1,94 @@ +/************************************************* +* 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 UTF8 string. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define COMPILE_PCRE8 + +#include "pcre_internal.h" + +/************************************************* +* Convert character value to UTF-8 * +*************************************************/ + +/* This function takes an integer value in the range 0 - 0x10ffff +and encodes it as a UTF-8 character in 1 to 4 pcre_uchars. + +Arguments: + cvalue the character value + buffer pointer to buffer for result - at least 6 pcre_uchars long + +Returns: number of characters placed in the buffer +*/ + +unsigned +int +PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer) +{ +#ifdef SUPPORT_UTF + +register int i, j; + +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 = 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_UTF is not defined. */ +return 0; + +#endif +} + +/* End of pcre_ord2utf8.c */ diff --git a/tools/pcre/pcre_printint.c b/tools/pcre/pcre_printint.c new file mode 100644 index 00000000..10b57542 --- /dev/null +++ b/tools/pcre/pcre_printint.c @@ -0,0 +1,766 @@ +/************************************************* +* 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 + +#if defined COMPILE_PCRE8 +void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths); +#elif defined COMPILE_PCRE16 +void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths); +#elif defined COMPILE_PCRE32 +void pcre32_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 unsigned int +print_char(FILE *f, pcre_uchar *ptr, BOOL utf) +{ +pcre_uint32 c = *ptr; + +#ifndef SUPPORT_UTF + +(void)utf; /* Avoid compiler warning */ +if (PRINTABLE(c)) fprintf(f, "%c", (char)c); +else if (c <= 0x80) fprintf(f, "\\x%02x", c); +else fprintf(f, "\\x{%x}", c); +return 0; + +#else + +#if defined COMPILE_PCRE8 + +if (!utf || (c & 0xc0) != 0xc0) + { + if (PRINTABLE(c)) fprintf(f, "%c", (char)c); + else if (c < 0x80) fprintf(f, "\\x%02x", 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; + } + +#elif defined COMPILE_PCRE16 + +if (!utf || (c & 0xfc00) != 0xd800) + { + if (PRINTABLE(c)) fprintf(f, "%c", (char)c); + else if (c <= 0x80) fprintf(f, "\\x%02x", c); + else fprintf(f, "\\x{%02x}", 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; + } + +#elif defined COMPILE_PCRE32 + +if (!utf || (c & 0xfffff800u) != 0xd800u) + { + if (PRINTABLE(c)) fprintf(f, "%c", (char)c); + else if (c <= 0x80) fprintf(f, "\\x%02x", c); + else fprintf(f, "\\x{%x}", c); + return 0; + } +else + { + /* This is a check for malformed UTF-32; it should only occur if the sanity + check has been turned off. Rather than swallow a surrogate, just stop if + we hit one. Print it with \X instead of \x as an indication. */ + fprintf(f, "\\X{%x}", c); + return 0; + } + +#endif /* COMPILE_PCRE[8|16|32] */ + +#endif /* SUPPORT_UTF */ +} + +/************************************************* +* Print uchar string (regardless of utf) * +*************************************************/ + +static void +print_puchar(FILE *f, PCRE_PUCHAR ptr) +{ +while (*ptr != '\0') + { + register pcre_uint32 c = *ptr++; + if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c); + } +} + +/************************************************* +* Find Unicode property name * +*************************************************/ + +static const char * +get_ucpname(unsigned int ptype, unsigned 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 Unicode property value * +*************************************************/ + +/* "Normal" properties can be printed from tables. The PT_CLIST property is a +pseudo-property that contains a pointer to a list of case-equivalent +characters. This is used only when UCP support is available and UTF mode is +selected. It should never occur otherwise, but just in case it does, have +something ready to print. */ + +static void +print_prop(FILE *f, pcre_uchar *code, const char *before, const char *after) +{ +if (code[1] != PT_CLIST) + { + fprintf(f, "%s%s %s%s", before, priv_OP_names[*code], get_ucpname(code[1], + code[2]), after); + } +else + { + const char *not = (*code == OP_PROP)? "" : "not "; +#ifndef SUPPORT_UCP + fprintf(f, "%s%sclist %d%s", before, not, code[2], after); +#else + const pcre_uint32 *p = PRIV(ucd_caseless_sets) + code[2]; + fprintf (f, "%s%sclist", before, not); + while (*p < NOTACHAR) fprintf(f, " %04x", *p++); + fprintf(f, "%s", after); +#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 +#if defined COMPILE_PCRE8 +void +pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths) +#elif defined COMPILE_PCRE16 +void +pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths) +#elif defined COMPILE_PCRE32 +void +pcre32_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_UTF(16|32) have the same value as PCRE_UTF8. */ +utf = (options & PCRE_UTF8) != 0; + +for(;;) + { + pcre_uchar *ccode; + const char *flag = " "; + pcre_uint32 c; + unsigned 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) + { + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) + { + print_prop(f, code + 1, "", " "); + extra = 2; + } + else fprintf(f, "%s", priv_OP_names[code[1]]); + } + 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: + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + { + print_prop(f, code + IMM2_SIZE + 1, " ", " "); + extra = 2; + } + else fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]); + 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: + print_prop(f, code, " ", ""); + 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; + unsigned int 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) + { + pcre_uchar ch; + while ((ch = *ccode++) != XCL_END) + { + if (ch == XCL_PROP) + { + unsigned int ptype = *ccode++; + unsigned int pvalue = *ccode++; + fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue)); + } + else if (ch == XCL_NOTPROP) + { + unsigned int ptype = *ccode++; + unsigned 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, "{%u,}", min); + else fprintf(f, "{%u,%u}", 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 --git a/tools/pcre/pcre_refcount.c b/tools/pcre/pcre_refcount.c new file mode 100644 index 00000000..79efa90f --- /dev/null +++ b/tools/pcre/pcre_refcount.c @@ -0,0 +1,92 @@ +/************************************************* +* 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 the external function pcre_refcount(), which is an +auxiliary function that can be used to maintain a reference count in a compiled +pattern data block. This might be helpful in applications where the block is +shared by different users. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + + +/************************************************* +* Maintain reference count * +*************************************************/ + +/* The reference count is a 16-bit field, initialized to zero. It is not +possible to transfer a non-zero count from one host to a different host that +has a different byte order - though I can't see why anyone in their right mind +would ever want to do that! + +Arguments: + argument_re points to compiled code + adjust value to add to the count + +Returns: the (possibly updated) count value (a non-negative number), or + a negative error number +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre_refcount(pcre *argument_re, int adjust) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_refcount(pcre16 *argument_re, int adjust) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre32_refcount(pcre32 *argument_re, int adjust) +#endif +{ +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; +return re->ref_count; +} + +/* End of pcre_refcount.c */ diff --git a/tools/pcre/pcre_scanner.cc b/tools/pcre/pcre_scanner.cc new file mode 100644 index 00000000..6be2be68 --- /dev/null +++ b/tools/pcre/pcre_scanner.cc @@ -0,0 +1,199 @@ +// Copyright (c) 2005, Google Inc. +// All rights reserved. +// +// 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 Google Inc. 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. +// +// Author: Sanjay Ghemawat + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "pcrecpp_internal.h" +#include "pcre_scanner.h" + +using std::vector; + +namespace pcrecpp { + +Scanner::Scanner() + : data_(), + input_(data_), + skip_(NULL), + should_skip_(false), + skip_repeat_(false), + save_comments_(false), + comments_(NULL), + comments_offset_(0) { +} + +Scanner::Scanner(const string& in) + : data_(in), + input_(data_), + skip_(NULL), + should_skip_(false), + skip_repeat_(false), + save_comments_(false), + comments_(NULL), + comments_offset_(0) { +} + +Scanner::~Scanner() { + delete skip_; + delete comments_; +} + +void Scanner::SetSkipExpression(const char* re) { + delete skip_; + if (re != NULL) { + skip_ = new RE(re); + should_skip_ = true; + skip_repeat_ = true; + ConsumeSkip(); + } else { + skip_ = NULL; + should_skip_ = false; + skip_repeat_ = false; + } +} + +void Scanner::Skip(const char* re) { + delete skip_; + if (re != NULL) { + skip_ = new RE(re); + should_skip_ = true; + skip_repeat_ = false; + ConsumeSkip(); + } else { + skip_ = NULL; + should_skip_ = false; + skip_repeat_ = false; + } +} + +void Scanner::DisableSkip() { + assert(skip_ != NULL); + should_skip_ = false; +} + +void Scanner::EnableSkip() { + assert(skip_ != NULL); + should_skip_ = true; + ConsumeSkip(); +} + +int Scanner::LineNumber() const { + // TODO: Make it more efficient by keeping track of the last point + // where we computed line numbers and counting newlines since then. + // We could use std:count, but not all systems have it. :-( + int count = 1; + for (const char* p = data_.data(); p < input_.data(); ++p) + if (*p == '\n') + ++count; + return count; +} + +int Scanner::Offset() const { + return (int)(input_.data() - data_.c_str()); +} + +bool Scanner::LookingAt(const RE& re) const { + int consumed; + return re.DoMatch(input_, RE::ANCHOR_START, &consumed, 0, 0); +} + + +bool Scanner::Consume(const RE& re, + const Arg& arg0, + const Arg& arg1, + const Arg& arg2) { + const bool result = re.Consume(&input_, arg0, arg1, arg2); + if (result && should_skip_) ConsumeSkip(); + return result; +} + +// helper function to consume *skip_ and honour save_comments_ +void Scanner::ConsumeSkip() { + const char* start_data = input_.data(); + while (skip_->Consume(&input_)) { + if (!skip_repeat_) { + // Only one skip allowed. + break; + } + } + if (save_comments_) { + if (comments_ == NULL) { + comments_ = new vector; + } + // already pointing one past end, so no need to +1 + int length = (int)(input_.data() - start_data); + if (length > 0) { + comments_->push_back(StringPiece(start_data, length)); + } + } +} + + +void Scanner::GetComments(int start, int end, vector *ranges) { + // short circuit out if we've not yet initialized comments_ + // (e.g., when save_comments is false) + if (!comments_) { + return; + } + // TODO: if we guarantee that comments_ will contain StringPieces + // that are ordered by their start, then we can do a binary search + // for the first StringPiece at or past start and then scan for the + // ones contained in the range, quit early (use equal_range or + // lower_bound) + for (vector::const_iterator it = comments_->begin(); + it != comments_->end(); ++it) { + if ((it->data() >= data_.c_str() + start && + it->data() + it->size() <= data_.c_str() + end)) { + ranges->push_back(*it); + } + } +} + + +void Scanner::GetNextComments(vector *ranges) { + // short circuit out if we've not yet initialized comments_ + // (e.g., when save_comments is false) + if (!comments_) { + return; + } + for (vector::const_iterator it = + comments_->begin() + comments_offset_; + it != comments_->end(); ++it) { + ranges->push_back(*it); + ++comments_offset_; + } +} + +} // namespace pcrecpp diff --git a/tools/pcre/pcre_scanner.h b/tools/pcre/pcre_scanner.h new file mode 100644 index 00000000..5617e451 --- /dev/null +++ b/tools/pcre/pcre_scanner.h @@ -0,0 +1,172 @@ +// Copyright (c) 2005, Google Inc. +// All rights reserved. +// +// 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 Google Inc. 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. +// +// Author: Sanjay Ghemawat +// +// Regular-expression based scanner for parsing an input stream. +// +// Example 1: parse a sequence of "var = number" entries from input: +// +// Scanner scanner(input); +// string var; +// int number; +// scanner.SetSkipExpression("\\s+"); // Skip any white space we encounter +// while (scanner.Consume("(\\w+) = (\\d+)", &var, &number)) { +// ...; +// } + +#ifndef _PCRE_SCANNER_H +#define _PCRE_SCANNER_H + +#include +#include +#include + +#include +#include + +namespace pcrecpp { + +class PCRECPP_EXP_DEFN Scanner { + public: + Scanner(); + explicit Scanner(const std::string& input); + ~Scanner(); + + // Return current line number. The returned line-number is + // one-based. I.e. it returns 1 + the number of consumed newlines. + // + // Note: this method may be slow. It may take time proportional to + // the size of the input. + int LineNumber() const; + + // Return the byte-offset that the scanner is looking in the + // input data; + int Offset() const; + + // Return true iff the start of the remaining input matches "re" + bool LookingAt(const RE& re) const; + + // Return true iff all of the following are true + // a. the start of the remaining input matches "re", + // b. if any arguments are supplied, matched sub-patterns can be + // parsed and stored into the arguments. + // If it returns true, it skips over the matched input and any + // following input that matches the "skip" regular expression. + bool Consume(const RE& re, + const Arg& arg0 = RE::no_arg, + const Arg& arg1 = RE::no_arg, + const Arg& arg2 = RE::no_arg + // TODO: Allow more arguments? + ); + + // Set the "skip" regular expression. If after consuming some data, + // a prefix of the input matches this RE, it is automatically + // skipped. For example, a programming language scanner would use + // a skip RE that matches white space and comments. + // + // scanner.SetSkipExpression("\\s+|//.*|/[*](.|\n)*?[*]/"); + // + // Skipping repeats as long as it succeeds. We used to let people do + // this by writing "(...)*" in the regular expression, but that added + // up to lots of recursive calls within the pcre library, so now we + // control repetition explicitly via the function call API. + // + // You can pass NULL for "re" if you do not want any data to be skipped. + void Skip(const char* re); // DEPRECATED; does *not* repeat + void SetSkipExpression(const char* re); + + // Temporarily pause "skip"ing. This + // Skip("Foo"); code ; DisableSkip(); code; EnableSkip() + // is similar to + // Skip("Foo"); code ; Skip(NULL); code ; Skip("Foo"); + // but avoids creating/deleting new RE objects. + void DisableSkip(); + + // Reenable previously paused skipping. Any prefix of the input + // that matches the skip pattern is immediately dropped. + void EnableSkip(); + + /***** Special wrappers around SetSkip() for some common idioms *****/ + + // Arranges to skip whitespace, C comments, C++ comments. + // The overall RE is a disjunction of the following REs: + // \\s whitespace + // //.*\n C++ comment + // /[*](.|\n)*?[*]/ C comment (x*? means minimal repetitions of x) + // We get repetition via the semantics of SetSkipExpression, not by using * + void SkipCXXComments() { + SetSkipExpression("\\s|//.*\n|/[*](?:\n|.)*?[*]/"); + } + + void set_save_comments(bool comments) { + save_comments_ = comments; + } + + bool save_comments() { + return save_comments_; + } + + // Append to vector ranges the comments found in the + // byte range [start,end] (inclusive) of the input data. + // Only comments that were extracted entirely within that + // range are returned: no range splitting of atomically-extracted + // comments is performed. + void GetComments(int start, int end, std::vector *ranges); + + // Append to vector ranges the comments added + // since the last time this was called. This + // functionality is provided for efficiency when + // interleaving scanning with parsing. + void GetNextComments(std::vector *ranges); + + private: + std::string data_; // All the input data + StringPiece input_; // Unprocessed input + RE* skip_; // If non-NULL, RE for skipping input + bool should_skip_; // If true, use skip_ + bool skip_repeat_; // If true, repeat skip_ as long as it works + bool save_comments_; // If true, aggregate the skip expression + + // the skipped comments + // TODO: later consider requiring that the StringPieces be added + // in order by their start position + std::vector *comments_; + + // the offset into comments_ that has been returned by GetNextComments + int comments_offset_; + + // helper function to consume *skip_ and honour + // save_comments_ + void ConsumeSkip(); +}; + +} // namespace pcrecpp + +#endif /* _PCRE_SCANNER_H */ diff --git a/tools/pcre/pcre_scanner_unittest.cc b/tools/pcre/pcre_scanner_unittest.cc new file mode 100644 index 00000000..7de8d2e8 --- /dev/null +++ b/tools/pcre/pcre_scanner_unittest.cc @@ -0,0 +1,159 @@ +// Copyright (c) 2005, Google Inc. +// All rights reserved. +// +// 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 Google Inc. 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. +// +// Author: Greg J. Badros +// +// Unittest for scanner, especially GetNextComments and GetComments() +// functionality. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include /* for strchr */ +#include +#include + +#include "pcrecpp.h" +#include "pcre_stringpiece.h" +#include "pcre_scanner.h" + +#define FLAGS_unittest_stack_size 49152 + +// Dies with a fatal error if the two values are not equal. +#define CHECK_EQ(a, b) do { \ + if ( (a) != (b) ) { \ + fprintf(stderr, "%s:%d: Check failed because %s != %s\n", \ + __FILE__, __LINE__, #a, #b); \ + exit(1); \ + } \ +} while (0) + +using std::vector; +using pcrecpp::StringPiece; +using pcrecpp::Scanner; + +static void TestScanner() { + const char input[] = "\n" + "alpha = 1; // this sets alpha\n" + "bravo = 2; // bravo is set here\n" + "gamma = 33; /* and here is gamma */\n"; + + const char *re = "(\\w+) = (\\d+);"; + + Scanner s(input); + string var; + int number; + s.SkipCXXComments(); + s.set_save_comments(true); + vector comments; + + s.Consume(re, &var, &number); + CHECK_EQ(var, "alpha"); + CHECK_EQ(number, 1); + CHECK_EQ(s.LineNumber(), 3); + s.GetNextComments(&comments); + CHECK_EQ(comments.size(), 1); + CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); + comments.resize(0); + + s.Consume(re, &var, &number); + CHECK_EQ(var, "bravo"); + CHECK_EQ(number, 2); + s.GetNextComments(&comments); + CHECK_EQ(comments.size(), 1); + CHECK_EQ(comments[0].as_string(), " // bravo is set here\n"); + comments.resize(0); + + s.Consume(re, &var, &number); + CHECK_EQ(var, "gamma"); + CHECK_EQ(number, 33); + s.GetNextComments(&comments); + CHECK_EQ(comments.size(), 1); + CHECK_EQ(comments[0].as_string(), " /* and here is gamma */\n"); + comments.resize(0); + + s.GetComments(0, sizeof(input), &comments); + CHECK_EQ(comments.size(), 3); + CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); + CHECK_EQ(comments[1].as_string(), " // bravo is set here\n"); + CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n"); + comments.resize(0); + + s.GetComments(0, (int)(strchr(input, '/') - input), &comments); + CHECK_EQ(comments.size(), 0); + comments.resize(0); + + s.GetComments((int)(strchr(input, '/') - input - 1), sizeof(input), + &comments); + CHECK_EQ(comments.size(), 3); + CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); + CHECK_EQ(comments[1].as_string(), " // bravo is set here\n"); + CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n"); + comments.resize(0); + + s.GetComments((int)(strchr(input, '/') - input - 1), + (int)(strchr(input + 1, '\n') - input + 1), &comments); + CHECK_EQ(comments.size(), 1); + CHECK_EQ(comments[0].as_string(), " // this sets alpha\n"); + comments.resize(0); +} + +static void TestBigComment() { + string input; + for (int i = 0; i < 1024; ++i) { + char buf[1024]; // definitely big enough + sprintf(buf, " # Comment %d\n", i); + input += buf; + } + input += "name = value;\n"; + + Scanner s(input.c_str()); + s.SetSkipExpression("\\s+|#.*\n"); + + string name; + string value; + s.Consume("(\\w+) = (\\w+);", &name, &value); + CHECK_EQ(name, "name"); + CHECK_EQ(value, "value"); +} + +// TODO: also test scanner and big-comment in a thread with a +// small stack size + +int main(int argc, char** argv) { + TestScanner(); + TestBigComment(); + + // Done + printf("OK\n"); + + return 0; +} diff --git a/tools/pcre/pcre_string_utils.c b/tools/pcre/pcre_string_utils.c new file mode 100644 index 00000000..94a51260 --- /dev/null +++ b/tools/pcre/pcre_string_utils.c @@ -0,0 +1,211 @@ +/************************************************* +* 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; +} + +#ifdef COMPILE_PCRE32 + +int +PRIV(strcmp_uc_uc_utf)(const pcre_uchar *str1, const pcre_uchar *str2) +{ +pcre_uchar c1; +pcre_uchar c2; + +while (*str1 != '\0' || *str2 != '\0') + { + c1 = RAWUCHARINC(str1); + c2 = RAWUCHARINC(str2); + if (c1 != c2) + return ((c1 > c2) << 1) - 1; + } +/* Both length and characters must be equal. */ +return 0; +} + +#endif /* COMPILE_PCRE32 */ + +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; +} + +#ifdef COMPILE_PCRE32 + +int +PRIV(strcmp_uc_c8_utf)(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 = RAWUCHARINC(str1); + c2 = (pcre_uchar)*ustr2++; + if (c1 != c2) + return ((c1 > c2) << 1) - 1; + } +/* Both length and characters must be equal. */ +return 0; +} + +#endif /* COMPILE_PCRE32 */ + +/* 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 --git a/tools/pcre/pcre_stringpiece.cc b/tools/pcre/pcre_stringpiece.cc new file mode 100644 index 00000000..67c0f1fc --- /dev/null +++ b/tools/pcre/pcre_stringpiece.cc @@ -0,0 +1,43 @@ +// Copyright (c) 2005, Google Inc. +// All rights reserved. +// +// 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 Google Inc. 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. +// +// Author: wilsonh@google.com (Wilson Hsieh) +// + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "pcrecpp_internal.h" +#include "pcre_stringpiece.h" + +std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece) { + return (o << piece.as_string()); +} diff --git a/tools/pcre/pcre_stringpiece.h.in b/tools/pcre/pcre_stringpiece.h.in new file mode 100644 index 00000000..369c10f3 --- /dev/null +++ b/tools/pcre/pcre_stringpiece.h.in @@ -0,0 +1,179 @@ +// Copyright (c) 2005, Google Inc. +// All rights reserved. +// +// 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 Google Inc. 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. +// +// Author: Sanjay Ghemawat +// +// A string like object that points into another piece of memory. +// Useful for providing an interface that allows clients to easily +// pass in either a "const char*" or a "string". +// +// Arghh! I wish C++ literals were automatically of type "string". + +#ifndef _PCRE_STRINGPIECE_H +#define _PCRE_STRINGPIECE_H + +#include +#include +#include // for ostream forward-declaration + +#if @pcre_have_type_traits@ +#define HAVE_TYPE_TRAITS +#include +#elif @pcre_have_bits_type_traits@ +#define HAVE_TYPE_TRAITS +#include +#endif + +#include + +using std::memcmp; +using std::strlen; +using std::string; + +namespace pcrecpp { + +class PCRECPP_EXP_DEFN StringPiece { + private: + const char* ptr_; + int length_; + + public: + // We provide non-explicit singleton constructors so users can pass + // in a "const char*" or a "string" wherever a "StringPiece" is + // expected. + StringPiece() + : ptr_(NULL), length_(0) { } + StringPiece(const char* str) + : ptr_(str), length_(static_cast(strlen(ptr_))) { } + StringPiece(const unsigned char* str) + : ptr_(reinterpret_cast(str)), + length_(static_cast(strlen(ptr_))) { } + StringPiece(const string& str) + : ptr_(str.data()), length_(static_cast(str.size())) { } + StringPiece(const char* offset, int len) + : ptr_(offset), length_(len) { } + + // data() may return a pointer to a buffer with embedded NULs, and the + // returned buffer may or may not be null terminated. Therefore it is + // typically a mistake to pass data() to a routine that expects a NUL + // terminated string. Use "as_string().c_str()" if you really need to do + // this. Or better yet, change your routine so it does not rely on NUL + // termination. + const char* data() const { return ptr_; } + int size() const { return length_; } + bool empty() const { return length_ == 0; } + + void clear() { ptr_ = NULL; length_ = 0; } + void set(const char* buffer, int len) { ptr_ = buffer; length_ = len; } + void set(const char* str) { + ptr_ = str; + length_ = static_cast(strlen(str)); + } + void set(const void* buffer, int len) { + ptr_ = reinterpret_cast(buffer); + length_ = len; + } + + char operator[](int i) const { return ptr_[i]; } + + void remove_prefix(int n) { + ptr_ += n; + length_ -= n; + } + + void remove_suffix(int n) { + length_ -= n; + } + + bool operator==(const StringPiece& x) const { + return ((length_ == x.length_) && + (memcmp(ptr_, x.ptr_, length_) == 0)); + } + bool operator!=(const StringPiece& x) const { + return !(*this == x); + } + +#define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp) \ + bool operator cmp (const StringPiece& x) const { \ + int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \ + return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_))); \ + } + STRINGPIECE_BINARY_PREDICATE(<, <); + STRINGPIECE_BINARY_PREDICATE(<=, <); + STRINGPIECE_BINARY_PREDICATE(>=, >); + STRINGPIECE_BINARY_PREDICATE(>, >); +#undef STRINGPIECE_BINARY_PREDICATE + + int compare(const StringPiece& x) const { + int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); + if (r == 0) { + if (length_ < x.length_) r = -1; + else if (length_ > x.length_) r = +1; + } + return r; + } + + string as_string() const { + return string(data(), size()); + } + + void CopyToString(string* target) const { + target->assign(ptr_, length_); + } + + // Does "this" start with "x" + bool starts_with(const StringPiece& x) const { + return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0)); + } +}; + +} // namespace pcrecpp + +// ------------------------------------------------------------------ +// Functions used to create STL containers that use StringPiece +// Remember that a StringPiece's lifetime had better be less than +// that of the underlying string or char*. If it is not, then you +// cannot safely store a StringPiece into an STL container +// ------------------------------------------------------------------ + +#ifdef HAVE_TYPE_TRAITS +// This makes vector really fast for some STL implementations +template<> struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; +#endif + +// allow StringPiece to be logged +std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece); + +#endif /* _PCRE_STRINGPIECE_H */ diff --git a/tools/pcre/pcre_stringpiece_unittest.cc b/tools/pcre/pcre_stringpiece_unittest.cc new file mode 100644 index 00000000..c58e028c --- /dev/null +++ b/tools/pcre/pcre_stringpiece_unittest.cc @@ -0,0 +1,150 @@ +// Copyright 2003 and onwards Google Inc. +// Author: Sanjay Ghemawat + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include // for make_pair + +#include "pcrecpp.h" +#include "pcre_stringpiece.h" + +// CHECK dies with a fatal error if condition is not true. It is *not* +// controlled by NDEBUG, so the check will be executed regardless of +// compilation mode. Therefore, it is safe to do things like: +// CHECK(fp->Write(x) == 4) +#define CHECK(condition) do { \ + if (!(condition)) { \ + fprintf(stderr, "%s:%d: Check failed: %s\n", \ + __FILE__, __LINE__, #condition); \ + exit(1); \ + } \ +} while (0) + +using pcrecpp::StringPiece; + +static void CheckSTLComparator() { + string s1("foo"); + string s2("bar"); + string s3("baz"); + + StringPiece p1(s1); + StringPiece p2(s2); + StringPiece p3(s3); + + typedef std::map TestMap; + TestMap map; + + map.insert(std::make_pair(p1, 0)); + map.insert(std::make_pair(p2, 1)); + map.insert(std::make_pair(p3, 2)); + + CHECK(map.size() == 3); + + TestMap::const_iterator iter = map.begin(); + CHECK(iter->second == 1); + ++iter; + CHECK(iter->second == 2); + ++iter; + CHECK(iter->second == 0); + ++iter; + CHECK(iter == map.end()); + + TestMap::iterator new_iter = map.find("zot"); + CHECK(new_iter == map.end()); + + new_iter = map.find("bar"); + CHECK(new_iter != map.end()); + + map.erase(new_iter); + CHECK(map.size() == 2); + + iter = map.begin(); + CHECK(iter->second == 2); + ++iter; + CHECK(iter->second == 0); + ++iter; + CHECK(iter == map.end()); +} + +static void CheckComparisonOperators() { +#define CMP_Y(op, x, y) \ + CHECK( (StringPiece((x)) op StringPiece((y)))); \ + CHECK( (StringPiece((x)).compare(StringPiece((y))) op 0)) + +#define CMP_N(op, x, y) \ + CHECK(!(StringPiece((x)) op StringPiece((y)))); \ + CHECK(!(StringPiece((x)).compare(StringPiece((y))) op 0)) + + CMP_Y(==, "", ""); + CMP_Y(==, "a", "a"); + CMP_Y(==, "aa", "aa"); + CMP_N(==, "a", ""); + CMP_N(==, "", "a"); + CMP_N(==, "a", "b"); + CMP_N(==, "a", "aa"); + CMP_N(==, "aa", "a"); + + CMP_N(!=, "", ""); + CMP_N(!=, "a", "a"); + CMP_N(!=, "aa", "aa"); + CMP_Y(!=, "a", ""); + CMP_Y(!=, "", "a"); + CMP_Y(!=, "a", "b"); + CMP_Y(!=, "a", "aa"); + CMP_Y(!=, "aa", "a"); + + CMP_Y(<, "a", "b"); + CMP_Y(<, "a", "aa"); + CMP_Y(<, "aa", "b"); + CMP_Y(<, "aa", "bb"); + CMP_N(<, "a", "a"); + CMP_N(<, "b", "a"); + CMP_N(<, "aa", "a"); + CMP_N(<, "b", "aa"); + CMP_N(<, "bb", "aa"); + + CMP_Y(<=, "a", "a"); + CMP_Y(<=, "a", "b"); + CMP_Y(<=, "a", "aa"); + CMP_Y(<=, "aa", "b"); + CMP_Y(<=, "aa", "bb"); + CMP_N(<=, "b", "a"); + CMP_N(<=, "aa", "a"); + CMP_N(<=, "b", "aa"); + CMP_N(<=, "bb", "aa"); + + CMP_N(>=, "a", "b"); + CMP_N(>=, "a", "aa"); + CMP_N(>=, "aa", "b"); + CMP_N(>=, "aa", "bb"); + CMP_Y(>=, "a", "a"); + CMP_Y(>=, "b", "a"); + CMP_Y(>=, "aa", "a"); + CMP_Y(>=, "b", "aa"); + CMP_Y(>=, "bb", "aa"); + + CMP_N(>, "a", "a"); + CMP_N(>, "a", "b"); + CMP_N(>, "a", "aa"); + CMP_N(>, "aa", "b"); + CMP_N(>, "aa", "bb"); + CMP_Y(>, "b", "a"); + CMP_Y(>, "aa", "a"); + CMP_Y(>, "b", "aa"); + CMP_Y(>, "bb", "aa"); + +#undef CMP_Y +#undef CMP_N +} + +int main(int argc, char** argv) { + CheckComparisonOperators(); + CheckSTLComparator(); + + printf("OK\n"); + return 0; +} diff --git a/tools/pcre/pcre_study.c b/tools/pcre/pcre_study.c new file mode 100644 index 00000000..12d2a668 --- /dev/null +++ b/tools/pcre/pcre_study.c @@ -0,0 +1,1562 @@ +/************************************************* +* 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 the external function pcre_study(), along with local +supporting functions. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + +#define SET_BIT(c) start_bits[c/8] |= (1 << (c&7)) + +/* Returns from set_start_bits() */ + +enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN }; + + + +/************************************************* +* Find the minimum subject length for a group * +*************************************************/ + +/* Scan a parenthesized group and compute the minimum length of subject that +is needed to match it. This is a lower bound; it does not mean there is a +string of that length that matches. In UTF8 mode, the result is in characters +rather than bytes. + +Arguments: + code pointer to start of group (the bracket) + startcode pointer to start of the whole pattern + options the compiling options + int RECURSE depth + +Returns: the minimum length + -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 pcre_uchar *code, const pcre_uchar *startcode, int options, + int recurse_depth) +{ +int length = -1; +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +BOOL utf = (options & PCRE_UTF8) != 0; +BOOL had_recurse = FALSE; +register int branchlength = 0; +register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE; + +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. */ + +for (;;) + { + int d, min; + pcre_uchar *cs, *ce; + register pcre_uchar op = *cc; + + switch (op) + { + case OP_COND: + case OP_SCOND: + + /* If there is only one branch in a condition, the implied branch has zero + length, so we don't add anything. This covers the DEFINE "condition" + automatically. */ + + cs = cc + GET(cc, 1); + if (*cs != OP_ALT) + { + cc = cs + 1 + LINK_SIZE; + break; + } + + /* Otherwise we can fall through and treat it the same as any other + subpattern. */ + + case OP_CBRA: + case OP_SCBRA: + case OP_BRA: + case OP_SBRA: + case OP_CBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOS: + case OP_SBRAPOS: + case OP_ONCE: + 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. 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 (op != OP_ALT) return length; + cc += 1 + LINK_SIZE; + branchlength = 0; + had_recurse = FALSE; + break; + + /* Skip over assertive subpatterns */ + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + do cc += GET(cc, 1); while (*cc == OP_ALT); + /* Fall through */ + + /* Skip over things that don't match chars */ + + case OP_REVERSE: + case OP_CREF: + case OP_NCREF: + case OP_RREF: + case OP_NRREF: + case OP_DEF: + case OP_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 += 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 += PRIV(OP_lengths)[*cc]; + do cc += GET(cc, 1); while (*cc == OP_ALT); + cc += 1 + LINK_SIZE; + break; + + /* Handle literal characters and + repetitions */ + + case OP_CHAR: + 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_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSPLUS: + branchlength++; + cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2; + break; + + /* Handle exact repetitions. The count is already in characters, but we + 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 += 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 += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP + || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); + break; + + /* Handle single-char non-literal matchers */ + + case OP_PROP: + case OP_NOTPROP: + cc += 2; + /* Fall through */ + + 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_EXTUNI: + case OP_HSPACE: + case OP_NOT_HSPACE: + case OP_VSPACE: + case OP_NOT_VSPACE: + branchlength++; + cc++; + break; + + /* "Any newline" might match two characters, but it also might match just + one. */ + + case OP_ANYNL: + branchlength += 1; + cc++; + break; + + /* 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_UTF + if (utf) return -1; +#endif + branchlength++; + cc++; + break; + + /* For repeated character types, we have to test for \p and \P, which have + an extra two bytes of parameters. */ + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSQUERY: + if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2; + cc += PRIV(OP_lengths)[op]; + break; + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEPOSUPTO: + 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 */ + + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + case OP_XCLASS: + /* The original code caused an unsigned overflow in 64 bit systems, + so now we use a conditional statement. */ + if (op == OP_XCLASS) + cc += GET(cc, 1); + else + cc += PRIV(OP_lengths)[OP_CLASS]; +#else + cc += PRIV(OP_lengths)[OP_CLASS]; +#endif + + switch (*cc) + { + case OP_CRPLUS: + case OP_CRMINPLUS: + branchlength++; + /* Fall through */ + + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + cc++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + branchlength += GET2(cc,1); + cc += 1 + 2 * IMM2_SIZE; + break; + + default: + branchlength++; + break; + } + break; + + /* Backreferences and subroutine calls are treated in the same way: we find + the minimum length for the subpattern. A recursion, however, causes an + a flag to be set that causes the length of this branch to be ignored. The + logic is that a recursion can only make sense if there is another + alternation that stops the recursing. That will provide the minimum length + (when no recursion happens). A backreference within the group that it is + referencing behaves in the same way. + + If PCRE_JAVASCRIPT_COMPAT is set, a backreference to an unset bracket + matches an empty string (by default it causes a matching failure), so in + that case we must set the minimum length to zero. */ + + case OP_REF: + case OP_REFI: + if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) + { + 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) + { + d = 0; + had_recurse = TRUE; + } + else + { + d = find_minlength(cs, startcode, options, recurse_depth); + } + } + else d = 0; + cc += 1 + IMM2_SIZE; + + /* Handle repeated back references */ + + switch (*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + min = 0; + cc++; + break; + + case OP_CRPLUS: + case OP_CRMINPLUS: + min = 1; + cc++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + min = GET2(cc, 1); + cc += 1 + 2 * IMM2_SIZE; + break; + + default: + min = 1; + break; + } + + 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 = (pcre_uchar *)startcode + GET(cc, 1); + do ce += GET(ce, 1); while (*ce == OP_ALT); + if ((cc > cs && cc < ce) || recurse_depth > 10) + had_recurse = TRUE; + else + { + 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. As it + happens, the "NOT" versions of these opcodes are used at present only for + ASCII characters, so they could be omitted from this list. However, in + future that may change, so we include them here so as not to leave a + gotcha for a future maintainer. */ + + case OP_UPTO: + case OP_UPTOI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_MINUPTO: + case OP_MINUPTOI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_POSUPTO: + case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + + case OP_STAR: + case OP_STARI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_MINSTAR: + case OP_MINSTARI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_POSSTAR: + case OP_POSSTARI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + + case OP_QUERY: + case OP_QUERYI: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_MINQUERY: + case OP_MINQUERYI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_POSQUERY: + case OP_POSQUERYI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + + cc += PRIV(OP_lengths)[op]; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + break; + + /* Skip these, but we need to add in the name length. */ + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + cc += PRIV(OP_lengths)[op] + cc[1]; + break; + + /* The remaining opcodes are just skipped over. */ + + case OP_CLOSE: + case OP_COMMIT: + case OP_FAIL: + case OP_PRUNE: + case OP_SET_SOM: + case OP_SKIP: + case OP_THEN: + cc += PRIV(OP_lengths)[op]; + break; + + /* This should not occur: we list all opcodes explicitly so that when + new ones get added they are properly considered. */ + + default: + return -3; + } + } +/* Control never gets here */ +} + + + +/************************************************* +* Set a bit and maybe its alternate case * +*************************************************/ + +/* Given a character, set its first byte's bit in the table, and also the +corresponding bit for the other version of a letter if we are caseless. In +UTF-8 mode, for characters greater than 127, we can only do the caseless thing +when Unicode property support is available. + +Arguments: + start_bits points to the bit map + p points to the character + caseless the caseless flag + cd the block with char table pointers + utf TRUE for UTF-8 / UTF-16 / UTF-32 mode + +Returns: pointer after the character +*/ + +static const pcre_uchar * +set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless, + compile_data *cd, BOOL utf) +{ +pcre_uint32 c = *p; + +#ifdef COMPILE_PCRE8 +SET_BIT(c); + +#ifdef SUPPORT_UTF +if (utf && c > 127) + { + GETCHARINC(c, p); +#ifdef SUPPORT_UCP + if (caseless) + { + pcre_uchar buff[6]; + c = UCD_OTHERCASE(c); + (void)PRIV(ord2utf)(c, buff); + SET_BIT(buff[0]); + } +#endif /* Not SUPPORT_UCP */ + return p; + } +#else /* Not SUPPORT_UTF */ +(void)(utf); /* Stops warning for unused parameter */ +#endif /* SUPPORT_UTF */ + +/* Not UTF-8 mode, or character is less than 127. */ + +if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]); +return p + 1; +#endif /* COMPILE_PCRE8 */ + +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +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 /* SUPPORT_UCP */ + return p; + } +#else /* Not SUPPORT_UTF */ +(void)(utf); /* Stops warning for unused parameter */ +#endif /* SUPPORT_UTF */ + +if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]); +return p + 1; +#endif +} + + + +/************************************************* +* Set bits for a positive character type * +*************************************************/ + +/* This function sets starting bits for a character type. In UTF-8 mode, we can +only do a direct setting for bytes less than 128, as otherwise there can be +confusion with bytes in the middle of UTF-8 characters. In a "traditional" +environment, the tables will only recognize ASCII characters anyway, but in at +least one Windows environment, some higher bytes bits were set in the tables. +So we deal with that case by considering the UTF-8 encoding. + +Arguments: + start_bits the starting bitmap + cbit type the type of character wanted + table_limit 32 for non-UTF-8; 16 for UTF-8 + cd the block with char table pointers + +Returns: nothing +*/ + +static void +set_type_bits(pcre_uint8 *start_bits, int cbit_type, unsigned int table_limit, + compile_data *cd) +{ +register pcre_uint32 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) + { + pcre_uchar buff[6]; + (void)PRIV(ord2utf)(c, buff); + SET_BIT(buff[0]); + } + } +#endif +} + + +/************************************************* +* Set bits for a negative character type * +*************************************************/ + +/* This function sets starting bits for a negative character type such as \D. +In UTF-8 mode, we can only do a direct setting for bytes less than 128, as +otherwise there can be confusion with bytes in the middle of UTF-8 characters. +Unlike in the positive case, where we can set appropriate starting bits for +specific high-valued UTF-8 characters, in this case we have to set the bits for +all high-valued characters. The lowest is 0xc2, but we overkill by starting at +0xc0 (192) for simplicity. + +Arguments: + start_bits the starting bitmap + cbit type the type of character wanted + table_limit 32 for non-UTF-8; 16 for UTF-8 + cd the block with char table pointers + +Returns: nothing +*/ + +static void +set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, unsigned int table_limit, + compile_data *cd) +{ +register pcre_uint32 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 +} + + + +/************************************************* +* Create bitmap of starting bytes * +*************************************************/ + +/* This function scans a compiled unanchored expression recursively and +attempts to build a bitmap of the set of possible starting bytes. As time goes +by, we may be able to get more clever at doing this. The SSB_CONTINUE return is +useful for parenthesized groups in patterns such as (a*)b where the group +provides some optional starting bytes but scanning must continue at the outer +level to find at least one mandatory byte. At the outermost level, this +function fails unless the result is SSB_DONE. + +Arguments: + code points to an expression + start_bits points to a 32-byte table, initialized to 0 + utf TRUE if in UTF-8 / UTF-16 / UTF-32 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 pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf, + compile_data *cd) +{ +register pcre_uint32 c; +int yield = SSB_DONE; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +int table_limit = utf? 16:32; +#else +int table_limit = 32; +#endif + +#if 0 +/* ========================================================================= */ +/* The following comment and code was inserted in January 1999. In May 2006, +when it was observed to cause compiler warnings about unused values, I took it +out again. If anybody is still using OS/2, they will have to put it back +manually. */ + +/* This next statement and the later reference to dummy are here in order to +trick the optimizer of the IBM C compiler for OS/2 into generating correct +code. Apparently IBM isn't going to fix the problem, and we would rather not +disable optimization (in this module it actually makes a big difference, and +the pcre module can use all the optimization it can get). */ + +volatile int dummy; +/* ========================================================================= */ +#endif + +do + { + 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) + { + /* 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 + branch. Otherwise, carry on scanning after the subpattern. */ + + case OP_BRA: + 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, 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); + tcode += 1 + LINK_SIZE; + } + break; + + /* If we hit ALT or KET, it means we haven't found anything mandatory in + this branch, though we might have found something optional. For ALT, we + continue with the next alternative, but we have to arrange that the final + result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET, + return SSB_CONTINUE: if this is the top level, that indicates failure, + but after a nested subpattern, it causes scanning to continue. */ + + case OP_ALT: + yield = SSB_CONTINUE; + try_next = FALSE; + break; + + case OP_KET: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + return SSB_CONTINUE; + + /* Skip over callout */ + + case OP_CALLOUT: + tcode += 2 + 2*LINK_SIZE; + break; + + /* Skip over lookbehind and negative lookahead assertions */ + + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + do tcode += GET(tcode, 1); while (*tcode == OP_ALT); + tcode += 1 + LINK_SIZE; + break; + + /* BRAZERO does the bracket, but carries on. */ + + case OP_BRAZERO: + case OP_BRAMINZERO: + 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. + dummy = 1; + ========================================================================= */ + do tcode += GET(tcode,1); while (*tcode == OP_ALT); + tcode += 1 + LINK_SIZE; + break; + + /* SKIPZERO skips the bracket. */ + + case OP_SKIPZERO: + tcode++; + do tcode += GET(tcode,1); while (*tcode == OP_ALT); + tcode += 1 + LINK_SIZE; + break; + + /* Single-char * or ? sets the bit and tries the next item */ + + case OP_STAR: + case OP_MINSTAR: + case OP_POSSTAR: + case OP_QUERY: + case OP_MINQUERY: + case OP_POSQUERY: + 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 */ + + case OP_UPTO: + case OP_MINUPTO: + case OP_POSUPTO: + tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, FALSE, cd, utf); + break; + + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, TRUE, cd, utf); + break; + + /* At least one single char sets the bit and stops */ + + case OP_EXACT: + tcode += IMM2_SIZE; + /* Fall through */ + case OP_CHAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_POSPLUS: + (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; + + /* Special spacing and line-terminating items. These recognize specific + lists of characters. The difference between VSPACE and ANYNL is that the + latter can match the two-character CRLF sequence, but that is not + relevant for finding the first character, so their code here is + identical. */ + + case OP_HSPACE: + SET_BIT(CHAR_HT); + SET_BIT(CHAR_SPACE); +#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 */ +#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + SET_BIT(0xA0); + SET_BIT(0xFF); /* For characters > 255 */ +#endif /* COMPILE_PCRE[8|16|32] */ + } + else +#endif /* SUPPORT_UTF */ + { +#ifndef EBCDIC + SET_BIT(0xA0); +#endif /* Not EBCDIC */ +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + SET_BIT(0xFF); /* For characters > 255 */ +#endif /* COMPILE_PCRE[16|32] */ + } + try_next = FALSE; + break; + + case OP_ANYNL: + case OP_VSPACE: + SET_BIT(CHAR_LF); + SET_BIT(CHAR_VT); + SET_BIT(CHAR_FF); + SET_BIT(CHAR_CR); +#ifdef SUPPORT_UTF + if (utf) + { +#ifdef COMPILE_PCRE8 + SET_BIT(0xC2); /* For U+0085 */ + SET_BIT(0xE2); /* For U+2028, U+2029 */ +#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + SET_BIT(CHAR_NEL); + SET_BIT(0xFF); /* For characters > 255 */ +#endif /* COMPILE_PCRE[8|16|32] */ + } + else +#endif /* SUPPORT_UTF */ + { + SET_BIT(CHAR_NEL); +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + SET_BIT(0xFF); /* For characters > 255 */ +#endif + } + try_next = FALSE; + break; + + /* Single character types set the bits and stop. Note that if PCRE_UCP + is set, we do not see these op codes because \d etc are converted to + properties. Therefore, these apply in the case when only characters less + than 256 are recognized to match the types. */ + + case OP_NOT_DIGIT: + set_nottype_bits(start_bits, cbit_digit, table_limit, cd); + try_next = FALSE; + break; + + case OP_DIGIT: + set_type_bits(start_bits, cbit_digit, table_limit, cd); + try_next = FALSE; + break; + + /* The cbit_space table has vertical tab as whitespace; we have to + ensure it is set as not whitespace. Luckily, the code value is the same + (0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate bit. */ + + case OP_NOT_WHITESPACE: + set_nottype_bits(start_bits, cbit_space, table_limit, cd); + start_bits[1] |= 0x08; + try_next = FALSE; + break; + + /* The cbit_space table has vertical tab as whitespace; we have to not + set it from the table. Luckily, the code value is the same (0x0b) in + ASCII and EBCDIC, so we can just adjust the appropriate bit. */ + + case OP_WHITESPACE: + c = start_bits[1]; /* Save in case it was already set */ + set_type_bits(start_bits, cbit_space, table_limit, cd); + start_bits[1] = (start_bits[1] & ~0x08) | c; + try_next = FALSE; + break; + + case OP_NOT_WORDCHAR: + set_nottype_bits(start_bits, cbit_word, table_limit, cd); + try_next = FALSE; + break; + + case OP_WORDCHAR: + set_type_bits(start_bits, cbit_word, table_limit, cd); + try_next = FALSE; + break; + + /* One or more character type fudges the pointer and restarts, knowing + it will hit a single character type and stop there. */ + + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSPLUS: + tcode++; + break; + + case OP_TYPEEXACT: + tcode += 1 + IMM2_SIZE; + break; + + /* Zero or more repeats of character types set the bits and then + try again. */ + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEPOSUPTO: + tcode += IMM2_SIZE; /* Fall through */ + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPOSSTAR: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSQUERY: + switch(tcode[1]) + { + default: + case OP_ANY: + case OP_ALLANY: + return SSB_FAIL; + + case OP_HSPACE: + SET_BIT(CHAR_HT); + SET_BIT(CHAR_SPACE); +#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 */ +#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + SET_BIT(0xA0); + SET_BIT(0xFF); /* For characters > 255 */ +#endif /* COMPILE_PCRE[8|16|32] */ + } + else +#endif /* SUPPORT_UTF */ +#ifndef EBCDIC + SET_BIT(0xA0); +#endif /* Not EBCDIC */ + break; + + case OP_ANYNL: + case OP_VSPACE: + SET_BIT(CHAR_LF); + SET_BIT(CHAR_VT); + SET_BIT(CHAR_FF); + SET_BIT(CHAR_CR); +#ifdef SUPPORT_UTF + if (utf) + { +#ifdef COMPILE_PCRE8 + SET_BIT(0xC2); /* For U+0085 */ + SET_BIT(0xE2); /* For U+2028, U+2029 */ +#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + SET_BIT(CHAR_NEL); + SET_BIT(0xFF); /* For characters > 255 */ +#endif /* COMPILE_PCRE16 */ + } + else +#endif /* SUPPORT_UTF */ + SET_BIT(CHAR_NEL); + break; + + case OP_NOT_DIGIT: + set_nottype_bits(start_bits, cbit_digit, table_limit, cd); + break; + + case OP_DIGIT: + set_type_bits(start_bits, cbit_digit, table_limit, cd); + break; + + /* The cbit_space table has vertical tab as whitespace; we have to + ensure it gets set as not whitespace. Luckily, the code value is the + same (0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate + bit. */ + + case OP_NOT_WHITESPACE: + set_nottype_bits(start_bits, cbit_space, table_limit, cd); + start_bits[1] |= 0x08; + break; + + /* The cbit_space table has vertical tab as whitespace; we have to + avoid setting it. Luckily, the code value is the same (0x0b) in ASCII + and EBCDIC, so we can just adjust the appropriate bit. */ + + case OP_WHITESPACE: + c = start_bits[1]; /* Save in case it was already set */ + set_type_bits(start_bits, cbit_space, table_limit, cd); + start_bits[1] = (start_bits[1] & ~0x08) | c; + break; + + case OP_NOT_WORDCHAR: + set_nottype_bits(start_bits, cbit_word, table_limit, cd); + break; + + case OP_WORDCHAR: + set_type_bits(start_bits, cbit_word, table_limit, cd); + break; + } + + tcode += 2; + break; + + /* Character class where all the information is in a bit map: set the + bits and either carry on or not, according to the repeat count. If it was + a negative class, and we are operating with UTF-8 characters, any byte + with a value >= 0xc4 is a potentially valid starter because it starts a + character with a value > 255. */ + + case OP_NCLASS: +#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 +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + 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 + for byte values. So we have to do a conversion for characters whose + value is > 127. In fact, there are only two possible starting bytes for + characters in the range 128 - 255. */ + +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (utf) + { + for (c = 0; c < 16; c++) start_bits[c] |= map[c]; + for (c = 128; c < 256; c++) + { + 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 */ + c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ + } + } + } + else +#endif + { + /* 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. For a zero + minimum repeat, continue; otherwise stop processing. */ + + tcode += 32 / sizeof(pcre_uchar); + switch (*tcode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + tcode++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE; + else try_next = FALSE; + break; + + default: + try_next = FALSE; + break; + } + } + break; /* End of bitmap class handling */ + + } /* End of switch */ + } /* End of try_next loop */ + + code += GET(code, 1); /* Advance to next branch */ + } +while (*code == OP_ALT); +return yield; +} + + + + + +/************************************************* +* Study a compiled expression * +*************************************************/ + +/* This function is handed a compiled expression that it must study to produce +information that will speed up the matching. It returns a pcre[16]_extra block +which then gets handed back to pcre_exec(). + +Arguments: + re points to the compiled expression + options contains option bits + errorptr points to where to place error messages; + set NULL unless error + +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 +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION +pcre_study(const pcre *external_re, int options, const char **errorptr) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION +pcre16_study(const pcre16 *external_re, int options, const char **errorptr) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN pcre32_extra * PCRE_CALL_CONVENTION +pcre32_study(const pcre32 *external_re, int options, const char **errorptr) +#endif +{ +int min; +BOOL bits_set = FALSE; +pcre_uint8 start_bits[32]; +PUBL(extra) *extra = NULL; +pcre_study_data *study; +const pcre_uint8 *tables; +pcre_uchar *code; +compile_data compile_block; +const REAL_PCRE *re = (const REAL_PCRE *)external_re; + +*errorptr = NULL; + +if (re == NULL || re->magic_number != MAGIC_NUMBER) + { + *errorptr = "argument is not a compiled regular expression"; + return NULL; + } + +if ((re->flags & PCRE_MODE) == 0) + { +#if defined COMPILE_PCRE8 + *errorptr = "argument not compiled in 8 bit mode"; +#elif defined COMPILE_PCRE16 + *errorptr = "argument not compiled in 16 bit mode"; +#elif defined COMPILE_PCRE32 + *errorptr = "argument not compiled in 32 bit mode"; +#endif + return NULL; + } + +if ((options & ~PUBLIC_STUDY_OPTIONS) != 0) + { + *errorptr = "unknown or incorrect option bit(s) set"; + return NULL; + } + +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 +a multiline pattern that matches only at "line starts", there is no point in +seeking a list of starting bytes. */ + +if ((re->options & PCRE_ANCHORED) == 0 && + (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0) + { + int rc; + + /* Set the character tables in the block that is passed around */ + + tables = re->tables; + +#if defined COMPILE_PCRE8 + if (tables == NULL) + (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, + (void *)(&tables)); +#elif defined COMPILE_PCRE16 + if (tables == NULL) + (void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, + (void *)(&tables)); +#elif defined COMPILE_PCRE32 + if (tables == NULL) + (void)pcre32_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, + (void *)(&tables)); +#endif + + compile_block.lcc = tables + lcc_offset; + compile_block.fcc = tables + fcc_offset; + compile_block.cbits = tables + cbits_offset; + compile_block.ctypes = tables + ctypes_offset; + + /* See if we can find a fixed set of initial characters for the pattern. */ + + 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. */ + +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; + } + +/* 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, or if +PCRE_STUDY_EXTRA_NEEDED is set, 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 || (options & ( +#ifdef SUPPORT_JIT + PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE | + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE | +#endif + PCRE_STUDY_EXTRA_NEEDED)) != 0) + { + extra = (PUBL(extra) *)(PUBL(malloc)) + (sizeof(PUBL(extra)) + sizeof(pcre_study_data)); + if (extra == NULL) + { + *errorptr = "failed to get memory"; + 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. */ + + if (bits_set) + { + study->flags |= PCRE_STUDY_MAPPED; + memcpy(study->start_bits, start_bits, sizeof(start_bits)); + } + else memset(study->start_bits, 0, 32 * sizeof(pcre_uint8)); + +#ifdef PCRE_DEBUG + if (bits_set) + { + pcre_uint8 *ptr = start_bits; + int i; + + printf("Start bits:\n"); + for (i = 0; i < 32; i++) + printf("%3d: %02x%s", i * 8, *ptr++, ((i + 1) & 0x7) != 0? " " : "\n"); + } +#endif + + /* Always set the minlength value in the block, because the JIT compiler + makes use of it. However, don't set the bit unless the length is greater than + zero - the interpretive pcre_exec() and pcre_dfa_exec() needn't waste time + checking the zero case. */ + + if (min > 0) + { + study->flags |= PCRE_STUDY_MINLEN; + study->minlength = min; + } + else study->minlength = 0; + + /* If JIT support was compiled and requested, attempt the JIT compilation. + If no starting bytes were found, and the minimum length is zero, and JIT + compilation fails, abandon the extra block and return NULL, unless + PCRE_STUDY_EXTRA_NEEDED is set. */ + +#ifdef SUPPORT_JIT + extra->executable_jit = NULL; + if ((options & PCRE_STUDY_JIT_COMPILE) != 0) + PRIV(jit_compile)(re, extra, JIT_COMPILE); + if ((options & PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE) != 0) + PRIV(jit_compile)(re, extra, JIT_PARTIAL_SOFT_COMPILE); + if ((options & PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) != 0) + PRIV(jit_compile)(re, extra, JIT_PARTIAL_HARD_COMPILE); + + if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0 && + (options & PCRE_STUDY_EXTRA_NEEDED) == 0) + { +#if defined COMPILE_PCRE8 + pcre_free_study(extra); +#elif defined COMPILE_PCRE16 + pcre16_free_study(extra); +#elif defined COMPILE_PCRE32 + pcre32_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 +*/ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN void +pcre_free_study(pcre_extra *extra) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN void +pcre16_free_study(pcre16_extra *extra) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN void +pcre32_free_study(pcre32_extra *extra) +#endif +{ +if (extra == NULL) + return; +#ifdef SUPPORT_JIT +if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && + extra->executable_jit != NULL) + PRIV(jit_free)(extra->executable_jit); +#endif +PUBL(free)(extra); +} + +/* End of pcre_study.c */ diff --git a/tools/pcre/pcre_tables.c b/tools/pcre/pcre_tables.c new file mode 100644 index 00000000..34ee0488 --- /dev/null +++ b/tools/pcre/pcre_tables.c @@ -0,0 +1,655 @@ +/************************************************* +* 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. +----------------------------------------------------------------------------- +*/ + +#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 +uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name +clashes with the library. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#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 pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS }; + +/* Tables of horizontal and vertical whitespace characters, suitable for +adding to classes. */ + +const pcre_uint32 PRIV(hspace_list)[] = { HSPACE_LIST }; +const pcre_uint32 PRIV(vspace_list)[] = { VSPACE_LIST }; + + + +/************************************************* +* Tables for UTF-8 support * +*************************************************/ + +/* These are the breakpoints for different numbers of bytes in a UTF-8 +character. */ + +#if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \ + || (defined PCRE_INCLUDED && (defined SUPPORT_PCRE16 || defined SUPPORT_PCRE32)) + +/* These tables are also required by pcretest in 16- or 32-bit mode. */ + +const int PRIV(utf8_table1)[] = + { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; + +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 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 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_PCRE[16|32])*/ + +#ifdef SUPPORT_UTF + +/* Table to translate from particular type value to the general value. */ + +const pcre_uint32 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 */ + ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */ + ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */ + ucp_P, ucp_P, /* Ps, Po */ + ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */ + ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */ +}; + +/* This table encodes the rules for finding the end of an extended grapheme +cluster. Every code point has a grapheme break property which is one of the +ucp_gbXX values defined in ucp.h. The 2-dimensional table is indexed by the +properties of two adjacent code points. The left property selects a word from +the table, and the right property selects a bit from that word like this: + + ucp_gbtable[left-property] & (1 << right-property) + +The value is non-zero if a grapheme break is NOT permitted between the relevant +two code points. The breaking rules are as follows: + +1. Break at the start and end of text (pretty obviously). + +2. Do not break between a CR and LF; otherwise, break before and after + controls. + +3. Do not break Hangul syllable sequences, the rules for which are: + + L may be followed by L, V, LV or LVT + LV or V may be followed by V or T + LVT or T may be followed by T + +4. Do not break before extending characters. + +The next two rules are only for extended grapheme clusters (but that's what we +are implementing). + +5. Do not break before SpacingMarks. + +6. Do not break after Prepend characters. + +7. Otherwise, break everywhere. +*/ + +const pcre_uint32 PRIV(ucp_gbtable[]) = { + (1< 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 +PCRE_UTF8_ERR22 Non-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-8 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; + +if (length < 0) + { + for (p = string; *p != 0; p++); + length = (int)(p - string); + } + +for (p = string; length-- > 0; p++) + { + register pcre_uchar ab, c, d; + pcre_uint32 v = 0; + + 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 (((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) + { + /* 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) + { + *erroroffset = (int)(p - string) - 1; + return PCRE_UTF8_ERR15; + } + break; + + /* 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 ((*(++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; + } + v = ((c & 0x0f) << 12) | ((d & 0x3f) << 6) | (*p & 0x3f); + break; + + /* 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 ((*(++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; + } + v = ((c & 0x07) << 18) | ((d & 0x3f) << 12) | ((p[-1] & 0x3f) << 6) | (*p & 0x3f); + break; + + /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be + 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 */ + + case 4: + 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; + + /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for + 1111 1100, xx00 00xx. */ + + case 5: + 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; + } + + /* 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) + { + *erroroffset = (int)(p - string) - ab; + return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12; + } + + /* Reject non-characters. The pointer p is currently at the last byte of the + character. */ + if ((v & 0xfffeu) == 0xfffeu || (v >= 0xfdd0 && v <= 0xfdef)) + { + *erroroffset = (int)(p - string) - ab; + return PCRE_UTF8_ERR22; + } + } + +#else /* Not SUPPORT_UTF */ +(void)(string); /* Keep picky compilers happy */ +(void)(length); +(void)(erroroffset); +#endif + +return PCRE_UTF8_ERR0; /* This indicates success */ +} + +/* End of pcre_valid_utf8.c */ diff --git a/tools/pcre/pcre_version.c b/tools/pcre/pcre_version.c new file mode 100644 index 00000000..ae86ff28 --- /dev/null +++ b/tools/pcre/pcre_version.c @@ -0,0 +1,98 @@ +/************************************************* +* 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 the external function pcre_version(), which returns a +string that identifies the PCRE version that is in use. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + + +/************************************************* +* Return version string * +*************************************************/ + +/* These macros are the standard way of turning unquoted text into C strings. +They allow macros like PCRE_MAJOR to be defined without quotes, which is +convenient for user programs that want to test its value. */ + +#define STRING(a) # a +#define XSTRING(s) STRING(s) + +/* A problem turned up with PCRE_PRERELEASE, which is defined empty for +production releases. Originally, it was used naively in this code: + + return XSTRING(PCRE_MAJOR) + "." XSTRING(PCRE_MINOR) + XSTRING(PCRE_PRERELEASE) + " " XSTRING(PCRE_DATE); + +However, when PCRE_PRERELEASE is empty, this leads to an attempted expansion of +STRING(). The C standard states: "If (before argument substitution) any +argument consists of no preprocessing tokens, the behavior is undefined." It +turns out the gcc treats this case as a single empty string - which is what we +really want - but Visual C grumbles about the lack of an argument for the +macro. Unfortunately, both are within their rights. To cope with both ways of +handling this, I had resort to some messy hackery that does a test at run time. +I could find no way of detecting that a macro is defined as an empty string at +pre-processor time. This hack uses a standard trick for avoiding calling +the STRING macro with an empty argument when doing the test. */ + +#if defined COMPILE_PCRE8 +PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION +pcre_version(void) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION +pcre16_version(void) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION +pcre32_version(void) +#endif +{ +return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)? + XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) : + XSTRING(PCRE_MAJOR.PCRE_MINOR) XSTRING(PCRE_PRERELEASE PCRE_DATE); +} + +/* End of pcre_version.c */ diff --git a/tools/pcre/pcre_xclass.c b/tools/pcre/pcre_xclass.c new file mode 100644 index 00000000..fa73cd8c --- /dev/null +++ b/tools/pcre/pcre_xclass.c @@ -0,0 +1,198 @@ +/************************************************* +* 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" + + +/************************************************* +* Match character against an XCLASS * +*************************************************/ + +/* This function is called to match a character against an extended class that +might contain values > 255 and/or Unicode properties. + +Arguments: + c the character + data points to the flag byte of the XCLASS data + +Returns: TRUE if character matches, else FALSE +*/ + +BOOL +PRIV(xclass)(pcre_uint32 c, const pcre_uchar *data, BOOL utf) +{ +pcre_uchar 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 && + (((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 / sizeof(pcre_uchar); + +while ((t = *data++) != XCL_END) + { + pcre_uint32 x, y; + if (t == XCL_SINGLE) + { +#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) + { +#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; + } + +#ifdef SUPPORT_UCP + else /* XCL_PROP & XCL_NOTPROP */ + { + const ucd_record *prop = GET_UCD(c); + + switch(*data) + { + case PT_ANY: + if (t == XCL_PROP) return !negated; + break; + + case PT_LAMP: + if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt) == (t == XCL_PROP)) return !negated; + break; + + case PT_GC: + if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP)) + return !negated; + break; + + case PT_PC: + if ((data[1] == prop->chartype) == (t == XCL_PROP)) return !negated; + break; + + case PT_SC: + if ((data[1] == prop->script) == (t == XCL_PROP)) return !negated; + break; + + case PT_ALNUM: + 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 ((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 ((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 ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) + == (t == XCL_PROP)) + return !negated; + break; + + /* This should never occur, but compilers may mutter if there is no + default. */ + + default: + return FALSE; + } + + data += 2; + } +#endif /* SUPPORT_UCP */ + } + +return negated; /* char did not match */ +} + +/* End of pcre_xclass.c */ diff --git a/tools/pcre/pcrecpp.cc b/tools/pcre/pcrecpp.cc new file mode 100644 index 00000000..c0ba9ca1 --- /dev/null +++ b/tools/pcre/pcrecpp.cc @@ -0,0 +1,922 @@ +// Copyright (c) 2010, Google Inc. +// All rights reserved. +// +// 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 Google Inc. 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. +// +// Author: Sanjay Ghemawat + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include /* for SHRT_MIN, USHRT_MAX, etc */ +#include /* for memcpy */ +#include +#include +#include +#include + +#include "pcrecpp_internal.h" +#include "pcre.h" +#include "pcrecpp.h" +#include "pcre_stringpiece.h" + + +namespace pcrecpp { + +// Maximum number of args we can set +static const int kMaxArgs = 16; +static const int kVecSize = (1 + kMaxArgs) * 3; // results + PCRE workspace + +// Special object that stands-in for no argument +Arg RE::no_arg((void*)NULL); + +// This is for ABI compatibility with old versions of pcre (pre-7.6), +// which defined a global no_arg variable instead of putting it in the +// RE class. This works on GCC >= 3, at least. It definitely works +// for ELF, but may not for other object formats (Mach-O, for +// instance, does not support aliases.) We could probably have a more +// inclusive test if we ever needed it. (Note that not only the +// __attribute__ syntax, but also __USER_LABEL_PREFIX__, are +// gnu-specific.) +#if defined(__GNUC__) && __GNUC__ >= 3 && defined(__ELF__) +# define ULP_AS_STRING(x) ULP_AS_STRING_INTERNAL(x) +# define ULP_AS_STRING_INTERNAL(x) #x +# define USER_LABEL_PREFIX_STR ULP_AS_STRING(__USER_LABEL_PREFIX__) +extern Arg no_arg + __attribute__((alias(USER_LABEL_PREFIX_STR "_ZN7pcrecpp2RE6no_argE"))); +#endif + +// If a regular expression has no error, its error_ field points here +static const string empty_string; + +// If the user doesn't ask for any options, we just use this one +static RE_Options default_options; + +void RE::Init(const string& pat, const RE_Options* options) { + pattern_ = pat; + if (options == NULL) { + options_ = default_options; + } else { + options_ = *options; + } + error_ = &empty_string; + re_full_ = NULL; + re_partial_ = NULL; + + re_partial_ = Compile(UNANCHORED); + if (re_partial_ != NULL) { + re_full_ = Compile(ANCHOR_BOTH); + } +} + +void RE::Cleanup() { + if (re_full_ != NULL) (*pcre_free)(re_full_); + if (re_partial_ != NULL) (*pcre_free)(re_partial_); + if (error_ != &empty_string) delete error_; +} + + +RE::~RE() { + Cleanup(); +} + + +pcre* RE::Compile(Anchor anchor) { + // First, convert RE_Options into pcre options + int pcre_options = 0; + pcre_options = options_.all_options(); + + // Special treatment for anchoring. This is needed because at + // runtime pcre only provides an option for anchoring at the + // beginning of a string (unless you use offset). + // + // There are three types of anchoring we want: + // UNANCHORED Compile the original pattern, and use + // a pcre unanchored match. + // ANCHOR_START Compile the original pattern, and use + // a pcre anchored match. + // ANCHOR_BOTH Tack a "\z" to the end of the original pattern + // and use a pcre anchored match. + + const char* compile_error; + int eoffset; + pcre* re; + if (anchor != ANCHOR_BOTH) { + re = pcre_compile(pattern_.c_str(), pcre_options, + &compile_error, &eoffset, NULL); + } else { + // Tack a '\z' at the end of RE. Parenthesize it first so that + // the '\z' applies to all top-level alternatives in the regexp. + string wrapped = "(?:"; // A non-counting grouping operator + wrapped += pattern_; + wrapped += ")\\z"; + re = pcre_compile(wrapped.c_str(), pcre_options, + &compile_error, &eoffset, NULL); + } + if (re == NULL) { + if (error_ == &empty_string) error_ = new string(compile_error); + } + return re; +} + +/***** Matching interfaces *****/ + +bool RE::FullMatch(const StringPiece& text, + const Arg& ptr1, + const Arg& ptr2, + const Arg& ptr3, + const Arg& ptr4, + const Arg& ptr5, + const Arg& ptr6, + const Arg& ptr7, + const Arg& ptr8, + const Arg& ptr9, + const Arg& ptr10, + const Arg& ptr11, + const Arg& ptr12, + const Arg& ptr13, + const Arg& ptr14, + const Arg& ptr15, + const Arg& ptr16) const { + const Arg* args[kMaxArgs]; + int n = 0; + if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; + if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; + if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; + if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; + if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; + if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; + if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; + if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; + if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; + if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; + if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; + if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; + if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; + if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; + if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; + if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; + done: + + int consumed; + int vec[kVecSize]; + return DoMatchImpl(text, ANCHOR_BOTH, &consumed, args, n, vec, kVecSize); +} + +bool RE::PartialMatch(const StringPiece& text, + const Arg& ptr1, + const Arg& ptr2, + const Arg& ptr3, + const Arg& ptr4, + const Arg& ptr5, + const Arg& ptr6, + const Arg& ptr7, + const Arg& ptr8, + const Arg& ptr9, + const Arg& ptr10, + const Arg& ptr11, + const Arg& ptr12, + const Arg& ptr13, + const Arg& ptr14, + const Arg& ptr15, + const Arg& ptr16) const { + const Arg* args[kMaxArgs]; + int n = 0; + if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; + if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; + if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; + if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; + if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; + if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; + if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; + if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; + if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; + if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; + if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; + if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; + if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; + if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; + if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; + if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; + done: + + int consumed; + int vec[kVecSize]; + return DoMatchImpl(text, UNANCHORED, &consumed, args, n, vec, kVecSize); +} + +bool RE::Consume(StringPiece* input, + const Arg& ptr1, + const Arg& ptr2, + const Arg& ptr3, + const Arg& ptr4, + const Arg& ptr5, + const Arg& ptr6, + const Arg& ptr7, + const Arg& ptr8, + const Arg& ptr9, + const Arg& ptr10, + const Arg& ptr11, + const Arg& ptr12, + const Arg& ptr13, + const Arg& ptr14, + const Arg& ptr15, + const Arg& ptr16) const { + const Arg* args[kMaxArgs]; + int n = 0; + if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; + if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; + if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; + if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; + if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; + if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; + if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; + if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; + if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; + if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; + if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; + if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; + if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; + if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; + if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; + if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; + done: + + int consumed; + int vec[kVecSize]; + if (DoMatchImpl(*input, ANCHOR_START, &consumed, + args, n, vec, kVecSize)) { + input->remove_prefix(consumed); + return true; + } else { + return false; + } +} + +bool RE::FindAndConsume(StringPiece* input, + const Arg& ptr1, + const Arg& ptr2, + const Arg& ptr3, + const Arg& ptr4, + const Arg& ptr5, + const Arg& ptr6, + const Arg& ptr7, + const Arg& ptr8, + const Arg& ptr9, + const Arg& ptr10, + const Arg& ptr11, + const Arg& ptr12, + const Arg& ptr13, + const Arg& ptr14, + const Arg& ptr15, + const Arg& ptr16) const { + const Arg* args[kMaxArgs]; + int n = 0; + if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; + if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; + if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; + if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; + if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; + if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; + if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; + if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; + if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; + if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; + if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; + if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; + if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; + if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; + if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; + if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; + done: + + int consumed; + int vec[kVecSize]; + if (DoMatchImpl(*input, UNANCHORED, &consumed, + args, n, vec, kVecSize)) { + input->remove_prefix(consumed); + return true; + } else { + return false; + } +} + +bool RE::Replace(const StringPiece& rewrite, + string *str) const { + int vec[kVecSize]; + int matches = TryMatch(*str, 0, UNANCHORED, true, vec, kVecSize); + if (matches == 0) + return false; + + string s; + if (!Rewrite(&s, rewrite, *str, vec, matches)) + return false; + + assert(vec[0] >= 0); + assert(vec[1] >= 0); + str->replace(vec[0], vec[1] - vec[0], s); + return true; +} + +// Returns PCRE_NEWLINE_CRLF, PCRE_NEWLINE_CR, or PCRE_NEWLINE_LF. +// Note that PCRE_NEWLINE_CRLF is defined to be P_N_CR | P_N_LF. +// Modified by PH to add PCRE_NEWLINE_ANY and PCRE_NEWLINE_ANYCRLF. + +static int NewlineMode(int pcre_options) { + // TODO: if we can make it threadsafe, cache this var + int newline_mode = 0; + /* if (newline_mode) return newline_mode; */ // do this once it's cached + if (pcre_options & (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF| + PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF)) { + newline_mode = (pcre_options & + (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF| + PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF)); + } else { + int newline; + pcre_config(PCRE_CONFIG_NEWLINE, &newline); + if (newline == 10) + newline_mode = PCRE_NEWLINE_LF; + else if (newline == 13) + newline_mode = PCRE_NEWLINE_CR; + else if (newline == 3338) + newline_mode = PCRE_NEWLINE_CRLF; + else if (newline == -1) + newline_mode = PCRE_NEWLINE_ANY; + else if (newline == -2) + newline_mode = PCRE_NEWLINE_ANYCRLF; + else + assert(NULL == "Unexpected return value from pcre_config(NEWLINE)"); + } + return newline_mode; +} + +int RE::GlobalReplace(const StringPiece& rewrite, + string *str) const { + int count = 0; + int vec[kVecSize]; + string out; + int start = 0; + bool last_match_was_empty_string = false; + + while (start <= static_cast(str->length())) { + // If the previous match was for the empty string, we shouldn't + // just match again: we'll match in the same way and get an + // infinite loop. Instead, we do the match in a special way: + // anchored -- to force another try at the same position -- + // and with a flag saying that this time, ignore empty matches. + // If this special match returns, that means there's a non-empty + // match at this position as well, and we can continue. If not, + // we do what perl does, and just advance by one. + // Notice that perl prints '@@@' for this; + // perl -le '$_ = "aa"; s/b*|aa/@/g; print' + int matches; + if (last_match_was_empty_string) { + matches = TryMatch(*str, start, ANCHOR_START, false, vec, kVecSize); + if (matches <= 0) { + int matchend = start + 1; // advance one character. + // If the current char is CR and we're in CRLF mode, skip LF too. + // Note it's better to call pcre_fullinfo() than to examine + // all_options(), since options_ could have changed bewteen + // compile-time and now, but this is simpler and safe enough. + // Modified by PH to add ANY and ANYCRLF. + if (matchend < static_cast(str->length()) && + (*str)[start] == '\r' && (*str)[matchend] == '\n' && + (NewlineMode(options_.all_options()) == PCRE_NEWLINE_CRLF || + NewlineMode(options_.all_options()) == PCRE_NEWLINE_ANY || + NewlineMode(options_.all_options()) == PCRE_NEWLINE_ANYCRLF)) { + matchend++; + } + // We also need to advance more than one char if we're in utf8 mode. +#ifdef SUPPORT_UTF8 + if (options_.utf8()) { + while (matchend < static_cast(str->length()) && + ((*str)[matchend] & 0xc0) == 0x80) + matchend++; + } +#endif + if (start < static_cast(str->length())) + out.append(*str, start, matchend - start); + start = matchend; + last_match_was_empty_string = false; + continue; + } + } else { + matches = TryMatch(*str, start, UNANCHORED, true, vec, kVecSize); + if (matches <= 0) + break; + } + int matchstart = vec[0], matchend = vec[1]; + assert(matchstart >= start); + assert(matchend >= matchstart); + out.append(*str, start, matchstart - start); + Rewrite(&out, rewrite, *str, vec, matches); + start = matchend; + count++; + last_match_was_empty_string = (matchstart == matchend); + } + + if (count == 0) + return 0; + + if (start < static_cast(str->length())) + out.append(*str, start, str->length() - start); + swap(out, *str); + return count; +} + +bool RE::Extract(const StringPiece& rewrite, + const StringPiece& text, + string *out) const { + int vec[kVecSize]; + int matches = TryMatch(text, 0, UNANCHORED, true, vec, kVecSize); + if (matches == 0) + return false; + out->erase(); + return Rewrite(out, rewrite, text, vec, matches); +} + +/*static*/ string RE::QuoteMeta(const StringPiece& unquoted) { + string result; + + // Escape any ascii character not in [A-Za-z_0-9]. + // + // 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`.) The one exception is + // escaping NUL: rather than doing backslash + NUL, like perl does, + // we do '\0', because pcre itself doesn't take embedded NUL chars. + for (int ii = 0; ii < unquoted.size(); ++ii) { + // Note that using 'isalnum' here raises the benchmark time from + // 32ns to 58ns: + if (unquoted[ii] == '\0') { + result += "\\0"; + } else if ((unquoted[ii] < 'a' || unquoted[ii] > 'z') && + (unquoted[ii] < 'A' || unquoted[ii] > 'Z') && + (unquoted[ii] < '0' || unquoted[ii] > '9') && + unquoted[ii] != '_' && + // If this is the part of a UTF8 or Latin1 character, we need + // to copy this byte without escaping. Experimentally this is + // what works correctly with the regexp library. + !(unquoted[ii] & 128)) { + result += '\\'; + result += unquoted[ii]; + } else { + result += unquoted[ii]; + } + } + + return result; +} + +/***** Actual matching and rewriting code *****/ + +int RE::TryMatch(const StringPiece& text, + int startpos, + Anchor anchor, + bool empty_ok, + int *vec, + int vecsize) const { + pcre* re = (anchor == ANCHOR_BOTH) ? re_full_ : re_partial_; + if (re == NULL) { + //fprintf(stderr, "Matching against invalid re: %s\n", error_->c_str()); + return 0; + } + + pcre_extra extra = { 0, 0, 0, 0, 0, 0 }; + if (options_.match_limit() > 0) { + extra.flags |= PCRE_EXTRA_MATCH_LIMIT; + extra.match_limit = options_.match_limit(); + } + if (options_.match_limit_recursion() > 0) { + extra.flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; + extra.match_limit_recursion = options_.match_limit_recursion(); + } + + // int options = 0; + // Changed by PH as a result of bugzilla #1288 + int options = (options_.all_options() & PCRE_NO_UTF8_CHECK); + + if (anchor != UNANCHORED) + options |= PCRE_ANCHORED; + if (!empty_ok) + options |= PCRE_NOTEMPTY; + + int rc = pcre_exec(re, // The regular expression object + &extra, + (text.data() == NULL) ? "" : text.data(), + text.size(), + startpos, + options, + vec, + vecsize); + + // Handle errors + if (rc == PCRE_ERROR_NOMATCH) { + return 0; + } else if (rc < 0) { + //fprintf(stderr, "Unexpected return code: %d when matching '%s'\n", + // re, pattern_.c_str()); + return 0; + } else if (rc == 0) { + // pcre_exec() returns 0 as a special case when the number of + // capturing subpatterns exceeds the size of the vector. + // When this happens, there is a match and the output vector + // is filled, but we miss out on the positions of the extra subpatterns. + rc = vecsize / 2; + } + + return rc; +} + +bool RE::DoMatchImpl(const StringPiece& text, + Anchor anchor, + int* consumed, + const Arg* const* args, + int n, + int* vec, + int vecsize) const { + assert((1 + n) * 3 <= vecsize); // results + PCRE workspace + int matches = TryMatch(text, 0, anchor, true, vec, vecsize); + assert(matches >= 0); // TryMatch never returns negatives + if (matches == 0) + return false; + + *consumed = vec[1]; + + if (n == 0 || args == NULL) { + // We are not interested in results + return true; + } + + if (NumberOfCapturingGroups() < n) { + // RE has fewer capturing groups than number of arg pointers passed in + return false; + } + + // If we got here, we must have matched the whole pattern. + // We do not need (can not do) any more checks on the value of 'matches' here + // -- see the comment for TryMatch. + for (int i = 0; i < n; i++) { + const int start = vec[2*(i+1)]; + const int limit = vec[2*(i+1)+1]; + if (!args[i]->Parse(text.data() + start, limit-start)) { + // TODO: Should we indicate what the error was? + return false; + } + } + + return true; +} + +bool RE::DoMatch(const StringPiece& text, + Anchor anchor, + int* consumed, + const Arg* const args[], + int n) const { + assert(n >= 0); + size_t const vecsize = (1 + n) * 3; // results + PCRE workspace + // (as for kVecSize) + int space[21]; // use stack allocation for small vecsize (common case) + int* vec = vecsize <= 21 ? space : new int[vecsize]; + bool retval = DoMatchImpl(text, anchor, consumed, args, n, vec, (int)vecsize); + if (vec != space) delete [] vec; + return retval; +} + +bool RE::Rewrite(string *out, const StringPiece &rewrite, + const StringPiece &text, int *vec, int veclen) const { + for (const char *s = rewrite.data(), *end = s + rewrite.size(); + s < end; s++) { + int c = *s; + if (c == '\\') { + c = *++s; + if (isdigit(c)) { + int n = (c - '0'); + if (n >= veclen) { + //fprintf(stderr, requested group %d in regexp %.*s\n", + // n, rewrite.size(), rewrite.data()); + return false; + } + int start = vec[2 * n]; + if (start >= 0) + out->append(text.data() + start, vec[2 * n + 1] - start); + } else if (c == '\\') { + *out += '\\'; + } else { + //fprintf(stderr, "invalid rewrite pattern: %.*s\n", + // rewrite.size(), rewrite.data()); + return false; + } + } else { + *out += c; + } + } + return true; +} + +// Return the number of capturing subpatterns, or -1 if the +// regexp wasn't valid on construction. +int RE::NumberOfCapturingGroups() const { + if (re_partial_ == NULL) return -1; + + int result; + int pcre_retval = pcre_fullinfo(re_partial_, // The regular expression object + NULL, // We did not study the pattern + PCRE_INFO_CAPTURECOUNT, + &result); + assert(pcre_retval == 0); + return result; +} + +/***** Parsers for various types *****/ + +bool Arg::parse_null(const char* str, int n, void* dest) { + // We fail if somebody asked us to store into a non-NULL void* pointer + return (dest == NULL); +} + +bool Arg::parse_string(const char* str, int n, void* dest) { + if (dest == NULL) return true; + reinterpret_cast(dest)->assign(str, n); + return true; +} + +bool Arg::parse_stringpiece(const char* str, int n, void* dest) { + if (dest == NULL) return true; + reinterpret_cast(dest)->set(str, n); + return true; +} + +bool Arg::parse_char(const char* str, int n, void* dest) { + if (n != 1) return false; + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = str[0]; + return true; +} + +bool Arg::parse_uchar(const char* str, int n, void* dest) { + if (n != 1) return false; + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = str[0]; + return true; +} + +// Largest number spec that we are willing to parse +static const int kMaxNumberLength = 32; + +// REQUIRES "buf" must have length at least kMaxNumberLength+1 +// REQUIRES "n > 0" +// Copies "str" into "buf" and null-terminates if necessary. +// Returns one of: +// a. "str" if no termination is needed +// b. "buf" if the string was copied and null-terminated +// c. "" if the input was invalid and has no hope of being parsed +static const char* TerminateNumber(char* buf, const char* str, int n) { + if ((n > 0) && isspace(*str)) { + // We are less forgiving than the strtoxxx() routines and do not + // allow leading spaces. + return ""; + } + + // See if the character right after the input text may potentially + // look like a digit. + if (isdigit(str[n]) || + ((str[n] >= 'a') && (str[n] <= 'f')) || + ((str[n] >= 'A') && (str[n] <= 'F'))) { + if (n > kMaxNumberLength) return ""; // Input too big to be a valid number + memcpy(buf, str, n); + buf[n] = '\0'; + return buf; + } else { + // We can parse right out of the supplied string, so return it. + return str; + } +} + +bool Arg::parse_long_radix(const char* str, + int n, + void* dest, + int radix) { + if (n == 0) return false; + char buf[kMaxNumberLength+1]; + str = TerminateNumber(buf, str, n); + char* end; + errno = 0; + long r = strtol(str, &end, radix); + if (end != str + n) return false; // Leftover junk + if (errno) return false; + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = r; + return true; +} + +bool Arg::parse_ulong_radix(const char* str, + int n, + void* dest, + int radix) { + if (n == 0) return false; + char buf[kMaxNumberLength+1]; + str = TerminateNumber(buf, str, n); + if (str[0] == '-') return false; // strtoul() on a negative number?! + char* end; + errno = 0; + unsigned long r = strtoul(str, &end, radix); + if (end != str + n) return false; // Leftover junk + if (errno) return false; + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = r; + return true; +} + +bool Arg::parse_short_radix(const char* str, + int n, + void* dest, + int radix) { + long r; + if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse + if (r < SHRT_MIN || r > SHRT_MAX) return false; // Out of range + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = static_cast(r); + return true; +} + +bool Arg::parse_ushort_radix(const char* str, + int n, + void* dest, + int radix) { + unsigned long r; + if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse + if (r > USHRT_MAX) return false; // Out of range + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = static_cast(r); + return true; +} + +bool Arg::parse_int_radix(const char* str, + int n, + void* dest, + int radix) { + long r; + if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse + if (r < INT_MIN || r > INT_MAX) return false; // Out of range + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = r; + return true; +} + +bool Arg::parse_uint_radix(const char* str, + int n, + void* dest, + int radix) { + unsigned long r; + if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse + if (r > UINT_MAX) return false; // Out of range + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = r; + return true; +} + +bool Arg::parse_longlong_radix(const char* str, + int n, + void* dest, + int radix) { +#ifndef HAVE_LONG_LONG + return false; +#else + if (n == 0) return false; + char buf[kMaxNumberLength+1]; + str = TerminateNumber(buf, str, n); + char* end; + errno = 0; +#if defined HAVE_STRTOQ + long long r = strtoq(str, &end, radix); +#elif defined HAVE_STRTOLL + long long r = strtoll(str, &end, radix); +#elif defined HAVE__STRTOI64 + long long r = _strtoi64(str, &end, radix); +#elif defined HAVE_STRTOIMAX + long long r = strtoimax(str, &end, radix); +#else +#error parse_longlong_radix: cannot convert input to a long-long +#endif + if (end != str + n) return false; // Leftover junk + if (errno) return false; + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = r; + return true; +#endif /* HAVE_LONG_LONG */ +} + +bool Arg::parse_ulonglong_radix(const char* str, + int n, + void* dest, + int radix) { +#ifndef HAVE_UNSIGNED_LONG_LONG + return false; +#else + if (n == 0) return false; + char buf[kMaxNumberLength+1]; + str = TerminateNumber(buf, str, n); + if (str[0] == '-') return false; // strtoull() on a negative number?! + char* end; + errno = 0; +#if defined HAVE_STRTOQ + unsigned long long r = strtouq(str, &end, radix); +#elif defined HAVE_STRTOLL + unsigned long long r = strtoull(str, &end, radix); +#elif defined HAVE__STRTOI64 + unsigned long long r = _strtoui64(str, &end, radix); +#elif defined HAVE_STRTOIMAX + unsigned long long r = strtoumax(str, &end, radix); +#else +#error parse_ulonglong_radix: cannot convert input to a long-long +#endif + if (end != str + n) return false; // Leftover junk + if (errno) return false; + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = r; + return true; +#endif /* HAVE_UNSIGNED_LONG_LONG */ +} + +bool Arg::parse_double(const char* str, int n, void* dest) { + if (n == 0) return false; + static const int kMaxLength = 200; + char buf[kMaxLength]; + if (n >= kMaxLength) return false; + memcpy(buf, str, n); + buf[n] = '\0'; + errno = 0; + char* end; + double r = strtod(buf, &end); + if (end != buf + n) return false; // Leftover junk + if (errno) return false; + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = r; + return true; +} + +bool Arg::parse_float(const char* str, int n, void* dest) { + double r; + if (!parse_double(str, n, &r)) return false; + if (dest == NULL) return true; + *(reinterpret_cast(dest)) = static_cast(r); + return true; +} + + +#define DEFINE_INTEGER_PARSERS(name) \ + bool Arg::parse_##name(const char* str, int n, void* dest) { \ + return parse_##name##_radix(str, n, dest, 10); \ + } \ + bool Arg::parse_##name##_hex(const char* str, int n, void* dest) { \ + return parse_##name##_radix(str, n, dest, 16); \ + } \ + bool Arg::parse_##name##_octal(const char* str, int n, void* dest) { \ + return parse_##name##_radix(str, n, dest, 8); \ + } \ + bool Arg::parse_##name##_cradix(const char* str, int n, void* dest) { \ + return parse_##name##_radix(str, n, dest, 0); \ + } + +DEFINE_INTEGER_PARSERS(short) /* */ +DEFINE_INTEGER_PARSERS(ushort) /* */ +DEFINE_INTEGER_PARSERS(int) /* Don't use semicolons after these */ +DEFINE_INTEGER_PARSERS(uint) /* statements because they can cause */ +DEFINE_INTEGER_PARSERS(long) /* compiler warnings if the checking */ +DEFINE_INTEGER_PARSERS(ulong) /* level is turned up high enough. */ +DEFINE_INTEGER_PARSERS(longlong) /* */ +DEFINE_INTEGER_PARSERS(ulonglong) /* */ + +#undef DEFINE_INTEGER_PARSERS + +} // namespace pcrecpp diff --git a/tools/pcre/pcrecpp.h b/tools/pcre/pcrecpp.h new file mode 100644 index 00000000..3e594b0d --- /dev/null +++ b/tools/pcre/pcrecpp.h @@ -0,0 +1,710 @@ +// Copyright (c) 2005, Google Inc. +// All rights reserved. +// +// 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 Google Inc. 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. +// +// Author: Sanjay Ghemawat +// Support for PCRE_XXX modifiers added by Giuseppe Maxia, July 2005 + +#ifndef _PCRECPP_H +#define _PCRECPP_H + +// C++ interface to the pcre regular-expression library. RE supports +// Perl-style regular expressions (with extensions like \d, \w, \s, +// ...). +// +// ----------------------------------------------------------------------- +// REGEXP SYNTAX: +// +// This module is part of the pcre library and hence supports its syntax +// for regular expressions. +// +// The syntax is pretty similar to Perl's. For those not familiar +// with Perl's regular expressions, here are some examples of the most +// commonly used extensions: +// +// "hello (\\w+) world" -- \w matches a "word" character +// "version (\\d+)" -- \d matches a digit +// "hello\\s+world" -- \s matches any whitespace character +// "\\b(\\w+)\\b" -- \b matches empty string at a word boundary +// "(?i)hello" -- (?i) turns on case-insensitive matching +// "/\\*(.*?)\\*/" -- .*? matches . minimum no. of times possible +// +// ----------------------------------------------------------------------- +// MATCHING INTERFACE: +// +// The "FullMatch" operation checks that supplied text matches a +// supplied pattern exactly. +// +// Example: successful match +// pcrecpp::RE re("h.*o"); +// re.FullMatch("hello"); +// +// Example: unsuccessful match (requires full match): +// pcrecpp::RE re("e"); +// !re.FullMatch("hello"); +// +// 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. Either +// could correctly be used for any of these examples. +// +// ----------------------------------------------------------------------- +// MATCHING WITH SUB-STRING EXTRACTION: +// +// You can supply extra pointer arguments to extract matched subpieces. +// +// Example: extracts "ruby" into "s" and 1234 into "i" +// int i; +// string s; +// pcrecpp::RE re("(\\w+):(\\d+)"); +// re.FullMatch("ruby:1234", &s, &i); +// +// Example: does not try to extract any extra sub-patterns +// re.FullMatch("ruby:1234", &s); +// +// Example: does not try to extract into NULL +// re.FullMatch("ruby:1234", NULL, &i); +// +// Example: integer overflow causes failure +// !re.FullMatch("ruby:1234567891234", NULL, &i); +// +// Example: fails because there aren't enough sub-patterns: +// !pcrecpp::RE("\\w+:\\d+").FullMatch("ruby:1234", &s); +// +// 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 +// type, or one of +// string (matched piece is copied to string) +// StringPiece (StringPiece is mutated to point to matched piece) +// T (where "bool T::ParseFrom(const char*, int)" exists) +// NULL (the corresponding matched sub-pattern is not copied) +// +// 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); +// +// ----------------------------------------------------------------------- +// DO_MATCH +// +// 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. +// +// ----------------------------------------------------------------------- +// PARTIAL MATCHES +// +// You can use the "PartialMatch" operation when you want the pattern +// to match any substring of the text. +// +// Example: simple search for a string: +// pcrecpp::RE("ell").PartialMatch("hello"); +// +// Example: find first number in a string: +// int number; +// pcrecpp::RE re("(\\d+)"); +// re.PartialMatch("x*100 + 20", &number); +// assert(number == 100); +// +// ----------------------------------------------------------------------- +// 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 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. E.g., "." will match one byte normally but with UTF8 +// set may match up to three bytes of a multi-byte character. +// +// Example: +// pcrecpp::RE_Options options; +// options.set_utf8(); +// pcrecpp::RE re(utf8_pattern, options); +// re.FullMatch(utf8_string); +// +// Example: using the convenience function UTF8(): +// pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8()); +// re.FullMatch(utf8_string); +// +// NOTE: The UTF8 option is ignored if pcre was not configured with the +// --enable-utf8 flag. +// +// ----------------------------------------------------------------------- +// 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. +// +// Currently, the following modifiers are supported +// +// modifier description Perl corresponding +// +// PCRE_CASELESS case insensitive match /i +// PCRE_MULTILINE multiple lines match /m +// 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_UTF8 handles UTF8 chars built-in +// PCRE_UNGREEDY reverses * and *? N/A +// PCRE_NO_AUTO_CAPTURE disables matching parens N/A (*) +// +// (For a full account on how each modifier works, please check the +// PCRE API reference manual). +// +// (*) Both Perl and PCRE allow non matching parentheses by means of the +// "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not +// capture, while (ab|cd) does. +// +// 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(), +// which returns true if the modifier is set, and +// 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 executation 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 will +// disable match limiting. Alternately, you can set match_limit_recursion() +// which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to limit how much pcre +// recurses. match_limit() caps the number of matches pcre does; +// match_limit_recrusion() caps the depth of recursion. +// +// 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; +// opt.set_caseless(true); +// +// if (RE("HELLO", opt).PartialMatch("hello world")) ... +// +// RE_options has two constructors. The default constructor takes no +// arguments 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, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); +// +// But new code is better off doing +// RE(pattern, +// RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str); +// (See below) +// +// 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 +// appropriate modifier already set: +// CASELESS(), UTF8(), MULTILINE(), DOTALL(), 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. e.g.: to pass +// PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one +// statement, you may write +// +// RE(" ^ xyz \\s+ .* blah$", RE_Options() +// .set_caseless(true) +// .set_extended(true) +// .set_multiline(true)).PartialMatch(sometext); +// +// ----------------------------------------------------------------------- +// SCANNING TEXT INCREMENTALLY +// +// 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 pcrecpp namespace. +// +// Example: read lines of the form "var = value" from a string. +// string contents = ...; // Fill string somehow +// pcrecpp::StringPiece input(contents); // Wrap in a StringPiece +// +// string var; +// int value; +// pcrecpp::RE re("(\\w+) = (\\d+)\n"); +// while (re.Consume(&input, &var, &value)) { +// ...; +// } +// +// 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 +// could extract all words from a string by repeatedly calling +// pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word) +// +// ----------------------------------------------------------------------- +// 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 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 base-10. +// +// Example: +// int a, b, c, d; +// pcrecpp::RE re("(.*) (.*) (.*) (.*)"); +// re.FullMatch("100 40 0100 0x40", +// pcrecpp::Octal(&a), pcrecpp::Hex(&b), +// pcrecpp::CRadix(&c), pcrecpp::CRadix(&d)); +// will leave 64 in a, b, c, and d. +// +// ----------------------------------------------------------------------- +// 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 pattern. \0 in "rewrite" refers to the entire +// matching text. E.g., +// +// string s = "yabba dabba doo"; +// pcrecpp::RE("b+").Replace("d", &s); +// +// will leave "s" containing "yada dabba doo". The result is true if +// the pattern matches and a replacement occurs, or false otherwise. +// +// 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. E.g., +// +// string s = "yabba dabba doo"; +// pcrecpp::RE("b+").GlobalReplace("d", &s); +// +// 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 occurred and the extraction happened +// successfully. If no match occurs, the string is left unaffected. + + +#include +#include +#include // defines the Arg class +// This isn't technically needed here, but we include it +// anyway so folks who include pcrecpp.h don't have to. +#include + +namespace pcrecpp { + +#define PCRE_SET_OR_CLEAR(b, o) \ + if (b) all_options_ |= (o); else all_options_ &= ~(o); \ + return *this + +#define PCRE_IS_SET(o) \ + (all_options_ & o) == o + +/***** Compiling regular expressions: the RE class *****/ + +// RE_Options allow you to set options to be passed along to pcre, +// along with other options we put on top of pcre. +// Only 9 modifiers, plus match_limit and match_limit_recursion, +// are supported now. +class PCRECPP_EXP_DEFN RE_Options { + public: + // constructor + RE_Options() : match_limit_(0), match_limit_recursion_(0), all_options_(0) {} + + // alternative constructor. + // To facilitate transfer of legacy code from C programs + // + // This lets you do + // RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); + // But new code is better off doing + // RE(pattern, + // RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str); + RE_Options(int option_flags) : match_limit_(0), match_limit_recursion_(0), + all_options_(option_flags) {} + // we're fine with the default destructor, copy constructor, etc. + + // accessors and mutators + int match_limit() const { return match_limit_; }; + RE_Options &set_match_limit(int limit) { + match_limit_ = limit; + return *this; + } + + int match_limit_recursion() const { return match_limit_recursion_; }; + RE_Options &set_match_limit_recursion(int limit) { + match_limit_recursion_ = limit; + return *this; + } + + bool caseless() const { + return PCRE_IS_SET(PCRE_CASELESS); + } + RE_Options &set_caseless(bool x) { + PCRE_SET_OR_CLEAR(x, PCRE_CASELESS); + } + + bool multiline() const { + return PCRE_IS_SET(PCRE_MULTILINE); + } + RE_Options &set_multiline(bool x) { + PCRE_SET_OR_CLEAR(x, PCRE_MULTILINE); + } + + bool dotall() const { + return PCRE_IS_SET(PCRE_DOTALL); + } + RE_Options &set_dotall(bool x) { + PCRE_SET_OR_CLEAR(x, PCRE_DOTALL); + } + + bool extended() const { + return PCRE_IS_SET(PCRE_EXTENDED); + } + RE_Options &set_extended(bool x) { + PCRE_SET_OR_CLEAR(x, PCRE_EXTENDED); + } + + bool dollar_endonly() const { + return PCRE_IS_SET(PCRE_DOLLAR_ENDONLY); + } + RE_Options &set_dollar_endonly(bool x) { + PCRE_SET_OR_CLEAR(x, PCRE_DOLLAR_ENDONLY); + } + + bool extra() const { + return PCRE_IS_SET(PCRE_EXTRA); + } + RE_Options &set_extra(bool x) { + PCRE_SET_OR_CLEAR(x, PCRE_EXTRA); + } + + bool ungreedy() const { + return PCRE_IS_SET(PCRE_UNGREEDY); + } + RE_Options &set_ungreedy(bool x) { + PCRE_SET_OR_CLEAR(x, PCRE_UNGREEDY); + } + + bool utf8() const { + return PCRE_IS_SET(PCRE_UTF8); + } + RE_Options &set_utf8(bool x) { + PCRE_SET_OR_CLEAR(x, PCRE_UTF8); + } + + bool no_auto_capture() const { + return PCRE_IS_SET(PCRE_NO_AUTO_CAPTURE); + } + RE_Options &set_no_auto_capture(bool x) { + PCRE_SET_OR_CLEAR(x, PCRE_NO_AUTO_CAPTURE); + } + + RE_Options &set_all_options(int opt) { + all_options_ = opt; + return *this; + } + int all_options() const { + return all_options_ ; + } + + // TODO: add other pcre flags + + private: + int match_limit_; + int match_limit_recursion_; + int all_options_; +}; + +// These functions return some common RE_Options +static inline RE_Options UTF8() { + return RE_Options().set_utf8(true); +} + +static inline RE_Options CASELESS() { + return RE_Options().set_caseless(true); +} +static inline RE_Options MULTILINE() { + return RE_Options().set_multiline(true); +} + +static inline RE_Options DOTALL() { + return RE_Options().set_dotall(true); +} + +static inline RE_Options EXTENDED() { + return RE_Options().set_extended(true); +} + +// Interface for regular expression matching. Also corresponds to a +// pre-compiled regular expression. An "RE" object is safe for +// concurrent use by multiple threads. +class PCRECPP_EXP_DEFN RE { + public: + // We provide implicit conversions from strings so that users can + // pass in a string or a "const char*" wherever an "RE" is expected. + RE(const string& pat) { Init(pat, NULL); } + RE(const string& pat, const RE_Options& option) { Init(pat, &option); } + RE(const char* pat) { Init(pat, NULL); } + RE(const char* pat, const RE_Options& option) { Init(pat, &option); } + RE(const unsigned char* pat) { + Init(reinterpret_cast(pat), NULL); + } + RE(const unsigned char* pat, const RE_Options& option) { + Init(reinterpret_cast(pat), &option); + } + + // Copy constructor & assignment - note that these are expensive + // because they recompile the expression. + RE(const RE& re) { Init(re.pattern_, &re.options_); } + const RE& operator=(const RE& re) { + if (this != &re) { + Cleanup(); + + // This is the code that originally came from Google + // Init(re.pattern_.c_str(), &re.options_); + + // This is the replacement from Ari Pollak + Init(re.pattern_, &re.options_); + } + return *this; + } + + + ~RE(); + + // The string specification for this RE. E.g. + // RE re("ab*c?d+"); + // re.pattern(); // "ab*c?d+" + const string& pattern() const { return pattern_; } + + // If RE could not be created properly, returns an error string. + // Else returns the empty string. + const string& error() const { return *error_; } + + /***** The useful part: the matching interface *****/ + + // This is provided so one can do pattern.ReplaceAll() just as + // easily as ReplaceAll(pattern-text, ....) + + bool FullMatch(const StringPiece& text, + const Arg& ptr1 = no_arg, + const Arg& ptr2 = no_arg, + const Arg& ptr3 = no_arg, + const Arg& ptr4 = no_arg, + const Arg& ptr5 = no_arg, + const Arg& ptr6 = no_arg, + const Arg& ptr7 = no_arg, + const Arg& ptr8 = no_arg, + const Arg& ptr9 = no_arg, + const Arg& ptr10 = no_arg, + const Arg& ptr11 = no_arg, + const Arg& ptr12 = no_arg, + const Arg& ptr13 = no_arg, + const Arg& ptr14 = no_arg, + const Arg& ptr15 = no_arg, + const Arg& ptr16 = no_arg) const; + + bool PartialMatch(const StringPiece& text, + const Arg& ptr1 = no_arg, + const Arg& ptr2 = no_arg, + const Arg& ptr3 = no_arg, + const Arg& ptr4 = no_arg, + const Arg& ptr5 = no_arg, + const Arg& ptr6 = no_arg, + const Arg& ptr7 = no_arg, + const Arg& ptr8 = no_arg, + const Arg& ptr9 = no_arg, + const Arg& ptr10 = no_arg, + const Arg& ptr11 = no_arg, + const Arg& ptr12 = no_arg, + const Arg& ptr13 = no_arg, + const Arg& ptr14 = no_arg, + const Arg& ptr15 = no_arg, + const Arg& ptr16 = no_arg) const; + + bool Consume(StringPiece* input, + const Arg& ptr1 = no_arg, + const Arg& ptr2 = no_arg, + const Arg& ptr3 = no_arg, + const Arg& ptr4 = no_arg, + const Arg& ptr5 = no_arg, + const Arg& ptr6 = no_arg, + const Arg& ptr7 = no_arg, + const Arg& ptr8 = no_arg, + const Arg& ptr9 = no_arg, + const Arg& ptr10 = no_arg, + const Arg& ptr11 = no_arg, + const Arg& ptr12 = no_arg, + const Arg& ptr13 = no_arg, + const Arg& ptr14 = no_arg, + const Arg& ptr15 = no_arg, + const Arg& ptr16 = no_arg) const; + + bool FindAndConsume(StringPiece* input, + const Arg& ptr1 = no_arg, + const Arg& ptr2 = no_arg, + const Arg& ptr3 = no_arg, + const Arg& ptr4 = no_arg, + const Arg& ptr5 = no_arg, + const Arg& ptr6 = no_arg, + const Arg& ptr7 = no_arg, + const Arg& ptr8 = no_arg, + const Arg& ptr9 = no_arg, + const Arg& ptr10 = no_arg, + const Arg& ptr11 = no_arg, + const Arg& ptr12 = no_arg, + const Arg& ptr13 = no_arg, + const Arg& ptr14 = no_arg, + const Arg& ptr15 = no_arg, + const Arg& ptr16 = no_arg) const; + + bool Replace(const StringPiece& rewrite, + string *str) const; + + int GlobalReplace(const StringPiece& rewrite, + string *str) const; + + bool Extract(const StringPiece &rewrite, + const StringPiece &text, + string *out) const; + + // Escapes all potentially meaningful regexp characters in + // 'unquoted'. The returned string, used as a regular expression, + // will exactly match the original string. For example, + // 1.5-2.0? + // may become: + // 1\.5\-2\.0\? + // Note QuoteMeta behaves the same as perl's QuoteMeta function, + // *except* that it escapes the NUL character (\0) as backslash + 0, + // rather than backslash + NUL. + static string QuoteMeta(const StringPiece& unquoted); + + + /***** Generic matching interface *****/ + + // Type of match (TODO: Should be restructured as part of RE_Options) + enum Anchor { + UNANCHORED, // No anchoring + ANCHOR_START, // Anchor at start only + ANCHOR_BOTH // Anchor at start and end + }; + + // General matching routine. Stores the length of the match in + // "*consumed" if successful. + bool DoMatch(const StringPiece& text, + Anchor anchor, + int* consumed, + const Arg* const* args, int n) const; + + // Return the number of capturing subpatterns, or -1 if the + // regexp wasn't valid on construction. + int NumberOfCapturingGroups() const; + + // The default value for an argument, to indicate the end of the argument + // list. This must be used only in optional argument defaults. It should NOT + // be passed explicitly. Some people have tried to use it like this: + // + // FullMatch(x, y, &z, no_arg, &w); + // + // This is a mistake, and will not work. + static Arg no_arg; + + private: + + void Init(const string& pattern, const RE_Options* options); + void Cleanup(); + + // Match against "text", filling in "vec" (up to "vecsize" * 2/3) with + // pairs of integers for the beginning and end positions of matched + // text. The first pair corresponds to the entire matched text; + // subsequent pairs correspond, in order, to parentheses-captured + // matches. Returns the number of pairs (one more than the number of + // the last subpattern with a match) if matching was successful + // and zero if the match failed. + // I.e. for RE("(foo)|(bar)|(baz)") it will return 2, 3, and 4 when matching + // against "foo", "bar", and "baz" respectively. + // When matching RE("(foo)|hello") against "hello", it will return 1. + // But the values for all subpattern are filled in into "vec". + int TryMatch(const StringPiece& text, + int startpos, + Anchor anchor, + bool empty_ok, + int *vec, + int vecsize) const; + + // Append the "rewrite" string, with backslash subsitutions from "text" + // and "vec", to string "out". + bool Rewrite(string *out, + const StringPiece& rewrite, + const StringPiece& text, + int *vec, + int veclen) const; + + // internal implementation for DoMatch + bool DoMatchImpl(const StringPiece& text, + Anchor anchor, + int* consumed, + const Arg* const args[], + int n, + int* vec, + int vecsize) const; + + // Compile the regexp for the specified anchoring mode + pcre* Compile(Anchor anchor); + + string pattern_; + RE_Options options_; + pcre* re_full_; // For full matches + pcre* re_partial_; // For partial matches + const string* error_; // Error indicator (or points to empty string) +}; + +} // namespace pcrecpp + +#endif /* _PCRECPP_H */ diff --git a/tools/pcre/pcrecpp_internal.h b/tools/pcre/pcrecpp_internal.h new file mode 100644 index 00000000..827f9e04 --- /dev/null +++ b/tools/pcre/pcrecpp_internal.h @@ -0,0 +1,71 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +Copyright (c) 2005, Google Inc. +All rights reserved. + +----------------------------------------------------------------------------- +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. +----------------------------------------------------------------------------- +*/ + + +#ifndef PCRECPP_INTERNAL_H +#define PCRECPP_INTERNAL_H + +/* When compiling a DLL for Windows, the exported symbols have to be declared +using some MS magic. I found some useful information on this web page: +http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the +information there, using __declspec(dllexport) without "extern" we have a +definition; with "extern" we have a declaration. The settings here override the +setting in pcre.h. We use: + + PCRECPP_EXP_DECL for declarations + PCRECPP_EXP_DEFN for definitions of exported functions + +*/ + +#ifndef PCRECPP_EXP_DECL +# ifdef _WIN32 +# ifndef PCRE_STATIC +# define PCRECPP_EXP_DECL extern __declspec(dllexport) +# define PCRECPP_EXP_DEFN __declspec(dllexport) +# else +# define PCRECPP_EXP_DECL extern +# define PCRECPP_EXP_DEFN +# endif +# else +# define PCRECPP_EXP_DECL extern +# define PCRECPP_EXP_DEFN +# endif +#endif + +#endif /* PCRECPP_INTERNAL_H */ + +/* End of pcrecpp_internal.h */ diff --git a/tools/pcre/pcrecpp_unittest.cc b/tools/pcre/pcrecpp_unittest.cc new file mode 100644 index 00000000..92cae8fb --- /dev/null +++ b/tools/pcre/pcrecpp_unittest.cc @@ -0,0 +1,1291 @@ +// -*- coding: utf-8 -*- +// +// Copyright (c) 2005 - 2010, Google Inc. +// All rights reserved. +// +// 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 Google Inc. 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. +// +// Author: Sanjay Ghemawat +// +// TODO: Test extractions for PartialMatch/Consume + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include /* for memset and strcmp */ +#include +#include +#include "pcrecpp.h" + +using pcrecpp::StringPiece; +using pcrecpp::RE; +using pcrecpp::RE_Options; +using pcrecpp::Hex; +using pcrecpp::Octal; +using pcrecpp::CRadix; + +static bool VERBOSE_TEST = false; + +// CHECK dies with a fatal error if condition is not true. It is *not* +// controlled by NDEBUG, so the check will be executed regardless of +// compilation mode. Therefore, it is safe to do things like: +// CHECK_EQ(fp->Write(x), 4) +#define CHECK(condition) do { \ + if (!(condition)) { \ + fprintf(stderr, "%s:%d: Check failed: %s\n", \ + __FILE__, __LINE__, #condition); \ + exit(1); \ + } \ +} while (0) + +#define CHECK_EQ(a, b) CHECK(a == b) + +static void Timing1(int num_iters) { + // Same pattern lots of times + RE pattern("ruby:\\d+"); + StringPiece p("ruby:1234"); + for (int j = num_iters; j > 0; j--) { + CHECK(pattern.FullMatch(p)); + } +} + +static void Timing2(int num_iters) { + // Same pattern lots of times + RE pattern("ruby:(\\d+)"); + int i; + for (int j = num_iters; j > 0; j--) { + CHECK(pattern.FullMatch("ruby:1234", &i)); + CHECK_EQ(i, 1234); + } +} + +static void Timing3(int num_iters) { + string text_string; + for (int j = num_iters; j > 0; j--) { + text_string += "this is another line\n"; + } + + RE line_matcher(".*\n"); + string line; + StringPiece text(text_string); + int counter = 0; + while (line_matcher.Consume(&text)) { + counter++; + } + printf("Matched %d lines\n", counter); +} + +#if 0 // uncomment this if you have a way of defining VirtualProcessSize() + +static void LeakTest() { + // Check for memory leaks + unsigned long long initial_size = 0; + for (int i = 0; i < 100000; i++) { + if (i == 50000) { + initial_size = VirtualProcessSize(); + printf("Size after 50000: %llu\n", initial_size); + } + char buf[100]; // definitely big enough + sprintf(buf, "pat%09d", i); + RE newre(buf); + } + uint64 final_size = VirtualProcessSize(); + printf("Size after 100000: %llu\n", final_size); + const double growth = double(final_size - initial_size) / final_size; + printf("Growth: %0.2f%%", growth * 100); + CHECK(growth < 0.02); // Allow < 2% growth +} + +#endif + +static void RadixTests() { + printf("Testing hex\n"); + +#define CHECK_HEX(type, value) \ + do { \ + type v; \ + CHECK(RE("([0-9a-fA-F]+)[uUlL]*").FullMatch(#value, Hex(&v))); \ + CHECK_EQ(v, 0x ## value); \ + CHECK(RE("([0-9a-fA-FxX]+)[uUlL]*").FullMatch("0x" #value, CRadix(&v))); \ + CHECK_EQ(v, 0x ## value); \ + } while(0) + + CHECK_HEX(short, 2bad); + CHECK_HEX(unsigned short, 2badU); + CHECK_HEX(int, dead); + CHECK_HEX(unsigned int, deadU); + CHECK_HEX(long, 7eadbeefL); + CHECK_HEX(unsigned long, deadbeefUL); +#ifdef HAVE_LONG_LONG + CHECK_HEX(long long, 12345678deadbeefLL); +#endif +#ifdef HAVE_UNSIGNED_LONG_LONG + CHECK_HEX(unsigned long long, cafebabedeadbeefULL); +#endif + +#undef CHECK_HEX + + printf("Testing octal\n"); + +#define CHECK_OCTAL(type, value) \ + do { \ + type v; \ + CHECK(RE("([0-7]+)[uUlL]*").FullMatch(#value, Octal(&v))); \ + CHECK_EQ(v, 0 ## value); \ + CHECK(RE("([0-9a-fA-FxX]+)[uUlL]*").FullMatch("0" #value, CRadix(&v))); \ + CHECK_EQ(v, 0 ## value); \ + } while(0) + + CHECK_OCTAL(short, 77777); + CHECK_OCTAL(unsigned short, 177777U); + CHECK_OCTAL(int, 17777777777); + CHECK_OCTAL(unsigned int, 37777777777U); + CHECK_OCTAL(long, 17777777777L); + CHECK_OCTAL(unsigned long, 37777777777UL); +#ifdef HAVE_LONG_LONG + CHECK_OCTAL(long long, 777777777777777777777LL); +#endif +#ifdef HAVE_UNSIGNED_LONG_LONG + CHECK_OCTAL(unsigned long long, 1777777777777777777777ULL); +#endif + +#undef CHECK_OCTAL + + printf("Testing decimal\n"); + +#define CHECK_DECIMAL(type, value) \ + do { \ + type v; \ + CHECK(RE("(-?[0-9]+)[uUlL]*").FullMatch(#value, &v)); \ + CHECK_EQ(v, value); \ + CHECK(RE("(-?[0-9a-fA-FxX]+)[uUlL]*").FullMatch(#value, CRadix(&v))); \ + CHECK_EQ(v, value); \ + } while(0) + + CHECK_DECIMAL(short, -1); + CHECK_DECIMAL(unsigned short, 9999); + CHECK_DECIMAL(int, -1000); + CHECK_DECIMAL(unsigned int, 12345U); + CHECK_DECIMAL(long, -10000000L); + CHECK_DECIMAL(unsigned long, 3083324652U); +#ifdef HAVE_LONG_LONG + CHECK_DECIMAL(long long, -100000000000000LL); +#endif +#ifdef HAVE_UNSIGNED_LONG_LONG + CHECK_DECIMAL(unsigned long long, 1234567890987654321ULL); +#endif + +#undef CHECK_DECIMAL + +} + +static void TestReplace() { + printf("Testing Replace\n"); + + struct ReplaceTest { + const char *regexp; + const char *rewrite; + const char *original; + const char *single; + const char *global; + int global_count; // the expected return value from ReplaceAll + }; + static const ReplaceTest tests[] = { + { "(qu|[b-df-hj-np-tv-z]*)([a-z]+)", + "\\2\\1ay", + "the quick brown fox jumps over the lazy dogs.", + "ethay quick brown fox jumps over the lazy dogs.", + "ethay ickquay ownbray oxfay umpsjay overay ethay azylay ogsday.", + 9 }, + { "\\w+", + "\\0-NOSPAM", + "paul.haahr@google.com", + "paul-NOSPAM.haahr@google.com", + "paul-NOSPAM.haahr-NOSPAM@google-NOSPAM.com-NOSPAM", + 4 }, + { "^", + "(START)", + "foo", + "(START)foo", + "(START)foo", + 1 }, + { "^", + "(START)", + "", + "(START)", + "(START)", + 1 }, + { "$", + "(END)", + "", + "(END)", + "(END)", + 1 }, + { "b", + "bb", + "ababababab", + "abbabababab", + "abbabbabbabbabb", + 5 }, + { "b", + "bb", + "bbbbbb", + "bbbbbbb", + "bbbbbbbbbbbb", + 6 }, + { "b+", + "bb", + "bbbbbb", + "bb", + "bb", + 1 }, + { "b*", + "bb", + "bbbbbb", + "bb", + "bbbb", + 2 }, + { "b*", + "bb", + "aaaaa", + "bbaaaaa", + "bbabbabbabbabbabb", + 6 }, + { "b*", + "bb", + "aa\naa\n", + "bbaa\naa\n", + "bbabbabb\nbbabbabb\nbb", + 7 }, + { "b*", + "bb", + "aa\raa\r", + "bbaa\raa\r", + "bbabbabb\rbbabbabb\rbb", + 7 }, + { "b*", + "bb", + "aa\r\naa\r\n", + "bbaa\r\naa\r\n", + "bbabbabb\r\nbbabbabb\r\nbb", + 7 }, + // Check empty-string matching (it's tricky!) + { "aa|b*", + "@", + "aa", + "@", + "@@", + 2 }, + { "b*|aa", + "@", + "aa", + "@aa", + "@@@", + 3 }, +#ifdef SUPPORT_UTF8 + { "b*", + "bb", + "\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8", // utf8 + "bb\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8", + "bb\xE3\x83\x9B""bb""\xE3\x83\xBC""bb""\xE3\x83\xA0""bb""\xE3\x81\xB8""bb", + 5 }, + { "b*", + "bb", + "\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n", // utf8 + "bb\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n", + ("bb\xE3\x83\x9B""bb\r\nbb""\xE3\x83\xBC""bb\rbb""\xE3\x83\xA0" + "bb\nbb""\xE3\x81\xB8""bb\r\nbb"), + 9 }, +#endif + { "", NULL, NULL, NULL, NULL, 0 } + }; + +#ifdef SUPPORT_UTF8 + const bool support_utf8 = true; +#else + const bool support_utf8 = false; +#endif + + for (const ReplaceTest *t = tests; t->original != NULL; ++t) { + RE re(t->regexp, RE_Options(PCRE_NEWLINE_CRLF).set_utf8(support_utf8)); + assert(re.error().empty()); + string one(t->original); + CHECK(re.Replace(t->rewrite, &one)); + CHECK_EQ(one, t->single); + string all(t->original); + const int replace_count = re.GlobalReplace(t->rewrite, &all); + CHECK_EQ(all, t->global); + CHECK_EQ(replace_count, t->global_count); + } + + // One final test: test \r\n replacement when we're not in CRLF mode + { + RE re("b*", RE_Options(PCRE_NEWLINE_CR).set_utf8(support_utf8)); + assert(re.error().empty()); + string all("aa\r\naa\r\n"); + CHECK_EQ(re.GlobalReplace("bb", &all), 9); + CHECK_EQ(all, string("bbabbabb\rbb\nbbabbabb\rbb\nbb")); + } + { + RE re("b*", RE_Options(PCRE_NEWLINE_LF).set_utf8(support_utf8)); + assert(re.error().empty()); + string all("aa\r\naa\r\n"); + CHECK_EQ(re.GlobalReplace("bb", &all), 9); + CHECK_EQ(all, string("bbabbabb\rbb\nbbabbabb\rbb\nbb")); + } + // TODO: test what happens when no PCRE_NEWLINE_* flag is set. + // Alas, the answer depends on how pcre was compiled. +} + +static void TestExtract() { + printf("Testing Extract\n"); + + string s; + + CHECK(RE("(.*)@([^.]*)").Extract("\\2!\\1", "boris@kremvax.ru", &s)); + CHECK_EQ(s, "kremvax!boris"); + + // check the RE interface as well + CHECK(RE(".*").Extract("'\\0'", "foo", &s)); + CHECK_EQ(s, "'foo'"); + CHECK(!RE("bar").Extract("'\\0'", "baz", &s)); + CHECK_EQ(s, "'foo'"); +} + +static void TestConsume() { + printf("Testing Consume\n"); + + string word; + + string s(" aaa b!@#$@#$cccc"); + StringPiece input(s); + + RE r("\\s*(\\w+)"); // matches a word, possibly proceeded by whitespace + CHECK(r.Consume(&input, &word)); + CHECK_EQ(word, "aaa"); + CHECK(r.Consume(&input, &word)); + CHECK_EQ(word, "b"); + CHECK(! r.Consume(&input, &word)); +} + +static void TestFindAndConsume() { + printf("Testing FindAndConsume\n"); + + string word; + + string s(" aaa b!@#$@#$cccc"); + StringPiece input(s); + + RE r("(\\w+)"); // matches a word + CHECK(r.FindAndConsume(&input, &word)); + CHECK_EQ(word, "aaa"); + CHECK(r.FindAndConsume(&input, &word)); + CHECK_EQ(word, "b"); + CHECK(r.FindAndConsume(&input, &word)); + CHECK_EQ(word, "cccc"); + CHECK(! r.FindAndConsume(&input, &word)); +} + +static void TestMatchNumberPeculiarity() { + printf("Testing match-number peculiarity\n"); + + string word1; + string word2; + string word3; + + RE r("(foo)|(bar)|(baz)"); + CHECK(r.PartialMatch("foo", &word1, &word2, &word3)); + CHECK_EQ(word1, "foo"); + CHECK_EQ(word2, ""); + CHECK_EQ(word3, ""); + CHECK(r.PartialMatch("bar", &word1, &word2, &word3)); + CHECK_EQ(word1, ""); + CHECK_EQ(word2, "bar"); + CHECK_EQ(word3, ""); + CHECK(r.PartialMatch("baz", &word1, &word2, &word3)); + CHECK_EQ(word1, ""); + CHECK_EQ(word2, ""); + CHECK_EQ(word3, "baz"); + CHECK(!r.PartialMatch("f", &word1, &word2, &word3)); + + string a; + CHECK(RE("(foo)|hello").FullMatch("hello", &a)); + CHECK_EQ(a, ""); +} + +static void TestRecursion() { + printf("Testing recursion\n"); + + // Get one string that passes (sometimes), one that never does. + string text_good("abcdefghijk"); + string text_bad("acdefghijkl"); + + // According to pcretest, matching text_good against (\w+)*b + // requires match_limit of at least 8192, and match_recursion_limit + // of at least 37. + + RE_Options options_ml; + options_ml.set_match_limit(8192); + RE re("(\\w+)*b", options_ml); + CHECK(re.PartialMatch(text_good) == true); + CHECK(re.PartialMatch(text_bad) == false); + CHECK(re.FullMatch(text_good) == false); + CHECK(re.FullMatch(text_bad) == false); + + options_ml.set_match_limit(1024); + RE re2("(\\w+)*b", options_ml); + CHECK(re2.PartialMatch(text_good) == false); // because of match_limit + CHECK(re2.PartialMatch(text_bad) == false); + CHECK(re2.FullMatch(text_good) == false); + CHECK(re2.FullMatch(text_bad) == false); + + RE_Options options_mlr; + options_mlr.set_match_limit_recursion(50); + RE re3("(\\w+)*b", options_mlr); + CHECK(re3.PartialMatch(text_good) == true); + CHECK(re3.PartialMatch(text_bad) == false); + CHECK(re3.FullMatch(text_good) == false); + CHECK(re3.FullMatch(text_bad) == false); + + options_mlr.set_match_limit_recursion(10); + RE re4("(\\w+)*b", options_mlr); + CHECK(re4.PartialMatch(text_good) == false); + CHECK(re4.PartialMatch(text_bad) == false); + CHECK(re4.FullMatch(text_good) == false); + CHECK(re4.FullMatch(text_bad) == false); +} + +// A meta-quoted string, interpreted as a pattern, should always match +// the original unquoted string. +static void TestQuoteMeta(string unquoted, RE_Options options = RE_Options()) { + string quoted = RE::QuoteMeta(unquoted); + RE re(quoted, options); + CHECK(re.FullMatch(unquoted)); +} + +// A string containing meaningful regexp characters, which is then meta- +// quoted, should not generally match a string the unquoted string does. +static void NegativeTestQuoteMeta(string unquoted, string should_not_match, + RE_Options options = RE_Options()) { + string quoted = RE::QuoteMeta(unquoted); + RE re(quoted, options); + CHECK(!re.FullMatch(should_not_match)); +} + +// Tests that quoted meta characters match their original strings, +// and that a few things that shouldn't match indeed do not. +static void TestQuotaMetaSimple() { + TestQuoteMeta("foo"); + TestQuoteMeta("foo.bar"); + TestQuoteMeta("foo\\.bar"); + TestQuoteMeta("[1-9]"); + TestQuoteMeta("1.5-2.0?"); + TestQuoteMeta("\\d"); + TestQuoteMeta("Who doesn't like ice cream?"); + TestQuoteMeta("((a|b)c?d*e+[f-h]i)"); + TestQuoteMeta("((?!)xxx).*yyy"); + TestQuoteMeta("(["); + TestQuoteMeta(string("foo\0bar", 7)); +} + +static void TestQuoteMetaSimpleNegative() { + NegativeTestQuoteMeta("foo", "bar"); + NegativeTestQuoteMeta("...", "bar"); + NegativeTestQuoteMeta("\\.", "."); + NegativeTestQuoteMeta("\\.", ".."); + NegativeTestQuoteMeta("(a)", "a"); + NegativeTestQuoteMeta("(a|b)", "a"); + NegativeTestQuoteMeta("(a|b)", "(a)"); + NegativeTestQuoteMeta("(a|b)", "a|b"); + NegativeTestQuoteMeta("[0-9]", "0"); + NegativeTestQuoteMeta("[0-9]", "0-9"); + NegativeTestQuoteMeta("[0-9]", "[9]"); + NegativeTestQuoteMeta("((?!)xxx)", "xxx"); +} + +static void TestQuoteMetaLatin1() { + TestQuoteMeta("3\xb2 = 9"); +} + +static void TestQuoteMetaUtf8() { +#ifdef SUPPORT_UTF8 + TestQuoteMeta("Pl\xc3\xa1\x63ido Domingo", pcrecpp::UTF8()); + TestQuoteMeta("xyz", pcrecpp::UTF8()); // No fancy utf8 + TestQuoteMeta("\xc2\xb0", pcrecpp::UTF8()); // 2-byte utf8 (degree symbol) + TestQuoteMeta("27\xc2\xb0 degrees", pcrecpp::UTF8()); // As a middle character + TestQuoteMeta("\xe2\x80\xb3", pcrecpp::UTF8()); // 3-byte utf8 (double prime) + TestQuoteMeta("\xf0\x9d\x85\x9f", pcrecpp::UTF8()); // 4-byte utf8 (music note) + TestQuoteMeta("27\xc2\xb0"); // Interpreted as Latin-1, but should still work + NegativeTestQuoteMeta("27\xc2\xb0", // 2-byte utf (degree symbol) + "27\\\xc2\\\xb0", + pcrecpp::UTF8()); +#endif +} + +static void TestQuoteMetaAll() { + printf("Testing QuoteMeta\n"); + TestQuotaMetaSimple(); + TestQuoteMetaSimpleNegative(); + TestQuoteMetaLatin1(); + TestQuoteMetaUtf8(); +} + +// +// Options tests contributed by +// Giuseppe Maxia, CTO, Stardata s.r.l. +// July 2005 +// +static void GetOneOptionResult( + const char *option_name, + const char *regex, + const char *str, + RE_Options options, + bool full, + string expected) { + + printf("Testing Option <%s>\n", option_name); + if(VERBOSE_TEST) + printf("/%s/ finds \"%s\" within \"%s\" \n", + regex, + expected.c_str(), + str); + string captured(""); + if (full) + RE(regex,options).FullMatch(str, &captured); + else + RE(regex,options).PartialMatch(str, &captured); + CHECK_EQ(captured, expected); +} + +static void TestOneOption( + const char *option_name, + const char *regex, + const char *str, + RE_Options options, + bool full, + bool assertive = true) { + + printf("Testing Option <%s>\n", option_name); + if (VERBOSE_TEST) + printf("'%s' %s /%s/ \n", + str, + (assertive? "matches" : "doesn't match"), + regex); + if (assertive) { + if (full) + CHECK(RE(regex,options).FullMatch(str)); + else + CHECK(RE(regex,options).PartialMatch(str)); + } else { + if (full) + CHECK(!RE(regex,options).FullMatch(str)); + else + CHECK(!RE(regex,options).PartialMatch(str)); + } +} + +static void Test_CASELESS() { + RE_Options options; + RE_Options options2; + + options.set_caseless(true); + TestOneOption("CASELESS (class)", "HELLO", "hello", options, false); + TestOneOption("CASELESS (class2)", "HELLO", "hello", options2.set_caseless(true), false); + TestOneOption("CASELESS (class)", "^[A-Z]+$", "Hello", options, false); + + TestOneOption("CASELESS (function)", "HELLO", "hello", pcrecpp::CASELESS(), false); + TestOneOption("CASELESS (function)", "^[A-Z]+$", "Hello", pcrecpp::CASELESS(), false); + options.set_caseless(false); + TestOneOption("no CASELESS", "HELLO", "hello", options, false, false); +} + +static void Test_MULTILINE() { + RE_Options options; + RE_Options options2; + const char *str = "HELLO\n" "cruel\n" "world\n"; + + options.set_multiline(true); + TestOneOption("MULTILINE (class)", "^cruel$", str, options, false); + TestOneOption("MULTILINE (class2)", "^cruel$", str, options2.set_multiline(true), false); + TestOneOption("MULTILINE (function)", "^cruel$", str, pcrecpp::MULTILINE(), false); + options.set_multiline(false); + TestOneOption("no MULTILINE", "^cruel$", str, options, false, false); +} + +static void Test_DOTALL() { + RE_Options options; + RE_Options options2; + const char *str = "HELLO\n" "cruel\n" "world"; + + options.set_dotall(true); + TestOneOption("DOTALL (class)", "HELLO.*world", str, options, true); + TestOneOption("DOTALL (class2)", "HELLO.*world", str, options2.set_dotall(true), true); + TestOneOption("DOTALL (function)", "HELLO.*world", str, pcrecpp::DOTALL(), true); + options.set_dotall(false); + TestOneOption("no DOTALL", "HELLO.*world", str, options, true, false); +} + +static void Test_DOLLAR_ENDONLY() { + RE_Options options; + RE_Options options2; + const char *str = "HELLO world\n"; + + TestOneOption("no DOLLAR_ENDONLY", "world$", str, options, false); + options.set_dollar_endonly(true); + TestOneOption("DOLLAR_ENDONLY 1", "world$", str, options, false, false); + TestOneOption("DOLLAR_ENDONLY 2", "world$", str, options2.set_dollar_endonly(true), false, false); +} + +static void Test_EXTRA() { + RE_Options options; + const char *str = "HELLO"; + + options.set_extra(true); + TestOneOption("EXTRA 1", "\\HELL\\O", str, options, true, false ); + TestOneOption("EXTRA 2", "\\HELL\\O", str, RE_Options().set_extra(true), true, false ); + options.set_extra(false); + TestOneOption("no EXTRA", "\\HELL\\O", str, options, true ); +} + +static void Test_EXTENDED() { + RE_Options options; + RE_Options options2; + const char *str = "HELLO world"; + + options.set_extended(true); + TestOneOption("EXTENDED (class)", "HELLO world", str, options, false, false); + TestOneOption("EXTENDED (class2)", "HELLO world", str, options2.set_extended(true), false, false); + TestOneOption("EXTENDED (class)", + "^ HE L{2} O " + "\\s+ " + "\\w+ $ ", + str, + options, + false); + + TestOneOption("EXTENDED (function)", "HELLO world", str, pcrecpp::EXTENDED(), false, false); + TestOneOption("EXTENDED (function)", + "^ HE L{2} O " + "\\s+ " + "\\w+ $ ", + str, + pcrecpp::EXTENDED(), + false); + + options.set_extended(false); + TestOneOption("no EXTENDED", "HELLO world", str, options, false); +} + +static void Test_NO_AUTO_CAPTURE() { + RE_Options options; + const char *str = "HELLO world"; + string captured; + + printf("Testing Option \n"); + if (VERBOSE_TEST) + printf("parentheses capture text\n"); + RE re("(world|universe)$", options); + CHECK(re.Extract("\\1", str , &captured)); + CHECK_EQ(captured, "world"); + options.set_no_auto_capture(true); + printf("testing Option \n"); + if (VERBOSE_TEST) + printf("parentheses do not capture text\n"); + re.Extract("\\1",str, &captured ); + CHECK_EQ(captured, "world"); +} + +static void Test_UNGREEDY() { + RE_Options options; + const char *str = "HELLO, 'this' is the 'world'"; + + options.set_ungreedy(true); + GetOneOptionResult("UNGREEDY 1", "('.*')", str, options, false, "'this'" ); + GetOneOptionResult("UNGREEDY 2", "('.*')", str, RE_Options().set_ungreedy(true), false, "'this'" ); + GetOneOptionResult("UNGREEDY", "('.*?')", str, options, false, "'this' is the 'world'" ); + + options.set_ungreedy(false); + GetOneOptionResult("no UNGREEDY", "('.*')", str, options, false, "'this' is the 'world'" ); + GetOneOptionResult("no UNGREEDY", "('.*?')", str, options, false, "'this'" ); +} + +static void Test_all_options() { + const char *str = "HELLO\n" "cruel\n" "world"; + RE_Options options; + options.set_all_options(PCRE_CASELESS | PCRE_DOTALL); + + TestOneOption("all_options (CASELESS|DOTALL)", "^hello.*WORLD", str , options, false); + options.set_all_options(0); + TestOneOption("all_options (0)", "^hello.*WORLD", str , options, false, false); + options.set_all_options(PCRE_MULTILINE | PCRE_EXTENDED); + + TestOneOption("all_options (MULTILINE|EXTENDED)", " ^ c r u e l $ ", str, options, false); + TestOneOption("all_options (MULTILINE|EXTENDED) with constructor", + " ^ c r u e l $ ", + str, + RE_Options(PCRE_MULTILINE | PCRE_EXTENDED), + false); + + TestOneOption("all_options (MULTILINE|EXTENDED) with concatenation", + " ^ c r u e l $ ", + str, + RE_Options() + .set_multiline(true) + .set_extended(true), + false); + + options.set_all_options(0); + TestOneOption("all_options (0)", "^ c r u e l $", str, options, false, false); + +} + +static void TestOptions() { + printf("Testing Options\n"); + Test_CASELESS(); + Test_MULTILINE(); + Test_DOTALL(); + Test_DOLLAR_ENDONLY(); + Test_EXTENDED(); + Test_NO_AUTO_CAPTURE(); + Test_UNGREEDY(); + Test_EXTRA(); + Test_all_options(); +} + +static void TestConstructors() { + printf("Testing constructors\n"); + + RE_Options options; + options.set_dotall(true); + const char *str = "HELLO\n" "cruel\n" "world"; + + RE orig("HELLO.*world", options); + CHECK(orig.FullMatch(str)); + + RE copy1(orig); + CHECK(copy1.FullMatch(str)); + + RE copy2("not a match"); + CHECK(!copy2.FullMatch(str)); + copy2 = copy1; + CHECK(copy2.FullMatch(str)); + copy2 = orig; + CHECK(copy2.FullMatch(str)); + + // Make sure when we assign to ourselves, nothing bad happens + orig = orig; + copy1 = copy1; + copy2 = copy2; + CHECK(orig.FullMatch(str)); + CHECK(copy1.FullMatch(str)); + CHECK(copy2.FullMatch(str)); +} + +int main(int argc, char** argv) { + // Treat any flag as --help + if (argc > 1 && argv[1][0] == '-') { + printf("Usage: %s [timing1|timing2|timing3 num-iters]\n" + " If 'timingX ###' is specified, run the given timing test\n" + " with the given number of iterations, rather than running\n" + " the default corectness test.\n", argv[0]); + return 0; + } + + if (argc > 1) { + if ( argc == 2 || atoi(argv[2]) == 0) { + printf("timing mode needs a num-iters argument\n"); + return 1; + } + if (!strcmp(argv[1], "timing1")) + Timing1(atoi(argv[2])); + else if (!strcmp(argv[1], "timing2")) + Timing2(atoi(argv[2])); + else if (!strcmp(argv[1], "timing3")) + Timing3(atoi(argv[2])); + else + printf("Unknown argument '%s'\n", argv[1]); + return 0; + } + + printf("PCRE C++ wrapper tests\n"); + printf("Testing FullMatch\n"); + + int i; + string s; + + /***** FullMatch with no args *****/ + + CHECK(RE("h.*o").FullMatch("hello")); + CHECK(!RE("h.*o").FullMatch("othello")); // Must be anchored at front + CHECK(!RE("h.*o").FullMatch("hello!")); // Must be anchored at end + CHECK(RE("a*").FullMatch("aaaa")); // Fullmatch with normal op + CHECK(RE("a*?").FullMatch("aaaa")); // Fullmatch with nongreedy op + CHECK(RE("a*?\\z").FullMatch("aaaa")); // Two unusual ops + + /***** FullMatch with args *****/ + + // Zero-arg + CHECK(RE("\\d+").FullMatch("1001")); + + // Single-arg + CHECK(RE("(\\d+)").FullMatch("1001", &i)); + CHECK_EQ(i, 1001); + CHECK(RE("(-?\\d+)").FullMatch("-123", &i)); + CHECK_EQ(i, -123); + CHECK(!RE("()\\d+").FullMatch("10", &i)); + CHECK(!RE("(\\d+)").FullMatch("1234567890123456789012345678901234567890", + &i)); + + // Digits surrounding integer-arg + CHECK(RE("1(\\d*)4").FullMatch("1234", &i)); + CHECK_EQ(i, 23); + CHECK(RE("(\\d)\\d+").FullMatch("1234", &i)); + CHECK_EQ(i, 1); + CHECK(RE("(-\\d)\\d+").FullMatch("-1234", &i)); + CHECK_EQ(i, -1); + CHECK(RE("(\\d)").PartialMatch("1234", &i)); + CHECK_EQ(i, 1); + CHECK(RE("(-\\d)").PartialMatch("-1234", &i)); + CHECK_EQ(i, -1); + + // String-arg + CHECK(RE("h(.*)o").FullMatch("hello", &s)); + CHECK_EQ(s, string("ell")); + + // StringPiece-arg + StringPiece sp; + CHECK(RE("(\\w+):(\\d+)").FullMatch("ruby:1234", &sp, &i)); + CHECK_EQ(sp.size(), 4); + CHECK(memcmp(sp.data(), "ruby", 4) == 0); + CHECK_EQ(i, 1234); + + // Multi-arg + CHECK(RE("(\\w+):(\\d+)").FullMatch("ruby:1234", &s, &i)); + CHECK_EQ(s, string("ruby")); + CHECK_EQ(i, 1234); + + // Ignore non-void* NULL arg + CHECK(RE("he(.*)lo").FullMatch("hello", (char*)NULL)); + CHECK(RE("h(.*)o").FullMatch("hello", (string*)NULL)); + CHECK(RE("h(.*)o").FullMatch("hello", (StringPiece*)NULL)); + CHECK(RE("(.*)").FullMatch("1234", (int*)NULL)); +#ifdef HAVE_LONG_LONG + CHECK(RE("(.*)").FullMatch("1234567890123456", (long long*)NULL)); +#endif + CHECK(RE("(.*)").FullMatch("123.4567890123456", (double*)NULL)); + CHECK(RE("(.*)").FullMatch("123.4567890123456", (float*)NULL)); + + // Fail on non-void* NULL arg if the match doesn't parse for the given type. + CHECK(!RE("h(.*)lo").FullMatch("hello", &s, (char*)NULL)); + CHECK(!RE("(.*)").FullMatch("hello", (int*)NULL)); + CHECK(!RE("(.*)").FullMatch("1234567890123456", (int*)NULL)); + CHECK(!RE("(.*)").FullMatch("hello", (double*)NULL)); + CHECK(!RE("(.*)").FullMatch("hello", (float*)NULL)); + + // Ignored arg + CHECK(RE("(\\w+)(:)(\\d+)").FullMatch("ruby:1234", &s, (void*)NULL, &i)); + CHECK_EQ(s, string("ruby")); + CHECK_EQ(i, 1234); + + // Type tests + { + char c; + CHECK(RE("(H)ello").FullMatch("Hello", &c)); + CHECK_EQ(c, 'H'); + } + { + unsigned char c; + CHECK(RE("(H)ello").FullMatch("Hello", &c)); + CHECK_EQ(c, static_cast('H')); + } + { + short v; + CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); + CHECK(RE("(-?\\d+)").FullMatch("-100", &v)); CHECK_EQ(v, -100); + CHECK(RE("(-?\\d+)").FullMatch("32767", &v)); CHECK_EQ(v, 32767); + CHECK(RE("(-?\\d+)").FullMatch("-32768", &v)); CHECK_EQ(v, -32768); + CHECK(!RE("(-?\\d+)").FullMatch("-32769", &v)); + CHECK(!RE("(-?\\d+)").FullMatch("32768", &v)); + } + { + unsigned short v; + CHECK(RE("(\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); + CHECK(RE("(\\d+)").FullMatch("32767", &v)); CHECK_EQ(v, 32767); + CHECK(RE("(\\d+)").FullMatch("65535", &v)); CHECK_EQ(v, 65535); + CHECK(!RE("(\\d+)").FullMatch("65536", &v)); + } + { + int v; + static const int max_value = 0x7fffffff; + static const int min_value = -max_value - 1; + CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); + CHECK(RE("(-?\\d+)").FullMatch("-100", &v)); CHECK_EQ(v, -100); + CHECK(RE("(-?\\d+)").FullMatch("2147483647", &v)); CHECK_EQ(v, max_value); + CHECK(RE("(-?\\d+)").FullMatch("-2147483648", &v)); CHECK_EQ(v, min_value); + CHECK(!RE("(-?\\d+)").FullMatch("-2147483649", &v)); + CHECK(!RE("(-?\\d+)").FullMatch("2147483648", &v)); + } + { + unsigned int v; + static const unsigned int max_value = 0xfffffffful; + CHECK(RE("(\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); + CHECK(RE("(\\d+)").FullMatch("4294967295", &v)); CHECK_EQ(v, max_value); + CHECK(!RE("(\\d+)").FullMatch("4294967296", &v)); + } +#ifdef HAVE_LONG_LONG +# if defined(__MINGW__) || defined(__MINGW32__) +# define LLD "%I64d" +# define LLU "%I64u" +# else +# define LLD "%lld" +# define LLU "%llu" +# endif + { + long long v; + static const long long max_value = 0x7fffffffffffffffLL; + static const long long min_value = -max_value - 1; + char buf[32]; // definitely big enough for a long long + + CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100); + CHECK(RE("(-?\\d+)").FullMatch("-100",&v)); CHECK_EQ(v, -100); + + sprintf(buf, LLD, max_value); + CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, max_value); + + sprintf(buf, LLD, min_value); + CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, min_value); + + sprintf(buf, LLD, max_value); + assert(buf[strlen(buf)-1] != '9'); + buf[strlen(buf)-1]++; + CHECK(!RE("(-?\\d+)").FullMatch(buf, &v)); + + sprintf(buf, LLD, min_value); + assert(buf[strlen(buf)-1] != '9'); + buf[strlen(buf)-1]++; + CHECK(!RE("(-?\\d+)").FullMatch(buf, &v)); + } +#endif +#if defined HAVE_UNSIGNED_LONG_LONG && defined HAVE_LONG_LONG + { + unsigned long long v; + long long v2; + static const unsigned long long max_value = 0xffffffffffffffffULL; + char buf[32]; // definitely big enough for a unsigned long long + + CHECK(RE("(-?\\d+)").FullMatch("100",&v)); CHECK_EQ(v, 100); + CHECK(RE("(-?\\d+)").FullMatch("-100",&v2)); CHECK_EQ(v2, -100); + + sprintf(buf, LLU, max_value); + CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, max_value); + + assert(buf[strlen(buf)-1] != '9'); + buf[strlen(buf)-1]++; + CHECK(!RE("(-?\\d+)").FullMatch(buf, &v)); + } +#endif + { + float v; + CHECK(RE("(.*)").FullMatch("100", &v)); + CHECK(RE("(.*)").FullMatch("-100.", &v)); + CHECK(RE("(.*)").FullMatch("1e23", &v)); + } + { + double v; + CHECK(RE("(.*)").FullMatch("100", &v)); + CHECK(RE("(.*)").FullMatch("-100.", &v)); + CHECK(RE("(.*)").FullMatch("1e23", &v)); + } + + // Check that matching is fully anchored + CHECK(!RE("(\\d+)").FullMatch("x1001", &i)); + CHECK(!RE("(\\d+)").FullMatch("1001x", &i)); + CHECK(RE("x(\\d+)").FullMatch("x1001", &i)); CHECK_EQ(i, 1001); + CHECK(RE("(\\d+)x").FullMatch("1001x", &i)); CHECK_EQ(i, 1001); + + // Braces + CHECK(RE("[0-9a-f+.-]{5,}").FullMatch("0abcd")); + CHECK(RE("[0-9a-f+.-]{5,}").FullMatch("0abcde")); + CHECK(!RE("[0-9a-f+.-]{5,}").FullMatch("0abc")); + + // Complicated RE + CHECK(RE("foo|bar|[A-Z]").FullMatch("foo")); + CHECK(RE("foo|bar|[A-Z]").FullMatch("bar")); + CHECK(RE("foo|bar|[A-Z]").FullMatch("X")); + CHECK(!RE("foo|bar|[A-Z]").FullMatch("XY")); + + // Check full-match handling (needs '$' tacked on internally) + CHECK(RE("fo|foo").FullMatch("fo")); + CHECK(RE("fo|foo").FullMatch("foo")); + CHECK(RE("fo|foo$").FullMatch("fo")); + CHECK(RE("fo|foo$").FullMatch("foo")); + CHECK(RE("foo$").FullMatch("foo")); + CHECK(!RE("foo\\$").FullMatch("foo$bar")); + CHECK(!RE("fo|bar").FullMatch("fox")); + + // Uncomment the following if we change the handling of '$' to + // prevent it from matching a trailing newline + if (false) { + // Check that we don't get bitten by pcre's special handling of a + // '\n' at the end of the string matching '$' + CHECK(!RE("foo$").PartialMatch("foo\n")); + } + + // Number of args + int a[16]; + CHECK(RE("").FullMatch("")); + + memset(a, 0, sizeof(0)); + CHECK(RE("(\\d){1}").FullMatch("1", + &a[0])); + CHECK_EQ(a[0], 1); + + memset(a, 0, sizeof(0)); + CHECK(RE("(\\d)(\\d)").FullMatch("12", + &a[0], &a[1])); + CHECK_EQ(a[0], 1); + CHECK_EQ(a[1], 2); + + memset(a, 0, sizeof(0)); + CHECK(RE("(\\d)(\\d)(\\d)").FullMatch("123", + &a[0], &a[1], &a[2])); + CHECK_EQ(a[0], 1); + CHECK_EQ(a[1], 2); + CHECK_EQ(a[2], 3); + + memset(a, 0, sizeof(0)); + CHECK(RE("(\\d)(\\d)(\\d)(\\d)").FullMatch("1234", + &a[0], &a[1], &a[2], &a[3])); + CHECK_EQ(a[0], 1); + CHECK_EQ(a[1], 2); + CHECK_EQ(a[2], 3); + CHECK_EQ(a[3], 4); + + memset(a, 0, sizeof(0)); + CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("12345", + &a[0], &a[1], &a[2], + &a[3], &a[4])); + CHECK_EQ(a[0], 1); + CHECK_EQ(a[1], 2); + CHECK_EQ(a[2], 3); + CHECK_EQ(a[3], 4); + CHECK_EQ(a[4], 5); + + memset(a, 0, sizeof(0)); + CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("123456", + &a[0], &a[1], &a[2], + &a[3], &a[4], &a[5])); + CHECK_EQ(a[0], 1); + CHECK_EQ(a[1], 2); + CHECK_EQ(a[2], 3); + CHECK_EQ(a[3], 4); + CHECK_EQ(a[4], 5); + CHECK_EQ(a[5], 6); + + memset(a, 0, sizeof(0)); + CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("1234567", + &a[0], &a[1], &a[2], &a[3], + &a[4], &a[5], &a[6])); + CHECK_EQ(a[0], 1); + CHECK_EQ(a[1], 2); + CHECK_EQ(a[2], 3); + CHECK_EQ(a[3], 4); + CHECK_EQ(a[4], 5); + CHECK_EQ(a[5], 6); + CHECK_EQ(a[6], 7); + + memset(a, 0, sizeof(0)); + CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)" + "(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch( + "1234567890123456", + &a[0], &a[1], &a[2], &a[3], + &a[4], &a[5], &a[6], &a[7], + &a[8], &a[9], &a[10], &a[11], + &a[12], &a[13], &a[14], &a[15])); + CHECK_EQ(a[0], 1); + CHECK_EQ(a[1], 2); + CHECK_EQ(a[2], 3); + CHECK_EQ(a[3], 4); + CHECK_EQ(a[4], 5); + CHECK_EQ(a[5], 6); + CHECK_EQ(a[6], 7); + CHECK_EQ(a[7], 8); + CHECK_EQ(a[8], 9); + CHECK_EQ(a[9], 0); + CHECK_EQ(a[10], 1); + CHECK_EQ(a[11], 2); + CHECK_EQ(a[12], 3); + CHECK_EQ(a[13], 4); + CHECK_EQ(a[14], 5); + CHECK_EQ(a[15], 6); + + /***** PartialMatch *****/ + + printf("Testing PartialMatch\n"); + + CHECK(RE("h.*o").PartialMatch("hello")); + CHECK(RE("h.*o").PartialMatch("othello")); + CHECK(RE("h.*o").PartialMatch("hello!")); + CHECK(RE("((((((((((((((((((((x))))))))))))))))))))").PartialMatch("x")); + + /***** other tests *****/ + + RadixTests(); + TestReplace(); + TestExtract(); + TestConsume(); + TestFindAndConsume(); + TestQuoteMetaAll(); + TestMatchNumberPeculiarity(); + + // Check the pattern() accessor + { + const string kPattern = "http://([^/]+)/.*"; + const RE re(kPattern); + CHECK_EQ(kPattern, re.pattern()); + } + + // Check RE error field. + { + RE re("foo"); + CHECK(re.error().empty()); // Must have no error + } + +#ifdef SUPPORT_UTF8 + // Check UTF-8 handling + { + printf("Testing UTF-8 handling\n"); + + // Three Japanese characters (nihongo) + const unsigned char utf8_string[] = { + 0xe6, 0x97, 0xa5, // 65e5 + 0xe6, 0x9c, 0xac, // 627c + 0xe8, 0xaa, 0x9e, // 8a9e + 0 + }; + const unsigned char utf8_pattern[] = { + '.', + 0xe6, 0x9c, 0xac, // 627c + '.', + 0 + }; + + // Both should match in either mode, bytes or UTF-8 + RE re_test1("........."); + CHECK(re_test1.FullMatch(utf8_string)); + RE re_test2("...", pcrecpp::UTF8()); + CHECK(re_test2.FullMatch(utf8_string)); + + // Check that '.' matches one byte or UTF-8 character + // according to the mode. + string ss; + RE re_test3("(.)"); + CHECK(re_test3.PartialMatch(utf8_string, &ss)); + CHECK_EQ(ss, string("\xe6")); + RE re_test4("(.)", pcrecpp::UTF8()); + CHECK(re_test4.PartialMatch(utf8_string, &ss)); + CHECK_EQ(ss, string("\xe6\x97\xa5")); + + // Check that string matches itself in either mode + RE re_test5(utf8_string); + CHECK(re_test5.FullMatch(utf8_string)); + RE re_test6(utf8_string, pcrecpp::UTF8()); + CHECK(re_test6.FullMatch(utf8_string)); + + // Check that pattern matches string only in UTF8 mode + RE re_test7(utf8_pattern); + CHECK(!re_test7.FullMatch(utf8_string)); + RE re_test8(utf8_pattern, pcrecpp::UTF8()); + CHECK(re_test8.FullMatch(utf8_string)); + } + + // Check that ungreedy, UTF8 regular expressions don't match when they + // oughtn't -- see bug 82246. + { + // This code always worked. + const char* pattern = "\\w+X"; + const string target = "a aX"; + RE match_sentence(pattern); + RE match_sentence_re(pattern, pcrecpp::UTF8()); + + CHECK(!match_sentence.FullMatch(target)); + CHECK(!match_sentence_re.FullMatch(target)); + } + + { + const char* pattern = "(?U)\\w+X"; + const string target = "a aX"; + RE match_sentence(pattern); + RE match_sentence_re(pattern, pcrecpp::UTF8()); + + CHECK(!match_sentence.FullMatch(target)); + CHECK(!match_sentence_re.FullMatch(target)); + } +#endif /* def SUPPORT_UTF8 */ + + printf("Testing error reporting\n"); + + { RE re("a\\1"); CHECK(!re.error().empty()); } + { + RE re("a[x"); + CHECK(!re.error().empty()); + } + { + RE re("a[z-a]"); + CHECK(!re.error().empty()); + } + { + RE re("a[[:foobar:]]"); + CHECK(!re.error().empty()); + } + { + RE re("a(b"); + CHECK(!re.error().empty()); + } + { + RE re("a\\"); + CHECK(!re.error().empty()); + } + + // Test that recursion is stopped + TestRecursion(); + + // Test Options + if (getenv("VERBOSE_TEST") != NULL) + VERBOSE_TEST = true; + TestOptions(); + + // Test the constructors + TestConstructors(); + + // Done + printf("OK\n"); + + return 0; +} diff --git a/tools/pcre/pcrecpparg.h.in b/tools/pcre/pcrecpparg.h.in new file mode 100644 index 00000000..61bcab54 --- /dev/null +++ b/tools/pcre/pcrecpparg.h.in @@ -0,0 +1,174 @@ +// Copyright (c) 2005, Google Inc. +// All rights reserved. +// +// 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 Google Inc. 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. +// +// Author: Sanjay Ghemawat + +#ifndef _PCRECPPARG_H +#define _PCRECPPARG_H + +#include // for NULL +#include + +#include + +namespace pcrecpp { + +class StringPiece; + +// Hex/Octal/Binary? + +// Special class for parsing into objects that define a ParseFrom() method +template +class _RE_MatchObject { + public: + static inline bool Parse(const char* str, int n, void* dest) { + if (dest == NULL) return true; + T* object = reinterpret_cast(dest); + return object->ParseFrom(str, n); + } +}; + +class PCRECPP_EXP_DEFN Arg { + public: + // Empty constructor so we can declare arrays of Arg + Arg(); + + // Constructor specially designed for NULL arguments + Arg(void*); + + typedef bool (*Parser)(const char* str, int n, void* dest); + +// Type-specific parsers +#define PCRE_MAKE_PARSER(type,name) \ + Arg(type* p) : arg_(p), parser_(name) { } \ + Arg(type* p, Parser parser) : arg_(p), parser_(parser) { } + + + PCRE_MAKE_PARSER(char, parse_char); + PCRE_MAKE_PARSER(unsigned char, parse_uchar); + PCRE_MAKE_PARSER(short, parse_short); + PCRE_MAKE_PARSER(unsigned short, parse_ushort); + PCRE_MAKE_PARSER(int, parse_int); + PCRE_MAKE_PARSER(unsigned int, parse_uint); + PCRE_MAKE_PARSER(long, parse_long); + PCRE_MAKE_PARSER(unsigned long, parse_ulong); +#if @pcre_have_long_long@ + PCRE_MAKE_PARSER(long long, parse_longlong); +#endif +#if @pcre_have_ulong_long@ + PCRE_MAKE_PARSER(unsigned long long, parse_ulonglong); +#endif + PCRE_MAKE_PARSER(float, parse_float); + PCRE_MAKE_PARSER(double, parse_double); + PCRE_MAKE_PARSER(std::string, parse_string); + PCRE_MAKE_PARSER(StringPiece, parse_stringpiece); + +#undef PCRE_MAKE_PARSER + + // Generic constructor + template Arg(T*, Parser parser); + // Generic constructor template + template Arg(T* p) + : arg_(p), parser_(_RE_MatchObject::Parse) { + } + + // Parse the data + bool Parse(const char* str, int n) const; + + private: + void* arg_; + Parser parser_; + + static bool parse_null (const char* str, int n, void* dest); + static bool parse_char (const char* str, int n, void* dest); + static bool parse_uchar (const char* str, int n, void* dest); + static bool parse_float (const char* str, int n, void* dest); + static bool parse_double (const char* str, int n, void* dest); + static bool parse_string (const char* str, int n, void* dest); + static bool parse_stringpiece (const char* str, int n, void* dest); + +#define PCRE_DECLARE_INTEGER_PARSER(name) \ + private: \ + static bool parse_ ## name(const char* str, int n, void* dest); \ + static bool parse_ ## name ## _radix( \ + const char* str, int n, void* dest, int radix); \ + public: \ + static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \ + static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \ + static bool parse_ ## name ## _cradix(const char* str, int n, void* dest) + + PCRE_DECLARE_INTEGER_PARSER(short); + PCRE_DECLARE_INTEGER_PARSER(ushort); + PCRE_DECLARE_INTEGER_PARSER(int); + PCRE_DECLARE_INTEGER_PARSER(uint); + PCRE_DECLARE_INTEGER_PARSER(long); + PCRE_DECLARE_INTEGER_PARSER(ulong); + PCRE_DECLARE_INTEGER_PARSER(longlong); + PCRE_DECLARE_INTEGER_PARSER(ulonglong); + +#undef PCRE_DECLARE_INTEGER_PARSER +}; + +inline Arg::Arg() : arg_(NULL), parser_(parse_null) { } +inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { } + +inline bool Arg::Parse(const char* str, int n) const { + return (*parser_)(str, n, arg_); +} + +// This part of the parser, appropriate only for ints, deals with bases +#define MAKE_INTEGER_PARSER(type, name) \ + inline Arg Hex(type* ptr) { \ + return Arg(ptr, Arg::parse_ ## name ## _hex); } \ + inline Arg Octal(type* ptr) { \ + return Arg(ptr, Arg::parse_ ## name ## _octal); } \ + inline Arg CRadix(type* ptr) { \ + return Arg(ptr, Arg::parse_ ## name ## _cradix); } + +MAKE_INTEGER_PARSER(short, short) /* */ +MAKE_INTEGER_PARSER(unsigned short, ushort) /* */ +MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */ +MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */ +MAKE_INTEGER_PARSER(long, long) /* because they can cause */ +MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */ +#if @pcre_have_long_long@ /* the checking level is */ +MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */ +#endif /* */ +#if @pcre_have_ulong_long@ /* */ +MAKE_INTEGER_PARSER(unsigned long long, ulonglong) /* */ +#endif + +#undef PCRE_IS_SET +#undef PCRE_SET_OR_CLEAR +#undef MAKE_INTEGER_PARSER + +} // namespace pcrecpp + + +#endif /* _PCRECPPARG_H */ diff --git a/tools/pcre/pcredemo.c b/tools/pcre/pcredemo.c new file mode 100644 index 00000000..946aba45 --- /dev/null +++ b/tools/pcre/pcredemo.c @@ -0,0 +1,406 @@ +/************************************************* +* PCRE DEMONSTRATION PROGRAM * +*************************************************/ + +/* This is a demonstration program to illustrate the most straightforward ways +of calling the PCRE regular expression library from a C program. See the +pcresample documentation for a short discussion ("man pcresample" if you have +the PCRE man pages installed). + +In Unix-like environments, if PCRE is installed in your standard system +libraries, you should be able to compile this program using this command: + +gcc -Wall pcredemo.c -lpcre -o pcredemo + +If PCRE is not installed in a standard place, it is likely to be installed with +support for the pkg-config mechanism. If you have pkg-config, you can compile +this program using this command: + +gcc -Wall pcredemo.c `pkg-config --cflags --libs libpcre` -o pcredemo + +If you do not have pkg-config, you may have to use this: + +gcc -Wall pcredemo.c -I/usr/local/include -L/usr/local/lib \ + -R/usr/local/lib -lpcre -o pcredemo + +Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and +library files for PCRE are installed on your system. Only some operating +systems (e.g. Solaris) use the -R option. + +Building under Windows: + +If you want to statically link this program against a non-dll .a file, you must +define PCRE_STATIC before including pcre.h, otherwise the pcre_malloc() and +pcre_free() exported functions will be declared __declspec(dllimport), with +unwanted results. So in this environment, uncomment the following line. */ + +/* #define PCRE_STATIC */ + +#include +#include +#include + +#define OVECCOUNT 30 /* should be a multiple of 3 */ + + +int main(int argc, char **argv) +{ +pcre *re; +const char *error; +char *pattern; +char *subject; +unsigned char *name_table; +unsigned int option_bits; +int erroffset; +int find_all; +int crlf_is_newline; +int namecount; +int name_entry_size; +int ovector[OVECCOUNT]; +int subject_length; +int rc, i; +int utf8; + + +/************************************************************************** +* First, sort out the command line. There is only one possible option at * +* the moment, "-g" to request repeated matching to find all occurrences, * +* like Perl's /g option. We set the variable find_all to a non-zero value * +* if the -g option is present. Apart from that, there must be exactly two * +* arguments. * +**************************************************************************/ + +find_all = 0; +for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-g") == 0) find_all = 1; + else break; + } + +/* After the options, we require exactly two arguments, which are the pattern, +and the subject string. */ + +if (argc - i != 2) + { + printf("Two arguments required: a regex and a subject string\n"); + return 1; + } + +pattern = argv[i]; +subject = argv[i+1]; +subject_length = (int)strlen(subject); + + +/************************************************************************* +* Now we are going to compile the regular expression pattern, and handle * +* and errors that are detected. * +*************************************************************************/ + +re = pcre_compile( + pattern, /* the pattern */ + 0, /* default options */ + &error, /* for error message */ + &erroffset, /* for error offset */ + NULL); /* use default character tables */ + +/* Compilation failed: print the error message and exit */ + +if (re == NULL) + { + printf("PCRE compilation failed at offset %d: %s\n", erroffset, error); + return 1; + } + + +/************************************************************************* +* If the compilation succeeded, we call PCRE again, in order to do a * +* pattern match against the subject string. This does just ONE match. If * +* further matching is needed, it will be done below. * +*************************************************************************/ + +rc = pcre_exec( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + subject, /* the subject string */ + subject_length, /* the length of the subject */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + ovector, /* output vector for substring information */ + OVECCOUNT); /* number of elements in the output vector */ + +/* Matching failed: handle error cases */ + +if (rc < 0) + { + switch(rc) + { + case PCRE_ERROR_NOMATCH: printf("No match\n"); break; + /* + Handle other special cases if you like + */ + default: printf("Matching error %d\n", rc); break; + } + pcre_free(re); /* Release memory used for the compiled pattern */ + return 1; + } + +/* Match succeded */ + +printf("\nMatch succeeded at offset %d\n", ovector[0]); + + +/************************************************************************* +* We have found the first match within the subject string. If the output * +* vector wasn't big enough, say so. Then output any substrings that were * +* captured. * +*************************************************************************/ + +/* The output vector wasn't big enough */ + +if (rc == 0) + { + rc = OVECCOUNT/3; + printf("ovector only has room for %d captured substrings\n", rc - 1); + } + +/* Show substrings stored in the output vector by number. Obviously, in a real +application you might want to do things other than print them. */ + +for (i = 0; i < rc; i++) + { + char *substring_start = subject + ovector[2*i]; + int substring_length = ovector[2*i+1] - ovector[2*i]; + printf("%2d: %.*s\n", i, substring_length, substring_start); + } + + +/************************************************************************** +* That concludes the basic part of this demonstration program. We have * +* compiled a pattern, and performed a single match. The code that follows * +* shows first how to access named substrings, and then how to code for * +* repeated matches on the same subject. * +**************************************************************************/ + +/* See if there are any named substrings, and if so, show them by name. First +we have to extract the count of named parentheses from the pattern. */ + +(void)pcre_fullinfo( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + PCRE_INFO_NAMECOUNT, /* number of named substrings */ + &namecount); /* where to put the answer */ + +if (namecount <= 0) printf("No named substrings\n"); else + { + unsigned char *tabptr; + printf("Named substrings\n"); + + /* Before we can access the substrings, we must extract the table for + translating names to numbers, and the size of each entry in the table. */ + + (void)pcre_fullinfo( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + PCRE_INFO_NAMETABLE, /* address of the table */ + &name_table); /* where to put the answer */ + + (void)pcre_fullinfo( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + PCRE_INFO_NAMEENTRYSIZE, /* size of each entry in the table */ + &name_entry_size); /* where to put the answer */ + + /* Now we can scan the table and, for each entry, print the number, the name, + and the substring itself. */ + + tabptr = name_table; + for (i = 0; i < namecount; i++) + { + int n = (tabptr[0] << 8) | tabptr[1]; + printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, + ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); + tabptr += name_entry_size; + } + } + + +/************************************************************************* +* If the "-g" option was given on the command line, we want to continue * +* to search for additional matches in the subject string, in a similar * +* way to the /g option in Perl. This turns out to be trickier than you * +* might think because of the possibility of matching an empty string. * +* What happens is as follows: * +* * +* If the previous match was NOT for an empty string, we can just start * +* the next match at the end of the previous one. * +* * +* If the previous match WAS for an empty string, we can't do that, as it * +* would lead to an infinite loop. Instead, a special call of pcre_exec() * +* is made with the PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED flags set. * +* The first of these tells PCRE that an empty string at the start of the * +* subject is not a valid match; other possibilities must be tried. The * +* second flag restricts PCRE to one match attempt at the initial string * +* position. If this match succeeds, an alternative to the empty string * +* match has been found, and we can print it and proceed round the loop, * +* advancing by the length of whatever was found. If this match does not * +* succeed, we still stay in the loop, advancing by just one character. * +* In UTF-8 mode, which can be set by (*UTF8) in the pattern, this may be * +* 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 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. * +*************************************************************************/ + +if (!find_all) /* Check for -g */ + { + pcre_free(re); /* Release the memory used for the compiled pattern */ + return 0; /* Finish unless -g was given */ + } + +/* Before running the loop, check for UTF-8 and whether CRLF is a valid newline +sequence. First, find the options with which the regex was compiled; extract +the UTF-8 state, and mask off all but the newline options. */ + +(void)pcre_fullinfo(re, NULL, PCRE_INFO_OPTIONS, &option_bits); +utf8 = option_bits & PCRE_UTF8; +option_bits &= PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_CRLF| + PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF; + +/* If no newline options were set, find the default newline convention from the +build configuration. */ + +if (option_bits == 0) + { + int 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. */ + option_bits = (d == 13)? PCRE_NEWLINE_CR : + (d == 10)? PCRE_NEWLINE_LF : + (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF : + (d == -2)? PCRE_NEWLINE_ANYCRLF : + (d == -1)? PCRE_NEWLINE_ANY : 0; + } + +/* See if CRLF is a valid newline sequence. */ + +crlf_is_newline = + option_bits == PCRE_NEWLINE_ANY || + option_bits == PCRE_NEWLINE_CRLF || + option_bits == PCRE_NEWLINE_ANYCRLF; + +/* Loop for second and subsequent matches */ + +for (;;) + { + int options = 0; /* Normally no options */ + int start_offset = ovector[1]; /* Start at end of previous match */ + + /* If the previous match was for an empty string, we are finished if we are + at the end of the subject. Otherwise, arrange to run another match at the + same point to see if a non-empty match can be found. */ + + if (ovector[0] == ovector[1]) + { + if (ovector[0] == subject_length) break; + options = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED; + } + + /* Run the next matching operation */ + + rc = pcre_exec( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + subject, /* the subject string */ + subject_length, /* the length of the subject */ + start_offset, /* starting offset in the subject */ + options, /* options */ + ovector, /* output vector for substring information */ + OVECCOUNT); /* number of elements in the output vector */ + + /* This time, a result of NOMATCH isn't an error. If the value in "options" + is zero, it just means we have found all possible matches, so the loop ends. + Otherwise, it means we have failed to find a non-empty-string match at a + point where there was a previous empty-string match. In this case, we do what + Perl does: advance the matching position by one character, and continue. We + do this by setting the "end of previous match" offset, because that is picked + up at the top of the loop as the point at which to start again. + + There are two complications: (a) When CRLF is a valid newline sequence, and + the current position is just before it, advance by an extra byte. (b) + Otherwise we must ensure that we skip an entire UTF-8 character if we are in + UTF-8 mode. */ + + if (rc == PCRE_ERROR_NOMATCH) + { + if (options == 0) break; /* All matches found */ + ovector[1] = start_offset + 1; /* Advance one byte */ + if (crlf_is_newline && /* If CRLF is newline & */ + start_offset < subject_length - 1 && /* we are at CRLF, */ + subject[start_offset] == '\r' && + subject[start_offset + 1] == '\n') + ovector[1] += 1; /* Advance by one more. */ + else if (utf8) /* Otherwise, ensure we */ + { /* advance a whole UTF-8 */ + while (ovector[1] < subject_length) /* character. */ + { + if ((subject[ovector[1]] & 0xc0) != 0x80) break; + ovector[1] += 1; + } + } + continue; /* Go round the loop again */ + } + + /* Other matching errors are not recoverable. */ + + if (rc < 0) + { + printf("Matching error %d\n", rc); + pcre_free(re); /* Release memory used for the compiled pattern */ + return 1; + } + + /* Match succeded */ + + printf("\nMatch succeeded again at offset %d\n", ovector[0]); + + /* The match succeeded, but the output vector wasn't big enough. */ + + if (rc == 0) + { + rc = OVECCOUNT/3; + printf("ovector only has room for %d captured substrings\n", rc - 1); + } + + /* As before, show substrings stored in the output vector by number, and then + also any named substrings. */ + + for (i = 0; i < rc; i++) + { + char *substring_start = subject + ovector[2*i]; + int substring_length = ovector[2*i+1] - ovector[2*i]; + printf("%2d: %.*s\n", i, substring_length, substring_start); + } + + if (namecount <= 0) printf("No named substrings\n"); else + { + unsigned char *tabptr = name_table; + printf("Named substrings\n"); + for (i = 0; i < namecount; i++) + { + int n = (tabptr[0] << 8) | tabptr[1]; + printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, + ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); + tabptr += name_entry_size; + } + } + } /* End of loop to find second and subsequent matches */ + +printf("\n"); +pcre_free(re); /* Release memory used for the compiled pattern */ +return 0; +} + +/* End of pcredemo.c */ diff --git a/tools/pcre/pcregexp.pas b/tools/pcre/pcregexp.pas new file mode 100644 index 00000000..77afd561 --- /dev/null +++ b/tools/pcre/pcregexp.pas @@ -0,0 +1,845 @@ +{ + pcRegExp - Perl compatible regular expressions for Virtual Pascal + (c) 2001 Peter S. Voronov aka Chem O'Dun + + Based on PCRE library interface unit for Virtual Pascal. + (c) 2001 Alexander Tokarev + + The current PCRE version is: 3.7 + + This software may be distributed under the terms of the modified BSD license + Copyright (c) 2001, Alexander Tokarev + All rights reserved. + + 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 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 HOLDER 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. + + The PCRE library is written by: Philip Hazel + Copyright (c) 1997-2004 University of Cambridge + + AngelsHolocaust 4-11-04 updated to use version v5.0 + (INFO: this is regex-directed, NFA) + AH: 9-11-04 - pcre_free: removed var, pcre already gives the ptr, now + everything works as it should (no more crashes) + -> removed CheckRegExp because pcre handles errors perfectly + 10-11-04 - added pcError (errorhandling), pcInit + 13-11-04 - removed the ErrorPos = 0 check -> always print erroroffset + 17-10-05 - support for \1-\9 backreferences in TpcRegExp.GetReplStr + 17-02-06 - added RunTimeOptions: caller can set options while searching + 19-02-06 - added SearchOfs(): let PCRE use the complete string and offset + into the string itself + 20-12-06 - support for version 7.0 + 27.08.08 - support for v7.7 +} + +{$H+} {$DEFINE PCRE_3_7} {$DEFINE PCRE_5_0} {$DEFINE PCRE_7_0} {$DEFINE PCRE_7_7} + +Unit pcregexp; + +Interface + +uses objects; + +Type + PpcRegExp = ^TpcRegExp; +// TpcRegExp = object + TpcRegExp = object(TObject) + MatchesCount: integer; + RegExpC, RegExpExt : Pointer; + Matches:Pointer; + RegExp: shortstring; + SourceLen: integer; + PartialMatch : boolean; + Error : boolean; + ErrorMsg : Pchar; + ErrorPos : integer; + RunTimeOptions: Integer; // options which can be set by the caller + constructor Init(const ARegExp : shortstring; AOptions : integer; ALocale : Pointer); + function Search(AStr: Pchar; ALen : longint) : boolean; virtual; + function SearchNext( AStr: Pchar; ALen : longint) : boolean; virtual; + function SearchOfs ( AStr: Pchar; ALen, AOfs : longint) : boolean; virtual; + function MatchSub(ANom: integer; var Pos, Len : longint) : boolean; virtual; + function MatchFull(var Pos, Len : longint) : boolean; virtual; + function GetSubStr(ANom: integer; AStr: Pchar) : string; virtual; + function GetFullStr(AStr: Pchar) : string; virtual; + function GetReplStr(AStr: Pchar; const ARepl: string) : string; virtual; + function GetPreSubStr(AStr: Pchar) : string; virtual; + function GetPostSubStr(AStr: Pchar) : string; virtual; + function ErrorStr : string; virtual; + destructor Done; virtual; + end; + + function pcGrepMatch(WildCard, aStr: string; AOptions:integer; ALocale : Pointer): Boolean; + function pcGrepSub(WildCard, aStr, aRepl: string; AOptions:integer; ALocale : Pointer): string; + + function pcFastGrepMatch(WildCard, aStr: string): Boolean; + function pcFastGrepSub(WildCard, aStr, aRepl: string): string; + +{$IFDEF PCRE_5_0} + function pcGetVersion : pchar; +{$ENDIF} + + function pcError (var pRegExp : Pointer) : Boolean; + function pcInit (const Pattern: Shortstring; CaseSens: Boolean) : Pointer; + +Const { Options } + PCRE_CASELESS = $0001; + PCRE_MULTILINE = $0002; + PCRE_DOTALL = $0004; + PCRE_EXTENDED = $0008; + PCRE_ANCHORED = $0010; + PCRE_DOLLAR_ENDONLY = $0020; + PCRE_EXTRA = $0040; + PCRE_NOTBOL = $0080; + PCRE_NOTEOL = $0100; + PCRE_UNGREEDY = $0200; + PCRE_NOTEMPTY = $0400; +{$IFDEF PCRE_5_0} + PCRE_UTF8 = $0800; + PCRE_NO_AUTO_CAPTURE = $1000; + PCRE_NO_UTF8_CHECK = $2000; + PCRE_AUTO_CALLOUT = $4000; + PCRE_PARTIAL = $8000; +{$ENDIF} +{$IFDEF PCRE_7_0} + PCRE_DFA_SHORTEST = $00010000; + PCRE_DFA_RESTART = $00020000; + PCRE_FIRSTLINE = $00040000; + PCRE_DUPNAMES = $00080000; + PCRE_NEWLINE_CR = $00100000; + PCRE_NEWLINE_LF = $00200000; + PCRE_NEWLINE_CRLF = $00300000; + PCRE_NEWLINE_ANY = $00400000; + PCRE_NEWLINE_ANYCRLF = $00500000; + + PCRE_NEWLINE_BITS = PCRE_NEWLINE_CR or PCRE_NEWLINE_LF or PCRE_NEWLINE_ANY; + +{$ENDIF} +{$IFDEF PCRE_7_7} + PCRE_BSR_ANYCRLF = $00800000; + PCRE_BSR_UNICODE = $01000000; + PCRE_JAVASCRIPT_COMPAT= $02000000; +{$ENDIF} + + PCRE_COMPILE_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_AUTO_CALLOUT + PCRE_CASELESS + + PCRE_DOLLAR_ENDONLY + PCRE_DOTALL + PCRE_EXTENDED + + PCRE_EXTRA + PCRE_MULTILINE + PCRE_NO_AUTO_CAPTURE + + PCRE_UNGREEDY + PCRE_UTF8 + PCRE_NO_UTF8_CHECK + {$IFDEF PCRE_7_0} + + PCRE_DUPNAMES + PCRE_FIRSTLINE + PCRE_NEWLINE_BITS + {$ENDIF} + {$IFDEF PCRE_7_7} + + PCRE_BSR_ANYCRLF + PCRE_BSR_UNICODE + PCRE_JAVASCRIPT_COMPAT + {$ENDIF} + ; + + PCRE_EXEC_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_NOTBOL + PCRE_NOTEOL + + PCRE_NOTEMPTY + PCRE_NO_UTF8_CHECK + PCRE_PARTIAL + {$IFDEF PCRE_7_0} + + PCRE_NEWLINE_BITS + {$ENDIF} + {$IFDEF PCRE_7_7} + + PCRE_BSR_ANYCRLF + PCRE_BSR_UNICODE + {$ENDIF} + ; + +{$IFDEF PCRE_7_0} + PCRE_DFA_EXEC_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_NOTBOL + PCRE_NOTEOL + + PCRE_NOTEMPTY + PCRE_NO_UTF8_CHECK + PCRE_PARTIAL + + PCRE_DFA_SHORTEST + PCRE_DFA_RESTART + + PCRE_NEWLINE_BITS + {$IFDEF PCRE_7_7} + + PCRE_BSR_ANYCRLF + PCRE_BSR_UNICODE + {$ENDIF} + ; +{$ENDIF} + +{ Exec-time and get/set-time error codes } + PCRE_ERROR_NOMATCH = -1; + PCRE_ERROR_NULL = -2; + PCRE_ERROR_BADOPTION = -3; + PCRE_ERROR_BADMAGIC = -4; + PCRE_ERROR_UNKNOWN_MODE = -5; + PCRE_ERROR_NOMEMORY = -6; + PCRE_ERROR_NOSUBSTRING = -7; +{$IFDEF PCRE_5_0} + PCRE_ERROR_MATCHLIMIT = -8; + PCRE_ERROR_CALLOUT = -9; { Never used by PCRE itself } + PCRE_ERROR_BADUTF8 = -10; + PCRE_ERROR_BADUTF8_OFFSET = -11; + PCRE_ERROR_PARTIAL = -12; + PCRE_ERROR_BADPARTIAL = -13; + PCRE_ERROR_INTERNAL = -14; + PCRE_ERROR_BADCOUNT = -15; +{$ENDIF} +{$IFDEF PCRE_7_0} + PCRE_ERROR_DFA_UITEM = -16; + PCRE_ERROR_DFA_UCOND = -17; + PCRE_ERROR_DFA_UMLIMIT = -18; + PCRE_ERROR_DFA_WSSIZE = -19; + PCRE_ERROR_DFA_RECURSE = -20; + PCRE_ERROR_RECURSIONLIMIT = -21; + PCRE_ERROR_NULLWSLIMIT = -22; + PCRE_ERROR_BADNEWLINE = -23; +{$ENDIF} + +{ Request types for pcre_fullinfo() } + + PCRE_INFO_OPTIONS = 0; + PCRE_INFO_SIZE = 1; + PCRE_INFO_CAPTURECOUNT = 2; + PCRE_INFO_BACKREFMAX = 3; + PCRE_INFO_FIRSTBYTE = 4; + PCRE_INFO_FIRSTCHAR = 4; { For backwards compatibility } + PCRE_INFO_FIRSTTABLE = 5; +{$IFDEF PCRE_5_0} + PCRE_INFO_LASTLITERAL = 6; + PCRE_INFO_NAMEENTRYSIZE = 7; + PCRE_INFO_NAMECOUNT = 8; + PCRE_INFO_NAMETABLE = 9; + PCRE_INFO_STUDYSIZE = 10; + PCRE_INFO_DEFAULT_TABLES = 11; +{$ENDIF PCRE_5_0} +{$IFDEF PCRE_7_7} + PCRE_INFO_OKPARTIAL = 12; + PCRE_INFO_JCHANGED = 13; + PCRE_INFO_HASCRORLF = 14; +{$ENDIF} + +{ Request types for pcre_config() } +{$IFDEF PCRE_5_0} + PCRE_CONFIG_UTF8 = 0; + PCRE_CONFIG_NEWLINE = 1; + PCRE_CONFIG_LINK_SIZE = 2; + PCRE_CONFIG_POSIX_MALLOC_THRESHOLD = 3; + PCRE_CONFIG_MATCH_LIMIT = 4; + PCRE_CONFIG_STACKRECURSE = 5; + PCRE_CONFIG_UNICODE_PROPERTIES = 6; +{$ENDIF PCRE_5_0} +{$IFDEF PCRE_7_0} + PCRE_CONFIG_MATCH_LIMIT_RECURSION = 7; +{$ENDIF} +{$IFDEF PCRE_7_7} + PCRE_CONFIG_BSR = 8; +{$ENDIF} + +{ Bit flags for the pcre_extra structure } +{$IFDEF PCRE_5_0} + PCRE_EXTRA_STUDY_DATA = $0001; + PCRE_EXTRA_MATCH_LIMIT = $0002; + PCRE_EXTRA_CALLOUT_DATA = $0004; + PCRE_EXTRA_TABLES = $0008; +{$ENDIF PCRE_5_0} +{$IFDEF PCRE_7_0} + PCRE_EXTRA_MATCH_LIMIT_RECURSION = $0010; +{$ENDIF} + +Const +// DefaultOptions : integer = 0; + DefaultLocaleTable : pointer = nil; + +{$IFDEF PCRE_5_0} +{ The structure for passing additional data to pcre_exec(). This is defined in +such as way as to be extensible. Always add new fields at the end, in order to +remain compatible. } + +type ppcre_extra = ^tpcre_extra; + tpcre_extra = record + flags : longint; { Bits for which fields are set } + study_data : pointer; { Opaque data from pcre_study() } + match_limit : longint; { Maximum number of calls to match() } + callout_data : pointer; { Data passed back in callouts } + tables : pointer; { Pointer to character tables } + match_limit_recursion: longint; { Max recursive calls to match() } + end; + +type ppcre_callout_block = ^pcre_callout_block; + pcre_callout_block = record + version, + (* ------------------------ Version 0 ------------------------------- *) + callout_number : integer; + offset_vector : pointer; + subject : pchar; + subject_length, start_match, current_position, capture_top, + capture_last : integer; + callout_data : pointer; + (* ------------------- Added for Version 1 -------------------------- *) + pattern_position, next_item_length : integer; + end; +{$ENDIF PCRE_5_0} + +{$OrgName+} +{$IFDEF VIRTUALPASCAL} {&Cdecl+} {$ENDIF VIRTUALPASCAL} + + { local replacement of external pcre memory management functions } + function pcre_malloc( size : integer ) : pointer; + procedure pcre_free( {var} p : pointer ); +{$IFDEF PCRE_5_0} + const pcre_stack_malloc: function ( size : integer ): pointer = pcre_malloc; + pcre_stack_free: procedure ( {var} p : pointer ) = pcre_free; + function pcre_callout(var p : ppcre_callout_block) : integer; +{$ENDIF PCRE_5_0} +{$IFDEF VIRTUALPASCAL} {&Cdecl-} {$ENDIF VIRTUALPASCAL} + +Implementation + +Uses strings, collect, messages, dnapp, commands, advance0, stringsx + {$IFDEF VIRTUALPASCAL} ,vpsyslow {$ENDIF VIRTUALPASCAL}; + +Const + MAGIC_NUMBER = $50435245; { 'PCRE' } + MAX_MATCHES = 90; { changed in 3.5 version; should be divisible by 3, was 64} + +Type + PMatchArray = ^TMatchArray; + TMatchArray = array[0..( MAX_MATCHES * 3 )] of integer; + + PRegExpCollection = ^TRegExpCollection; + TRegExpCollection = object(TSortedCollection) + MaxRegExp : integer; + SearchRegExp : shortstring; + CompareModeInsert : boolean; + constructor Init(AMaxRegExp:integer); + procedure FreeItem(P: Pointer); virtual; + function Compare(P1, P2: Pointer): Integer; virtual; + function Find(ARegExp:shortstring;var P: PpcRegExp):boolean; virtual; + function CheckNew(ARegExp:shortstring):PpcRegExp;virtual; + end; + +Var + PRegExpCache : PRegExpCollection; + + +{$IFDEF VIRTUALPASCAL} {&Cdecl+} {$ENDIF VIRTUALPASCAL} + + { imported original pcre functions } + + function pcre_compile( const pattern : PChar; options : integer; + var errorptr : PChar; var erroroffset : integer; + const tables : PChar ) : pointer {pcre}; external; +{$IFDEF PCRE_7_0} + function pcre_compile2( const pattern : PChar; options : integer; + var errorcodeptr : Integer; + var errorptr : PChar; var erroroffset : integer; + const tables : PChar ) : pointer {pcre}; external; +{$ENDIF} +{$IFDEF PCRE_5_0} + function pcre_config( what : integer; where : pointer) : integer; external; + function pcre_copy_named_substring( const code : pointer {pcre}; + const subject : pchar; + var ovector : integer; + stringcount : integer; + const stringname : pchar; + var buffer : pchar; + size : integer) : integer; external; + function pcre_copy_substring( const subject : pchar; var ovector : integer; + stringcount, stringnumber : integer; + var buffer : pchar; size : integer ) + : integer; external; + function pcre_exec( const argument_re : pointer {pcre}; + const extra_data : pointer {pcre_extra}; +{$ELSE} + function pcre_exec( const external_re : pointer; + const external_extra : pointer; +{$ENDIF} + const subject : PChar; + length, start_offset, options : integer; + offsets : pointer; + offsetcount : integer ) : integer; external; +{$IFDEF PCRE_7_0} + function pcre_dfa_exec( const argument_re : pointer {pcre}; + const extra_data : pointer {pcre_extra}; + const subject : pchar; + length, start_offset, options : integer; + offsets : pointer; + offsetcount : integer; + workspace : pointer; + wscount : integer ) : integer; external; +{$ENDIF} +{$IFDEF PCRE_5_0} + procedure pcre_free_substring( const p : pchar ); external; + procedure pcre_free_substring_list( var p : pchar ); external; + function pcre_fullinfo( const argument_re : pointer {pcre}; + const extra_data : pointer {pcre_extra}; + what : integer; + where : pointer ) : integer; external; + function pcre_get_named_substring( const code : pointer {pcre}; + const subject : pchar; + var ovector : integer; + stringcount : integer; + const stringname : pchar; + var stringptr : pchar ) : integer; external; + function pcre_get_stringnumber( const code : pointer {pcre}; + const stringname : pchar ) : integer; external; + function pcre_get_stringtable_entries( const code : pointer {pcre}; + const stringname : pchar; + var firstptr, + lastptr : pchar ) : integer; external; + function pcre_get_substring( const subject : pchar; var ovector : integer; + stringcount, stringnumber : integer; + var stringptr : pchar ) : integer; external; + function pcre_get_substring_list( const subject : pchar; var ovector : integer; + stringcount : integer; + listptr : pointer {const char ***listptr}) : integer; external; + function pcre_info( const argument_re : pointer {pcre}; + var optptr : integer; + var first_byte : integer ) : integer; external; + function pcre_maketables : pchar; external; +{$ENDIF} +{$IFDEF PCRE_7_0} + function pcre_refcount( const argument_re : pointer {pcre}; + adjust : integer ) : pchar; external; +{$ENDIF} + function pcre_study( const external_re : pointer {pcre}; + options : integer; + var errorptr : PChar ) : pointer {pcre_extra}; external; +{$IFDEF PCRE_5_0} + function pcre_version : pchar; external; +{$ENDIF} + + function pcre_malloc( size : integer ) : pointer; + begin + GetMem( result, size ); + end; + + procedure pcre_free( {var} p : pointer ); + begin + if (p <> nil) then + FreeMem( p, 0 ); + {@p := nil;} + end; + +{$IFDEF PCRE_5_0} +(* Called from PCRE as a result of the (?C) item. We print out where we are in +the match. Yield zero unless more callouts than the fail count, or the callout +data is not zero. *) + + function pcre_callout; + begin + end; +{$ENDIF} + +{$IFDEF VIRTUALPASCAL} {&Cdecl-} {$ENDIF VIRTUALPASCAL} + +// Always include the newest version of the library +{$IFDEF PCRE_7_7} + {$L pcre77.lib} +{$ELSE} + {$IFDEF PCRE_7_0} + {$L pcre70.lib} + {$ELSE} + {$IFDEF PCRE_5_0} + {$L pcre50.lib} + {$ELSE} + {$IFDEF PCRE_3_7} + {$L pcre37.lib} + {$ENDIF PCRE_3_7} + {$ENDIF PCRE_5_0} + {$ENDIF PCRE_7_0} +{$ENDIF PCRE_7_7} + +{TpcRegExp} + + constructor TpcRegExp.Init(const ARegExp:shortstring; AOptions:integer; ALocale : Pointer); + var + pRegExp : PChar; + begin + RegExp:=ARegExp; + RegExpC:=nil; + RegExpExt:=nil; + Matches:=nil; + MatchesCount:=0; + Error:=true; + ErrorMsg:=nil; + ErrorPos:=0; + RunTimeOptions := 0; + if length(RegExp) < 255 then + begin + RegExp[length(RegExp)+1]:=#0; + pRegExp:=@RegExp[1]; + end + else + begin + GetMem(pRegExp,length(RegExp)+1); + pRegExp:=strpcopy(pRegExp,RegExp); + end; + RegExpC := pcre_compile( pRegExp, + AOptions and PCRE_COMPILE_ALLOWED_OPTIONS, + ErrorMsg, ErrorPos, ALocale); + if length(RegExp) = 255 then + StrDispose(pRegExp); + if RegExpC = nil then + exit; + ErrorMsg:=nil; + RegExpExt := pcre_study( RegExpC, 0, ErrorMsg ); + if (RegExpExt = nil) and (ErrorMsg <> nil) then + begin + pcre_free(RegExpC); + exit; + end; + GetMem(Matches,SizeOf(TMatchArray)); + Error:=false; + end; + + destructor TpcRegExp.Done; + begin + if RegExpC <> nil then + pcre_free(RegExpC); + if RegExpExt <> nil then + pcre_free(RegExpExt); + if Matches <> nil then + FreeMem(Matches,SizeOf(TMatchArray)); + end; + + function TpcRegExp.SearchNext( AStr: Pchar; ALen : longint ) : boolean; + var Options: Integer; + begin // must handle PCRE_ERROR_PARTIAL here + Options := (RunTimeOptions or startup.MiscMultiData.cfgRegEx.DefaultOptions) and + PCRE_EXEC_ALLOWED_OPTIONS; + if MatchesCount > 0 then + MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, PMatchArray(Matches)^[1], + Options, Matches, MAX_MATCHES ) else + MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, 0, + Options, Matches, MAX_MATCHES ); +{ if MatchesCount = 0 then + MatchesCount := MatchesCount div 3;} + PartialMatch := MatchesCount = PCRE_ERROR_PARTIAL; + SearchNext := MatchesCount > 0; + end; + + function TpcRegExp.Search( AStr: Pchar; ALen : longint):boolean; + begin + MatchesCount:=0; + Search:=SearchNext(AStr,ALen); + SourceLen:=ALen; + end; + + function TpcRegExp.SearchOfs( AStr: Pchar; ALen, AOfs: longint ) : boolean; + var Options: Integer; + begin + MatchesCount:=0; + Options := (RunTimeOptions or startup.MiscMultiData.cfgRegEx.DefaultOptions) and + PCRE_EXEC_ALLOWED_OPTIONS; + MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, AOfs, + Options, Matches, MAX_MATCHES ); + PartialMatch := MatchesCount = PCRE_ERROR_PARTIAL; + SearchOfs := MatchesCount > 0; + SourceLen := ALen-AOfs; + end; + + function TpcRegExp.MatchSub(ANom:integer; var Pos,Len:longint):boolean; + begin + if (MatchesCount > 0) and (ANom <= (MatchesCount-1)) then + begin + ANom:=ANom*2; + Pos:=PMatchArray(Matches)^[ANom]; + Len:=PMatchArray(Matches)^[ANom+1]-Pos; + MatchSub:=true; + end + else + MatchSub:=false; + end; + + function TpcRegExp.MatchFull(var Pos,Len:longint):boolean; + begin + MatchFull:=MatchSub(0,Pos,Len); + end; + + function TpcRegExp.GetSubStr(ANom: integer; AStr: Pchar):string; + var + s: ansistring; + pos,len: longint; + begin + s:=''; + if MatchSub(ANom, pos, len) then + begin + setlength(s, len); + Move(AStr[pos], s[1], len); + end; + GetSubStr:=s; + end; + + function TpcRegExp.GetPreSubStr(AStr: Pchar):string; + var + s: ansistring; + l: longint; + begin + s:=''; + if (MatchesCount > 0) then + begin + l:=PMatchArray(Matches)^[0]-1; + if l > 0 then + begin + setlength(s,l); + Move(AStr[1],s[1],l); + end; + end; + GetPreSubStr:=s; + end; + + function TpcRegExp.GetPostSubStr(AStr: Pchar):string; + var + s: ansistring; + l: longint; + ANom: integer; + begin + s:=''; + if (MatchesCount > 0) then + begin + ANom:=(MatchesCount-1){*2} shl 1; + l:=SourceLen-PMatchArray(Matches)^[ANom+1]+1; + if l > 0 then + begin + setlength(s,l); + Move(AStr[PMatchArray(Matches)^[ANom+1]],s[1],l); + end; + end; + GetPostSubStr:=s; + end; + + + function TpcRegExp.GetFullStr(AStr: Pchar):string; + var + s: ansistring; + l: longint; + begin + GetFullStr:=GetSubStr(0,AStr); + end; + + function TpcRegExp.GetReplStr(AStr: Pchar; const ARepl: string):string; + var + s: ansistring; + l,i,lasti: longint; + begin + l:=length(ARepl); + i:=1; + lasti:=1; + s:=''; + while i <= l do + begin + case ARepl[i] of + '\' : + begin + if i < l then + begin + s:=s+copy(ARepl,lasti,i-lasti){+ARepl[i+1]}; + {AH 17-10-05 support for POSIX \1-\9 backreferences} + case ARepl[i+1] of + '0' : s:=s+GetFullStr(AStr); + '1'..'9' : s:=s+GetSubStr(ord(ARepl[i+1])-ord('0'),AStr); + else s:=s+ARepl[i+1]; // copy the escaped character + end; + end; + inc(i); + lasti:=i+1; + end; + '$' : + begin + if i < l then + begin + s:=s+copy(ARepl,lasti,i-lasti); + case ARepl[i+1] of + '&' : s:=s+GetFullStr(AStr); + '1'..'9' : s:=s+GetSubStr(ord(ARepl[i+1])-ord('0'),AStr); + '`' : s:=s+GetPreSubStr(AStr); + #39 : s:=s+GetPostSubStr(AStr); + end; + end; + inc(i); + lasti:=i+1; + end; + end; + inc(i); + end; + if lasti <= {AH 25-10-2004 added =, else l==1 won't work} l then + s:=s+copy(ARepl,lasti,l-lasti+1); + GetReplStr:=s; + end; + + function TpcRegExp.ErrorStr:string; + begin + ErrorStr:=StrPas(ErrorMsg); + end; + +{TRegExpCollection} + +constructor TRegExpCollection.Init(AMaxRegExp: integer); +begin + Inherited Init(1,1); + MaxRegExp:=AMaxRegExp; + CompareModeInsert:=true; +end; + +procedure TRegExpCollection.FreeItem(P: Pointer); +begin + if P <> nil then + begin + Dispose(PpcRegExp(P),Done); + end; +end; + +function TRegExpCollection.Compare(P1, P2: Pointer): Integer; +//var +// l,l1,l2,i : byte; +//// wPos: pchar; +begin + if CompareModeInsert then + begin +// l1:=length(PpcRegExp(P1)^.RegExp); +// l2:=length(PpcRegExp(P2)^.RegExp); +// if l1 > l2 then l:=l2 else +// l:=l1; +// for i:=1 to l do +// if PpcRegExp(P1).RegExp[i] <> PpcRegExp(P2).RegExp[i] then break; +// if i <=l then +// Compare:=ord(PpcRegExp(P1).RegExp[i])-ord(PpcRegExp(P2).RegExp[i]) else +// Compare:=l1-l2; + Compare := stringsx.PasStrCmp(PpcRegExp(P1).RegExp, PpcRegExp(P2).RegExp, False); + end + else + begin +// l1:=length(PpcRegExp(P1)^.RegExp); +// l2:=length(SearchRegExp); +// if l1 > l2 then l:=l2 else +// l:=l1; +// for i:=1 to l do +// if PpcRegExp(P1).RegExp[i] <> SearchRegExp[i] then +// begin +// Compare:=ord(PpcRegExp(P1).RegExp[i])-ord(SearchRegExp[i]); +// break; +// end; +// if i > l then Compare:=l1-l2; + Compare := stringsx.PasStrCmp(PpcRegExp(P1).RegExp, SearchRegExp, False); + end; +end; + +function TRegExpCollection.Find(ARegExp:shortstring;var P: PpcRegExp):boolean; +var I : integer; +begin + CompareModeInsert:=false; + SearchRegExp:=ARegExp; + if Search(nil,I) then + begin + P:=PpcRegExp(At(I)); + Find:=true; + end + else + begin + P:=nil; + Find:=false; + end; + CompareModeInsert:=true; +end; + +function TRegExpCollection.CheckNew(ARegExp:shortstring):PpcRegExp; +var + P : PpcRegExp; +begin + if not Find(ARegExp,P) then + begin + if Count = MaxRegExp then + AtFree(0); + P:=New(ppcRegExp,Init(ARegExp,PCRE_CASELESS,nil)); + Insert(P); + end; + CheckNew:=P; +end; + +function pcGrepMatch(WildCard, aStr: string; AOptions:integer; ALocale : Pointer): Boolean; +var + PpcRE:PpcRegExp; +begin + PpcRE:=New(ppcRegExp,Init(WildCard,AOptions,Alocale)); + pcGrepMatch:=PpcRE^.Search(pchar(AStr),Length(AStr)); + Dispose(PpcRE,Done); +end; + +function pcGrepSub(WildCard, aStr, aRepl: string; AOptions:integer; ALocale : Pointer): string; +var + PpcRE:PpcRegExp; +begin + PpcRE:=New(ppcRegExp,Init(WildCard,AOptions,Alocale)); + if PpcRE^.Search(pchar(AStr),Length(AStr)) then + pcGrepSub:=PpcRE^.GetReplStr(pchar(AStr),ARepl) + else + pcGrepSub:=''; + Dispose(PpcRE,Done); +end; + +function pcFastGrepMatch(WildCard, aStr: string): Boolean; +var + PpcRE:PpcRegExp; +begin + PpcRE:=PRegExpCache^.CheckNew(WildCard); + pcFastGrepMatch:=PpcRE^.Search(pchar(AStr),Length(AStr)); +end; + +function pcFastGrepSub(WildCard, aStr, aRepl: string): string; +var + PpcRE:PpcRegExp; +begin + PpcRE:=PRegExpCache^.CheckNew(WildCard); + if PpcRE^.Search(pchar(AStr),Length(AStr)) then + pcFastGrepSub:=PpcRE^.GetReplStr(pchar(AStr),ARepl) + else + pcFastGrepSub:=''; +end; + +{$IFDEF PCRE_5_0} +function pcGetVersion : pchar; assembler; {$FRAME-}{$USES none} +asm + call pcre_version +end; +{$ENDIF PCRE_5_0} + +function pcError; +var P: ppcRegExp absolute pRegExp; +begin + Result := (P = nil) or P^.Error; + If Result and (P <> nil) then + begin +{ if P^.ErrorPos = 0 then + MessageBox(GetString(erRegExpCompile)+'"'+P^.ErrorStr+'"', nil,mfConfirmation+mfOkButton) + else} + MessageBox(GetString(erRegExpCompile)+'"'+P^.ErrorStr+'"'+GetString(erRegExpCompPos), + @P^.ErrorPos,mfConfirmation+mfOkButton); + Dispose(P, Done); + P:=nil; + end; +end; + +function pcInit; +var Options : Integer; +begin + If CaseSens then Options := 0 else Options := PCRE_CASELESS; + Result := New( PpcRegExp, Init( Pattern, + {DefaultOptions} + startup.MiscMultiData.cfgRegEx.DefaultOptions or Options, + DefaultLocaleTable) ); +end; + +Initialization + PRegExpCache:=New(PRegExpCollection,Init(64)); +Finalization + Dispose(PRegExpCache,Done); +End. diff --git a/tools/pcre/pcregrep.c b/tools/pcre/pcregrep.c new file mode 100644 index 00000000..2e0dc03f --- /dev/null +++ b/tools/pcre/pcregrep.c @@ -0,0 +1,3180 @@ +/************************************************* +* pcregrep program * +*************************************************/ + +/* This is a grep program that uses the PCRE regular expression library to do +its pattern matching. On a Unix or Win32 system it can recurse into +directories. + + 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. +----------------------------------------------------------------------------- +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef SUPPORT_LIBZ +#include +#endif + +#ifdef SUPPORT_LIBBZ2 +#include +#endif + +#include "pcre.h" + +#define FALSE 0 +#define TRUE 1 + +typedef int BOOL; + +#define OFFSET_SIZE 99 + +#if BUFSIZ > 8192 +#define MAXPATLEN BUFSIZ +#else +#define MAXPATLEN 8192 +#endif + +#define PATBUFSIZE (MAXPATLEN + 10) /* Allows for prefix+suffix */ + +/* Values for the "filenames" variable, which specifies options for file name +output. The order is important; it is assumed that a file name is wanted for +all values greater than FN_DEFAULT. */ + +enum { FN_NONE, FN_DEFAULT, FN_MATCH_ONLY, FN_NOMATCH_ONLY, FN_FORCE }; + +/* File reading styles */ + +enum { FR_PLAIN, FR_LIBZ, FR_LIBBZ2 }; + +/* Actions for the -d and -D options */ + +enum { dee_READ, dee_SKIP, dee_RECURSE }; +enum { DEE_READ, DEE_SKIP }; + +/* Actions for special processing options (flag bits) */ + +#define PO_WORD_MATCH 0x0001 +#define PO_LINE_MATCH 0x0002 +#define PO_FIXED_STRINGS 0x0004 + +/* Line ending types */ + +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 +this, we use a macro that compiles a fudge. Oddly, this does not also seem to +apply to fprintf(). */ + +#define FWRITE(a,b,c,d) if (fwrite(a,b,c,d)) {} + + + +/************************************************* +* Global variables * +*************************************************/ + +/* Jeffrey Friedl has some debugging requirements that are not part of the +regular code. */ + +#ifdef JFRIEDL_DEBUG +static int S_arg = -1; +static unsigned int jfriedl_XR = 0; /* repeat regex attempt this many times */ +static unsigned int jfriedl_XT = 0; /* replicate text this many times */ +static const char *jfriedl_prefix = ""; +static const char *jfriedl_postfix = ""; +#endif + +static int endlinetype; + +static char *colour_string = (char *)"1;31"; +static char *colour_option = NULL; +static char *dee_option = NULL; +static char *DEE_option = NULL; +static char *locale = NULL; +static char *main_buffer = NULL; +static char *newline = NULL; +static char *om_separator = (char *)""; +static char *stdin_name = (char *)"(standard input)"; + +static const unsigned char *pcretables = NULL; + +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; + +#if defined HAVE_WINDOWS_H && HAVE_WINDOWS_H +static int dee_action = dee_SKIP; +#else +static int dee_action = dee_READ; +#endif + +static int DEE_action = DEE_READ; +static int error_count = 0; +static int filenames = FN_DEFAULT; +static int pcre_options = 0; +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; + +static BOOL count_only = FALSE; +static BOOL do_colour = FALSE; +static BOOL file_offsets = FALSE; +static BOOL hyphenpending = FALSE; +static BOOL invert = FALSE; +static BOOL line_buffered = FALSE; +static BOOL line_offsets = FALSE; +static BOOL multiline = FALSE; +static BOOL number = FALSE; +static BOOL omit_zero_count = FALSE; +static BOOL resource_error = FALSE; +static BOOL quiet = FALSE; +static BOOL show_only_matching = FALSE; +static BOOL silent = FALSE; +static BOOL utf8 = FALSE; + +/* Structure for list of --only-matching capturing numbers. */ + +typedef struct omstr { + struct omstr *next; + int groupnum; +} omstr; + +static omstr *only_matching = NULL; +static omstr *only_matching_last = NULL; + +/* Structure for holding the two variables that describe a number chain. */ + +typedef struct omdatastr { + omstr **anchor; + omstr **lastptr; +} omdatastr; + +static omdatastr only_matching_data = { &only_matching, &only_matching_last }; + +/* Structure for list of file names (for -f and --{in,ex}clude-from) */ + +typedef struct fnstr { + struct fnstr *next; + char *name; +} fnstr; + +static fnstr *exclude_from = NULL; +static fnstr *exclude_from_last = NULL; +static fnstr *include_from = NULL; +static fnstr *include_from_last = NULL; + +static fnstr *file_lists = NULL; +static fnstr *file_lists_last = NULL; +static fnstr *pattern_files = NULL; +static fnstr *pattern_files_last = NULL; + +/* Structure for holding the two variables that describe a file name chain. */ + +typedef struct fndatastr { + fnstr **anchor; + fnstr **lastptr; +} fndatastr; + +static fndatastr exclude_from_data = { &exclude_from, &exclude_from_last }; +static fndatastr include_from_data = { &include_from, &include_from_last }; +static fndatastr file_lists_data = { &file_lists, &file_lists_last }; +static fndatastr pattern_files_data = { &pattern_files, &pattern_files_last }; + +/* Structure for pattern and its compiled form; used for matching patterns and +also for include/exclude patterns. */ + +typedef struct patstr { + struct patstr *next; + char *string; + pcre *compiled; + pcre_extra *hint; +} patstr; + +static patstr *patterns = NULL; +static patstr *patterns_last = NULL; +static patstr *include_patterns = NULL; +static patstr *include_patterns_last = NULL; +static patstr *exclude_patterns = NULL; +static patstr *exclude_patterns_last = NULL; +static patstr *include_dir_patterns = NULL; +static patstr *include_dir_patterns_last = NULL; +static patstr *exclude_dir_patterns = NULL; +static patstr *exclude_dir_patterns_last = NULL; + +/* Structure holding the two variables that describe a pattern chain. A pointer +to such structures is used for each appropriate option. */ + +typedef struct patdatastr { + patstr **anchor; + patstr **lastptr; +} patdatastr; + +static patdatastr match_patdata = { &patterns, &patterns_last }; +static patdatastr include_patdata = { &include_patterns, &include_patterns_last }; +static patdatastr exclude_patdata = { &exclude_patterns, &exclude_patterns_last }; +static patdatastr include_dir_patdata = { &include_dir_patterns, &include_dir_patterns_last }; +static patdatastr exclude_dir_patdata = { &exclude_dir_patterns, &exclude_dir_patterns_last }; + +static patstr **incexlist[4] = { &include_patterns, &exclude_patterns, + &include_dir_patterns, &exclude_dir_patterns }; + +static const char *incexname[4] = { "--include", "--exclude", + "--include-dir", "--exclude-dir" }; + +/* Structure for options and list of them */ + +enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_LONGNUMBER, + OP_OP_NUMBER, OP_OP_NUMBERS, OP_PATLIST, OP_FILELIST, OP_BINFILES }; + +typedef struct option_item { + int type; + int one_char; + void *dataptr; + const char *long_name; + const char *help_text; +} option_item; + +/* Options without a single-letter equivalent get a negative value. This can be +used to identify them. */ + +#define N_COLOUR (-1) +#define N_EXCLUDE (-2) +#define N_EXCLUDE_DIR (-3) +#define N_HELP (-4) +#define N_INCLUDE (-5) +#define N_INCLUDE_DIR (-6) +#define N_LABEL (-7) +#define N_LOCALE (-8) +#define N_NULL (-9) +#define N_LOFFSETS (-10) +#define N_FOFFSETS (-11) +#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) +#define N_EXCLUDE_FROM (-19) +#define N_INCLUDE_FROM (-20) +#define N_OM_SEPARATOR (-21) + +static option_item optionlist[] = { + { 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" }, + { OP_NODATA, 'c', NULL, "count", "print only a count of matching lines per FILE" }, + { OP_STRING, 'D', &DEE_option, "devices=action","how to handle devices, FIFOs, and sockets" }, + { OP_STRING, 'd', &dee_option, "directories=action", "how to handle directories" }, + { OP_PATLIST, 'e', &match_patdata, "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_FILELIST, 'f', &pattern_files_data, "file=path", "read patterns from file" }, + { OP_FILELIST, N_FILE_LIST, &file_lists_data, "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" }, + { OP_NODATA, N_LBUFFER, NULL, "line-buffered", "use line buffering" }, + { OP_NODATA, N_LOFFSETS, NULL, "line-offsets", "output line numbers and offsets, not text" }, + { OP_STRING, N_LOCALE, &locale, "locale=locale", "use the named locale" }, + { OP_LONGNUMBER, N_M_LIMIT, &match_limit, "match-limit=number", "set PCRE match limit option" }, + { OP_LONGNUMBER, N_M_LIMIT_REC, &match_limit_recursion, "recursion-limit=number", "set PCRE match recursion limit option" }, + { OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" }, + { OP_STRING, 'N', &newline, "newline=type", "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" }, + { OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" }, + { OP_OP_NUMBERS, 'o', &only_matching_data, "only-matching=n", "show only the part of the line that matched" }, + { OP_STRING, N_OM_SEPARATOR, &om_separator, "om-separator=text", "set separator for multiple -o output" }, + { OP_NODATA, 'q', NULL, "quiet", "suppress output, just set return code" }, + { OP_NODATA, 'r', NULL, "recursive", "recursively scan sub-directories" }, + { OP_PATLIST, N_EXCLUDE,&exclude_patdata, "exclude=pattern","exclude matching files when recursing" }, + { OP_PATLIST, N_INCLUDE,&include_patdata, "include=pattern","include matching files when recursing" }, + { OP_PATLIST, N_EXCLUDE_DIR,&exclude_dir_patdata, "exclude-dir=pattern","exclude matching directories when recursing" }, + { OP_PATLIST, N_INCLUDE_DIR,&include_dir_patdata, "include-dir=pattern","include matching directories when recursing" }, + { OP_FILELIST, N_EXCLUDE_FROM,&exclude_from_data, "exclude-from=path", "read exclude list from file" }, + { OP_FILELIST, N_INCLUDE_FROM,&include_from_data, "include-from=path", "read include list from file" }, + + /* These two were accidentally implemented with underscores instead of + hyphens in the option names. As this was not discovered for several releases, + the incorrect versions are left in the table for compatibility. However, the + --help function misses out any option that has an underscore in its name. */ + + { OP_PATLIST, N_EXCLUDE_DIR,&exclude_dir_patdata, "exclude_dir=pattern","exclude matching directories when recursing" }, + { OP_PATLIST, N_INCLUDE_DIR,&include_dir_patdata, "include_dir=pattern","include matching directories when recursing" }, + +#ifdef JFRIEDL_DEBUG + { OP_OP_NUMBER, 'S', &S_arg, "jeffS", "replace matched (sub)string with X" }, +#endif + { OP_NODATA, 's', NULL, "no-messages", "suppress error messages" }, + { OP_NODATA, 'u', NULL, "utf-8", "use UTF-8 mode" }, + { OP_NODATA, 'V', NULL, "version", "print version information and exit" }, + { OP_NODATA, 'v', NULL, "invert-match", "select non-matching lines" }, + { OP_NODATA, 'w', NULL, "word-regex(p)", "force patterns to match only as words" }, + { OP_NODATA, 'x', NULL, "line-regex(p)", "force patterns to match only whole lines" }, + { OP_NODATA, 0, NULL, NULL, NULL } +}; + +/* Tables for prefixing and suffixing patterns, according to the -w, -x, and -F +options. These set the 1, 2, and 4 bits in process_options, respectively. Note +that the combination of -w and -x has the same effect as -x on its own, so we +can treat them as the same. Note that the MAXPATLEN macro assumes the longest +prefix+suffix is 10 characters; if anything longer is added, it must be +adjusted. */ + +static const char *prefix[] = { + "", "\\b", "^(?:", "^(?:", "\\Q", "\\b\\Q", "^(?:\\Q", "^(?:\\Q" }; + +static const char *suffix[] = { + "", "\\b", ")$", ")$", "\\E", "\\E\\b", "\\E)$", "\\E)$" }; + +/* UTF-8 tables - used only when the newline setting is "any". */ + +const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + +const char 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 }; + + + +/************************************************* +* Exit from the program * +*************************************************/ + +/* If there has been a resource error, give a suitable message. + +Argument: the return code +Returns: does not return +*/ + +static void +pcregrep_exit(int rc) +{ +if (resource_error) + { + 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"); + } +exit(rc); +} + + +/************************************************* +* Add item to chain of patterns * +*************************************************/ + +/* Used to add an item onto a chain, or just return an unconnected item if the +"after" argument is NULL. + +Arguments: + s pattern string to add + after if not NULL points to item to insert after + +Returns: new pattern block +*/ + +static patstr * +add_pattern(char *s, patstr *after) +{ +patstr *p = (patstr *)malloc(sizeof(patstr)); +if (p == NULL) + { + fprintf(stderr, "pcregrep: malloc failed\n"); + pcregrep_exit(2); + } +if (strlen(s) > MAXPATLEN) + { + fprintf(stderr, "pcregrep: pattern is too long (limit is %d bytes)\n", + MAXPATLEN); + return NULL; + } +p->next = NULL; +p->string = s; +p->compiled = NULL; +p->hint = NULL; + +if (after != NULL) + { + p->next = after->next; + after->next = p; + } +return p; +} + + +/************************************************* +* Free chain of patterns * +*************************************************/ + +/* Used for several chains of patterns. + +Argument: pointer to start of chain +Returns: nothing +*/ + +static void +free_pattern_chain(patstr *pc) +{ +while (pc != NULL) + { + patstr *p = pc; + pc = p->next; + if (p->hint != NULL) pcre_free_study(p->hint); + if (p->compiled != NULL) pcre_free(p->compiled); + free(p); + } +} + + +/************************************************* +* Free chain of file names * +*************************************************/ + +/* +Argument: pointer to start of chain +Returns: nothing +*/ + +static void +free_file_chain(fnstr *fn) +{ +while (fn != NULL) + { + fnstr *f = fn; + fn = f->next; + free(f); + } +} + + +/************************************************* +* OS-specific functions * +*************************************************/ + +/* These functions are defined so that they can be made system specific, +although at present the only ones are for Unix, Win32, and for "no support". */ + + +/************* Directory scanning in Unix ***********/ + +#if defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H +#include +#include +#include + +typedef DIR directory_type; +#define FILESEP '/' + +static int +isdirectory(char *filename) +{ +struct stat statbuf; +if (stat(filename, &statbuf) < 0) + return 0; /* In the expectation that opening as a file will fail */ +return (statbuf.st_mode & S_IFMT) == S_IFDIR; +} + +static directory_type * +opendirectory(char *filename) +{ +return opendir(filename); +} + +static char * +readdirectory(directory_type *dir) +{ +for (;;) + { + struct dirent *dent = readdir(dir); + if (dent == NULL) return NULL; + if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0) + return dent->d_name; + } +/* Control never reaches here */ +} + +static void +closedirectory(directory_type *dir) +{ +closedir(dir); +} + + +/************* Test for regular file in Unix **********/ + +static int +isregfile(char *filename) +{ +struct stat statbuf; +if (stat(filename, &statbuf) < 0) + return 1; /* In the expectation that opening as a file will fail */ +return (statbuf.st_mode & S_IFMT) == S_IFREG; +} + + +/************* Test for a terminal in Unix **********/ + +static BOOL +is_stdout_tty(void) +{ +return isatty(fileno(stdout)); +} + +static BOOL +is_file_tty(FILE *f) +{ +return isatty(fileno(f)); +} + + +/************* Directory scanning in Win32 ***********/ + +/* I (Philip Hazel) have no means of testing this code. It was contributed by +Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES +when it did not exist. David Byron added a patch that moved the #include of + to before the INVALID_FILE_ATTRIBUTES definition rather than after. +The double test below stops gcc 4.4.4 grumbling that HAVE_WINDOWS_H is +undefined when it is indeed undefined. */ + +#elif defined HAVE_WINDOWS_H && HAVE_WINDOWS_H + +#ifndef STRICT +# define STRICT +#endif +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#include + +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF +#endif + +typedef struct directory_type +{ +HANDLE handle; +BOOL first; +WIN32_FIND_DATA data; +} directory_type; + +#define FILESEP '/' + +int +isdirectory(char *filename) +{ +DWORD attr = GetFileAttributes(filename); +if (attr == INVALID_FILE_ATTRIBUTES) + return 0; +return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; +} + +directory_type * +opendirectory(char *filename) +{ +size_t len; +char *pattern; +directory_type *dir; +DWORD err; +len = strlen(filename); +pattern = (char *)malloc(len + 3); +dir = (directory_type *)malloc(sizeof(*dir)); +if ((pattern == NULL) || (dir == NULL)) + { + fprintf(stderr, "pcregrep: malloc failed\n"); + pcregrep_exit(2); + } +memcpy(pattern, filename, len); +memcpy(&(pattern[len]), "\\*", 3); +dir->handle = FindFirstFile(pattern, &(dir->data)); +if (dir->handle != INVALID_HANDLE_VALUE) + { + free(pattern); + dir->first = TRUE; + return dir; + } +err = GetLastError(); +free(pattern); +free(dir); +errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT; +return NULL; +} + +char * +readdirectory(directory_type *dir) +{ +for (;;) + { + if (!dir->first) + { + if (!FindNextFile(dir->handle, &(dir->data))) + return NULL; + } + else + { + dir->first = FALSE; + } + if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0) + return dir->data.cFileName; + } +#ifndef _MSC_VER +return NULL; /* Keep compiler happy; never executed */ +#endif +} + +void +closedirectory(directory_type *dir) +{ +FindClose(dir->handle); +free(dir); +} + + +/************* Test for regular file in Win32 **********/ + +/* I don't know how to do this, or if it can be done; assume all paths are +regular if they are not directories. */ + +int isregfile(char *filename) +{ +return !isdirectory(filename); +} + + +/************* Test for a terminal in Win32 **********/ + +/* I don't know how to do this; assume never */ + +static BOOL +is_stdout_tty(void) +{ +return FALSE; +} + +static BOOL +is_file_tty(FILE *f) +{ +return FALSE; +} + + +/************* Directory scanning when we can't do it ***********/ + +/* The type is void, and apart from isdirectory(), the functions do nothing. */ + +#else + +#define FILESEP 0 +typedef void directory_type; + +int isdirectory(char *filename) { return 0; } +directory_type * opendirectory(char *filename) { return (directory_type*)0;} +char *readdirectory(directory_type *dir) { return (char*)0;} +void closedirectory(directory_type *dir) {} + + +/************* Test for regular when we can't do it **********/ + +/* Assume all files are regular. */ + +int isregfile(char *filename) { return 1; } + + +/************* Test for a terminal when we can't do it **********/ + +static BOOL +is_stdout_tty(void) +{ +return FALSE; +} + +static BOOL +is_file_tty(FILE *f) +{ +return FALSE; +} + +#endif + + + +#ifndef HAVE_STRERROR +/************************************************* +* Provide strerror() for non-ANSI libraries * +*************************************************/ + +/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() +in their libraries, but can provide the same facility by this simple +alternative function. */ + +extern int sys_nerr; +extern char *sys_errlist[]; + +char * +strerror(int n) +{ +if (n < 0 || n >= sys_nerr) return "unknown error number"; +return sys_errlist[n]; +} +#endif /* HAVE_STRERROR */ + + + +/************************************************* +* Usage function * +*************************************************/ + +static int +usage(int rc) +{ +option_item *op; +fprintf(stderr, "Usage: pcregrep [-"); +for (op = optionlist; op->one_char != 0; op++) + { + if (op->one_char > 0) fprintf(stderr, "%c", op->one_char); + } +fprintf(stderr, "] [long options] [pattern] [files]\n"); +fprintf(stderr, "Type `pcregrep --help' for more information and the long " + "options.\n"); +return rc; +} + + + +/************************************************* +* Help function * +*************************************************/ + +static void +help(void) +{ +option_item *op; + +printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n"); +printf("Search for PATTERN in each FILE or standard input.\n"); +printf("PATTERN must be present if neither -e nor -f is used.\n"); +printf("\"-\" can be used as a file name to mean STDIN.\n"); + +#ifdef SUPPORT_LIBZ +printf("Files whose names end in .gz are read using zlib.\n"); +#endif + +#ifdef SUPPORT_LIBBZ2 +printf("Files whose names end in .bz2 are read using bzlib2.\n"); +#endif + +#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 +printf("Other files and the standard input are read as plain files.\n\n"); +#else +printf("All files are read as plain files, without any interpretation.\n\n"); +#endif + +printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n"); +printf("Options:\n"); + +for (op = optionlist; op->one_char != 0; op++) + { + int n; + char s[4]; + + /* Two options were accidentally implemented and documented with underscores + instead of hyphens in their names, something that was not noticed for quite a + few releases. When fixing this, I left the underscored versions in the list + in case people were using them. However, we don't want to display them in the + help data. There are no other options that contain underscores, and we do not + expect ever to implement such options. Therefore, just omit any option that + contains an underscore. */ + + if (strchr(op->long_name, '_') != NULL) continue; + + 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("\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("The maximum size of any pattern is %d bytes.\n", MAXPATLEN); + +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"); +} + + + +/************************************************* +* Test exclude/includes * +*************************************************/ + +/* If any exclude pattern matches, the path is excluded. Otherwise, unless +there are no includes, the path must match an include pattern. + +Arguments: + path the path to be matched + ip the chain of include patterns + ep the chain of exclude patterns + +Returns: TRUE if the path is not excluded +*/ + +static BOOL +test_incexc(char *path, patstr *ip, patstr *ep) +{ +int plen = strlen(path); + +for (; ep != NULL; ep = ep->next) + { + if (pcre_exec(ep->compiled, NULL, path, plen, 0, 0, NULL, 0) >= 0) + return FALSE; + } + +if (ip == NULL) return TRUE; + +for (; ip != NULL; ip = ip->next) + { + if (pcre_exec(ip->compiled, NULL, path, plen, 0, 0, NULL, 0) >= 0) + return TRUE; + } + +return FALSE; +} + + + +/************************************************* +* Decode integer argument value * +*************************************************/ + +/* Integer arguments can be followed by K or M. Avoid the use of strtoul() +because SunOS4 doesn't have it. This is used only for unpicking arguments, so +just keep it simple. + +Arguments: + option_data the option data string + op the option item (for error messages) + longop TRUE if option given in long form + +Returns: a long integer +*/ + +static long int +decode_number(char *option_data, option_item *op, BOOL longop) +{ +unsigned long int n = 0; +char *endptr = option_data; +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) /* Error */ + { + if (longop) + { + char *equals = strchr(op->long_name, '='); + int nlen = (equals == NULL)? (int)strlen(op->long_name) : + (int)(equals - op->long_name); + fprintf(stderr, "pcregrep: Malformed number \"%s\" after --%.*s\n", + option_data, nlen, op->long_name); + } + else + fprintf(stderr, "pcregrep: Malformed number \"%s\" after -%c\n", + option_data, op->one_char); + pcregrep_exit(usage(2)); + } + +return n; +} + + + +/************************************************* +* Add item to a chain of numbers * +*************************************************/ + +/* Used to add an item onto a chain, or just return an unconnected item if the +"after" argument is NULL. + +Arguments: + n the number to add + after if not NULL points to item to insert after + +Returns: new number block +*/ + +static omstr * +add_number(int n, omstr *after) +{ +omstr *om = (omstr *)malloc(sizeof(omstr)); + +if (om == NULL) + { + fprintf(stderr, "pcregrep: malloc failed\n"); + pcregrep_exit(2); + } +om->next = NULL; +om->groupnum = n; + +if (after != NULL) + { + om->next = after->next; + after->next = om; + } +return om; +} + + + +/************************************************* +* Read one line of input * +*************************************************/ + +/* Normally, input is read using fread() into a large buffer, so many lines may +be read at once. However, doing this for tty input means that no output appears +until a lot of input has been typed. Instead, tty input is handled line by +line. We cannot use fgets() for this, because it does not stop at a binary +zero, and therefore there is no way of telling how many characters it has read, +because there may be binary zeros embedded in the data. + +Arguments: + buffer the buffer to read into + length the maximum number of characters to read + f the file + +Returns: the number of characters read, zero at end of file +*/ + +static unsigned int +read_one_line(char *buffer, int length, FILE *f) +{ +int c; +int yield = 0; +while ((c = fgetc(f)) != EOF) + { + buffer[yield++] = c; + if (c == '\n' || yield >= length) break; + } +return yield; +} + + + +/************************************************* +* Find end of line * +*************************************************/ + +/* The length of the endline sequence that is found is set via lenptr. This may +be zero at the very end of the file if there is no line-ending sequence there. + +Arguments: + p current position in line + endptr end of available data + lenptr where to put the length of the eol sequence + +Returns: pointer after the last byte of the line, + including the newline byte(s) +*/ + +static char * +end_of_line(char *p, char *endptr, int *lenptr) +{ +switch(endlinetype) + { + default: /* Just in case */ + case EL_LF: + while (p < endptr && *p != '\n') p++; + if (p < endptr) + { + *lenptr = 1; + return p + 1; + } + *lenptr = 0; + return endptr; + + case EL_CR: + while (p < endptr && *p != '\r') p++; + if (p < endptr) + { + *lenptr = 1; + return p + 1; + } + *lenptr = 0; + return endptr; + + case EL_CRLF: + for (;;) + { + while (p < endptr && *p != '\r') p++; + if (++p >= endptr) + { + *lenptr = 0; + return endptr; + } + if (*p == '\n') + { + *lenptr = 2; + return p + 1; + } + } + break; + + case EL_ANYCRLF: + while (p < endptr) + { + int extra = 0; + register int c = *((unsigned char *)p); + + if (utf8 && c >= 0xc0) + { + int gcii, gcss; + extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ + gcss = 6*extra; + c = (c & utf8_table3[extra]) << gcss; + for (gcii = 1; gcii <= extra; gcii++) + { + gcss -= 6; + c |= (p[gcii] & 0x3f) << gcss; + } + } + + p += 1 + extra; + + switch (c) + { + case '\n': + *lenptr = 1; + return p; + + case '\r': + if (p < endptr && *p == '\n') + { + *lenptr = 2; + p++; + } + else *lenptr = 1; + return p; + + default: + break; + } + } /* End of loop for ANYCRLF case */ + + *lenptr = 0; /* Must have hit the end */ + return endptr; + + case EL_ANY: + while (p < endptr) + { + int extra = 0; + register int c = *((unsigned char *)p); + + if (utf8 && c >= 0xc0) + { + int gcii, gcss; + extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ + gcss = 6*extra; + c = (c & utf8_table3[extra]) << gcss; + for (gcii = 1; gcii <= extra; gcii++) + { + gcss -= 6; + c |= (p[gcii] & 0x3f) << gcss; + } + } + + p += 1 + extra; + + switch (c) + { + case '\n': /* LF */ + case '\v': /* VT */ + case '\f': /* FF */ + *lenptr = 1; + return p; + + case '\r': /* CR */ + if (p < endptr && *p == '\n') + { + *lenptr = 2; + p++; + } + else *lenptr = 1; + return p; + +#ifndef EBCDIC + case 0x85: /* Unicode NEL */ + *lenptr = utf8? 2 : 1; + return p; + + case 0x2028: /* Unicode LS */ + case 0x2029: /* Unicode PS */ + *lenptr = 3; + return p; +#endif /* Not EBCDIC */ + + default: + break; + } + } /* End of loop for ANY case */ + + *lenptr = 0; /* Must have hit the end */ + return endptr; + } /* End of overall switch */ +} + + + +/************************************************* +* Find start of previous line * +*************************************************/ + +/* This is called when looking back for before lines to print. + +Arguments: + p start of the subsequent line + startptr start of available data + +Returns: pointer to the start of the previous line +*/ + +static char * +previous_line(char *p, char *startptr) +{ +switch(endlinetype) + { + default: /* Just in case */ + case EL_LF: + p--; + while (p > startptr && p[-1] != '\n') p--; + return p; + + case EL_CR: + p--; + while (p > startptr && p[-1] != '\n') p--; + return p; + + case EL_CRLF: + for (;;) + { + p -= 2; + while (p > startptr && p[-1] != '\n') p--; + if (p <= startptr + 1 || p[-2] == '\r') return p; + } + return p; /* But control should never get here */ + + case EL_ANY: + case EL_ANYCRLF: + if (*(--p) == '\n' && p > startptr && p[-1] == '\r') p--; + if (utf8) while ((*p & 0xc0) == 0x80) p--; + + while (p > startptr) + { + register unsigned int c; + char *pp = p - 1; + + if (utf8) + { + int extra = 0; + while ((*pp & 0xc0) == 0x80) pp--; + c = *((unsigned char *)pp); + if (c >= 0xc0) + { + int gcii, gcss; + extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */ + gcss = 6*extra; + c = (c & utf8_table3[extra]) << gcss; + for (gcii = 1; gcii <= extra; gcii++) + { + gcss -= 6; + c |= (pp[gcii] & 0x3f) << gcss; + } + } + } + else c = *((unsigned char *)pp); + + if (endlinetype == EL_ANYCRLF) switch (c) + { + case '\n': /* LF */ + case '\r': /* CR */ + return p; + + default: + break; + } + + else switch (c) + { + case '\n': /* LF */ + case '\v': /* VT */ + case '\f': /* FF */ + case '\r': /* CR */ +#ifndef EBCDIE + case 0x85: /* Unicode NEL */ + case 0x2028: /* Unicode LS */ + case 0x2029: /* Unicode PS */ +#endif /* Not EBCDIC */ + return p; + + default: + break; + } + + p = pp; /* Back one character */ + } /* End of loop for ANY case */ + + return startptr; /* Hit start of data */ + } /* End of overall switch */ +} + + + + + +/************************************************* +* Print the previous "after" lines * +*************************************************/ + +/* This is called if we are about to lose said lines because of buffer filling, +and at the end of the file. The data in the line is written using fwrite() so +that a binary zero does not terminate it. + +Arguments: + lastmatchnumber the number of the last matching line, plus one + lastmatchrestart where we restarted after the last match + endptr end of available data + printname filename for printing + +Returns: nothing +*/ + +static void +do_after_lines(int lastmatchnumber, char *lastmatchrestart, char *endptr, + char *printname) +{ +if (after_context > 0 && lastmatchnumber > 0) + { + int count = 0; + while (lastmatchrestart < endptr && count++ < after_context) + { + int ellength; + char *pp = lastmatchrestart; + if (printname != NULL) fprintf(stdout, "%s-", printname); + if (number) fprintf(stdout, "%d-", lastmatchnumber++); + pp = end_of_line(pp, endptr, &ellength); + FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout); + lastmatchrestart = pp; + } + hyphenpending = TRUE; + } +} + + + +/************************************************* +* Apply patterns to subject till one matches * +*************************************************/ + +/* This function is called to run through all patterns, looking for a match. It +is used multiple times for the same subject when colouring is enabled, in order +to find all possible matches. + +Arguments: + 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 + invert if there was a non-fatal error +*/ + +static BOOL +match_patterns(char *matchptr, size_t length, int startoffset, int *offsets, + int *mrc) +{ +int i; +size_t slen = length; +patstr *p = patterns; +const char *msg = "this text:\n\n"; + +if (slen > 200) + { + slen = 200; + msg = "text that starts:\n\n"; + } +for (i = 1; p != NULL; p = p->next, i++) + { + *mrc = pcre_exec(p->compiled, p->hint, 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); + if (patterns->next != NULL) fprintf(stderr, "pattern number %d to ", i); + 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 || + *mrc == PCRE_ERROR_JIT_STACKLIMIT) + resource_error = TRUE; + if (error_count++ > 20) + { + fprintf(stderr, "pcregrep: Too many errors - abandoned.\n"); + pcregrep_exit(2); + } + return invert; /* No more matching; don't show the line again */ + } + +return FALSE; /* No match, no errors */ +} + + + +/************************************************* +* Grep an individual file * +*************************************************/ + +/* This is called from grep_or_recurse() below. It uses a buffer that is three +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 +"before" context printing. + +Arguments: + handle the fopened FILE stream for a normal file + 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 an overlong line is encountered + 3 if there is a read error on a .bz2 file +*/ + +static int +pcregrep(void *handle, int frtype, char *filename, char *printname) +{ +int rc = 1; +int linenumber = 1; +int lastmatchnumber = 0; +int count = 0; +int filepos = 0; +int offsets[OFFSET_SIZE]; +char *lastmatchrestart = NULL; +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 */ + +#ifdef SUPPORT_LIBZ +gzFile ingz = NULL; +#endif + +#ifdef SUPPORT_LIBBZ2 +BZFILE *inbz2 = NULL; +#endif + + +/* Do the first read into the start of the buffer and set up the pointer to end +of what we have. In the case of libz, a non-zipped .gz file will be read as a +plain file. However, if a .bz2 file isn't actually bzipped, the first read will +fail. */ + +(void)frtype; + +#ifdef SUPPORT_LIBZ +if (frtype == FR_LIBZ) + { + ingz = (gzFile)handle; + bufflength = gzread (ingz, main_buffer, bufsize); + } +else +#endif + +#ifdef SUPPORT_LIBBZ2 +if (frtype == FR_LIBBZ2) + { + inbz2 = (BZFILE *)handle; + 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 +#endif + + { + in = (FILE *)handle; + if (is_file_tty(in)) input_line_buffered = TRUE; + bufflength = input_line_buffered? + read_one_line(main_buffer, bufsize, in) : + fread(main_buffer, 1, bufsize, in); + } + +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 +file, but ptr will never get there, because as soon as it gets over 2/3 of the +way, the buffer is shifted left and re-filled. */ + +while (ptr < endptr) + { + int endlinelength; + int mrc = 0; + int startoffset = 0; + BOOL match; + char *matchptr = ptr; + char *t = ptr; + size_t length, linelength; + + /* At this point, ptr is at the start of a line. We need to find the length + of the subject string to pass to pcre_exec(). In multiline mode, it is the + length remainder of the data in the buffer. Otherwise, it is the length of + the next line, excluding the terminating newline. After matching, we always + advance by the length of the next line. In multiline mode the PCRE_FIRSTLINE + option is used for compiling, so that any match is constrained to be in the + first line. */ + + t = end_of_line(t, endptr, &endlinelength); + 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 + if (jfriedl_XT || jfriedl_XR) + { +# include +# include + struct timeval start_time, end_time; + struct timezone dummy; + int i; + + if (jfriedl_XT) + { + unsigned long newlen = length * jfriedl_XT + strlen(jfriedl_prefix) + strlen(jfriedl_postfix); + const char *orig = ptr; + ptr = malloc(newlen + 1); + if (!ptr) { + printf("out of memory"); + pcregrep_exit(2); + } + endptr = ptr; + strcpy(endptr, jfriedl_prefix); endptr += strlen(jfriedl_prefix); + for (i = 0; i < jfriedl_XT; i++) { + strncpy(endptr, orig, length); + endptr += length; + } + strcpy(endptr, jfriedl_postfix); endptr += strlen(jfriedl_postfix); + length = newlen; + } + + if (gettimeofday(&start_time, &dummy) != 0) + perror("bad gettimeofday"); + + + for (i = 0; i < jfriedl_XR; i++) + match = (pcre_exec(patterns->compiled, patterns->hint, ptr, length, 0, + PCRE_NOTEMPTY, offsets, OFFSET_SIZE) >= 0); + + if (gettimeofday(&end_time, &dummy) != 0) + perror("bad gettimeofday"); + + double delta = ((end_time.tv_sec + (end_time.tv_usec / 1000000.0)) + - + (start_time.tv_sec + (start_time.tv_usec / 1000000.0))); + + printf("%s TIMER[%.4f]\n", match ? "MATCH" : "FAIL", delta); + return 0; + } +#endif + + /* We come back here after a match when show_only_matching is set, in order + to find any further matches in the same line. This applies to + --only-matching, --file-offsets, and --line-offsets. */ + + ONLY_MATCHING_RESTART: + + /* Run through all the patterns until one matches or there is an error other + 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, startoffset, offsets, &mrc); + + /* If it's a match or a not-match (as required), do what's wanted. */ + + if (match != invert) + { + BOOL hyphenprinted = FALSE; + + /* We've failed if we want a file that doesn't have any matches. */ + + if (filenames == FN_NOMATCH_ONLY) return 1; + + /* Just count if just counting is wanted. */ + + 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. */ + + else if (filenames == FN_MATCH_ONLY) + { + fprintf(stdout, "%s\n", printname); + return 0; + } + + /* Likewise, if all we want is a yes/no answer. */ + + else if (quiet) return 0; + + /* The --only-matching option prints just the substring that matched, + and/or one or more captured portions of it, as long as these strings are + not empty. The --file-offsets and --line-offsets options output offsets for + the matching substring (all three set show_only_matching). None of these + mutually exclusive options 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 (show_only_matching) + { + if (!invert) + { + if (printname != NULL) fprintf(stdout, "%s:", printname); + if (number) fprintf(stdout, "%d:", linenumber); + + /* Handle --line-offsets */ + + if (line_offsets) + fprintf(stdout, "%d,%d\n", (int)(matchptr + offsets[0] - ptr), + offsets[1] - offsets[0]); + + /* Handle --file-offsets */ + + else if (file_offsets) + fprintf(stdout, "%d,%d\n", + (int)(filepos + matchptr + offsets[0] - ptr), + offsets[1] - offsets[0]); + + /* Handle --only-matching, which may occur many times */ + + else + { + BOOL printed = FALSE; + omstr *om; + + for (om = only_matching; om != NULL; om = om->next) + { + int n = om->groupnum; + if (n < mrc) + { + int plen = offsets[2*n + 1] - offsets[2*n]; + if (plen > 0) + { + if (printed) fprintf(stdout, "%s", om_separator); + if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string); + FWRITE(matchptr + offsets[n*2], 1, plen, stdout); + if (do_colour) fprintf(stdout, "%c[00m", 0x1b); + printed = TRUE; + } + } + } + + if (printed || printname != NULL || number) fprintf(stdout, "\n"); + } + + /* Prepare to repeat to find the next match */ + + match = FALSE; + if (line_buffered) fflush(stdout); + rc = 0; /* Had some success */ + startoffset = offsets[1]; /* Restart after the match */ + goto ONLY_MATCHING_RESTART; + } + } + + /* This is the default case when none of the above options is set. We print + the matching lines(s), possibly preceded and/or followed by other lines of + context. */ + + else + { + /* See if there is a requirement to print some "after" lines from a + previous match. We never print any overlaps. */ + + if (after_context > 0 && lastmatchnumber > 0) + { + int ellength; + int linecount = 0; + char *p = lastmatchrestart; + + while (p < ptr && linecount < after_context) + { + p = end_of_line(p, ptr, &ellength); + linecount++; + } + + /* It is important to advance lastmatchrestart during this printing so + that it interacts correctly with any "before" printing below. Print + each line's data using fwrite() in case there are binary zeroes. */ + + while (lastmatchrestart < p) + { + char *pp = lastmatchrestart; + if (printname != NULL) fprintf(stdout, "%s-", printname); + if (number) fprintf(stdout, "%d-", lastmatchnumber++); + pp = end_of_line(pp, endptr, &ellength); + FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout); + lastmatchrestart = pp; + } + if (lastmatchrestart != ptr) hyphenpending = TRUE; + } + + /* If there were non-contiguous lines printed above, insert hyphens. */ + + if (hyphenpending) + { + fprintf(stdout, "--\n"); + hyphenpending = FALSE; + hyphenprinted = TRUE; + } + + /* See if there is a requirement to print some "before" lines for this + match. Again, don't print overlaps. */ + + if (before_context > 0) + { + int linecount = 0; + char *p = ptr; + + while (p > main_buffer && (lastmatchnumber == 0 || p > lastmatchrestart) && + linecount < before_context) + { + linecount++; + p = previous_line(p, main_buffer); + } + + if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted) + fprintf(stdout, "--\n"); + + while (p < ptr) + { + int ellength; + char *pp = p; + if (printname != NULL) fprintf(stdout, "%s-", printname); + if (number) fprintf(stdout, "%d-", linenumber - linecount--); + pp = end_of_line(pp, endptr, &ellength); + FWRITE(p, 1, pp - p, stdout); + p = pp; + } + } + + /* Now print the matching line(s); ensure we set hyphenpending at the end + of the file if any context lines are being output. */ + + if (after_context > 0 || before_context > 0) + endhyphenpending = TRUE; + + if (printname != NULL) fprintf(stdout, "%s:", printname); + if (number) fprintf(stdout, "%d:", linenumber); + + /* In multiline mode, we want to print to the end of the line in which + the end of the matched string is found, so we adjust linelength and the + line number appropriately, but only when there actually was a match + (invert not set). Because the PCRE_FIRSTLINE option is set, the start of + the match will always be before the first newline sequence. */ + + if (multiline & !invert) + { + char *endmatch = ptr + offsets[1]; + t = ptr; + while (t < endmatch) + { + t = end_of_line(t, endptr, &endlinelength); + if (t < endmatch) linenumber++; else break; + } + linelength = t - ptr - endlinelength; + } + + /*** NOTE: Use only fwrite() to output the data line, so that binary + zeroes are treated as just another data character. */ + + /* This extra option, for Jeffrey Friedl's debugging requirements, + replaces the matched string, or a specific captured string if it exists, + with X. When this happens, colouring is ignored. */ + +#ifdef JFRIEDL_DEBUG + if (S_arg >= 0 && S_arg < mrc) + { + int first = S_arg * 2; + int last = first + 1; + FWRITE(ptr, 1, offsets[first], stdout); + fprintf(stdout, "X"); + FWRITE(ptr + offsets[last], 1, linelength - offsets[last], stdout); + } + else +#endif + + /* We have to split the line(s) up if colouring, and search for further + matches, but not of course if the line is a non-match. */ + + if (do_colour && !invert) + { + int plength; + 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 (;;) + { + 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); + } + + /* In multiline mode, we may have already printed the complete line + and its line-ending characters (if they matched the pattern), so there + may be no more to print. */ + + plength = (int)((linelength + endlinelength) - startoffset); + if (plength > 0) FWRITE(ptr + startoffset, 1, plength, stdout); + } + + /* Not colouring; no need to search for further matches */ + + else FWRITE(ptr, 1, linelength + endlinelength, stdout); + } + + /* End of doing what has to be done for a match. If --line-buffered was + given, flush the output. */ + + if (line_buffered) fflush(stdout); + rc = 0; /* Had some success */ + + /* Remember where the last match happened for after_context. We remember + where we are about to restart, and that line's number. */ + + lastmatchrestart = ptr + linelength + endlinelength; + lastmatchnumber = linenumber + 1; + } + + /* For a match in multiline inverted mode (which of course did not cause + anything to be printed), we have to move on to the end of the match before + proceeding. */ + + if (multiline && invert && match) + { + int ellength; + char *endmatch = ptr + offsets[1]; + t = ptr; + while (t < endmatch) + { + t = end_of_line(t, endptr, &ellength); + if (t <= endmatch) linenumber++; else break; + } + endmatch = end_of_line(endmatch, endptr, &ellength); + linelength = endmatch - ptr - ellength; + } + + /* Advance to after the newline and increment the line number. The file + offset to the current line is maintained in filepos. */ + + ptr += linelength + endlinelength; + filepos += (int)(linelength + endlinelength); + linenumber++; + + /* 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 < (size_t)bufsize) + { + int add = read_one_line(ptr, bufsize - (int)(ptr - main_buffer), in); + bufflength += add; + endptr += add; + } + + /* If we haven't yet reached the end of the file (the buffer is full), and + the current point is in the top 1/3 of the buffer, slide the buffer down by + 1/3 and refill it. Before we do this, if some unprinted "after" lines are + about to be lost, print them. */ + + if (bufflength >= (size_t)bufsize && ptr > main_buffer + 2*bufthird) + { + if (after_context > 0 && + lastmatchnumber > 0 && + lastmatchrestart < main_buffer + bufthird) + { + do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); + lastmatchnumber = 0; + } + + /* Now do the shuffle */ + + memmove(main_buffer, main_buffer + bufthird, 2*bufthird); + ptr -= bufthird; + +#ifdef SUPPORT_LIBZ + if (frtype == FR_LIBZ) + bufflength = 2*bufthird + + gzread (ingz, main_buffer + 2*bufthird, bufthird); + else +#endif + +#ifdef SUPPORT_LIBBZ2 + if (frtype == FR_LIBBZ2) + bufflength = 2*bufthird + + BZ2_bzread(inbz2, main_buffer + 2*bufthird, bufthird); + else +#endif + + bufflength = 2*bufthird + + (input_line_buffered? + 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 -= bufthird; + } + } /* Loop through the whole file */ + +/* End of file; print final "after" lines if wanted; do_after_lines sets +hyphenpending if it prints something. */ + +if (!show_only_matching && !count_only) + { + do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); + hyphenpending |= endhyphenpending; + } + +/* Print the file name if we are looking for those without matches and there +were none. If we found a match, we won't have got this far. */ + +if (filenames == FN_NOMATCH_ONLY) + { + fprintf(stdout, "%s\n", printname); + return 0; + } + +/* Print the match count if wanted */ + +if (count_only) + { + if (count > 0 || !omit_zero_count) + { + if (printname != NULL && filenames != FN_NONE) + fprintf(stdout, "%s:", printname); + fprintf(stdout, "%d\n", count); + } + } + +return rc; +} + + + +/************************************************* +* Grep a file or recurse into a directory * +*************************************************/ + +/* Given a path name, if it's a directory, scan all the files if we are +recursing; if it's a file, grep it. + +Arguments: + pathname the path to investigate + dir_recurse TRUE if recursing is wanted (-r or -drecurse) + only_one_at_top TRUE if the path is the only one at toplevel + +Returns: -1 the file/directory was skipped + 0 if there was at least one match + 1 if there were no matches + 2 there was some kind of error + +However, file opening failures are suppressed if "silent" is set. +*/ + +static int +grep_or_recurse(char *pathname, BOOL dir_recurse, BOOL only_one_at_top) +{ +int rc = 1; +int frtype; +void *handle; +char *lastcomp; +FILE *in = NULL; /* Ensure initialized */ + +#ifdef SUPPORT_LIBZ +gzFile ingz = NULL; +#endif + +#ifdef SUPPORT_LIBBZ2 +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, stdin_name, + (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))? + stdin_name : NULL); + } + +/* Inclusion and exclusion: --include-dir and --exclude-dir apply only to +directories, whereas --include and --exclude apply to everything else. The test +is against the final component of the path. */ + +lastcomp = strrchr(pathname, FILESEP); +lastcomp = (lastcomp == NULL)? pathname : lastcomp + 1; + +/* If the file is a directory, skip if not recursing or if explicitly excluded. +Otherwise, scan the directory and recurse for each path within it. The scanning +code is localized so it can be made system-specific. */ + +if (isdirectory(pathname)) + { + if (dee_action == dee_SKIP || + !test_incexc(lastcomp, include_dir_patterns, exclude_dir_patterns)) + return -1; + + if (dee_action == dee_RECURSE) + { + char buffer[1024]; + char *nextfile; + directory_type *dir = opendirectory(pathname); + + if (dir == NULL) + { + if (!silent) + fprintf(stderr, "pcregrep: Failed to open directory %s: %s\n", pathname, + strerror(errno)); + return 2; + } + + while ((nextfile = readdirectory(dir)) != NULL) + { + int frc; + sprintf(buffer, "%.512s%c%.128s", pathname, FILESEP, nextfile); + frc = grep_or_recurse(buffer, dir_recurse, FALSE); + if (frc > 1) rc = frc; + else if (frc == 0 && rc == 1) rc = 0; + } + + closedirectory(dir); + return rc; + } + } + +/* If the file is not a directory and not a regular file, skip it if that's +been requested. Otherwise, check for explicit include/exclude. */ + +else if ((!isregfile(pathname) && DEE_action == DEE_SKIP) || + !test_incexc(lastcomp, include_patterns, exclude_patterns)) + return -1; + +/* Control reaches here if we have a regular file, or if we have a directory +and recursion or skipping was not requested, or if we have anything else and +skipping was not requested. The scan proceeds. If this is the first and only +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. */ + +#ifdef SUPPORT_LIBZ +if (pathlen > 3 && strcmp(pathname + pathlen - 3, ".gz") == 0) + { + ingz = gzopen(pathname, "rb"); + if (ingz == NULL) + { + if (!silent) + fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname, + strerror(errno)); + return 2; + } + handle = (void *)ingz; + frtype = FR_LIBZ; + } +else +#endif + +/* Otherwise open with bz2lib if it is supported and the name ends with .bz2. */ + +#ifdef SUPPORT_LIBBZ2 +if (pathlen > 4 && strcmp(pathname + pathlen - 4, ".bz2") == 0) + { + inbz2 = BZ2_bzopen(pathname, "rb"); + handle = (void *)inbz2; + frtype = FR_LIBBZ2; + } +else +#endif + +/* Otherwise use plain fopen(). The label is so that we can come back here if +an attempt to read a .bz2 file indicates that it really is a plain file. */ + +#ifdef SUPPORT_LIBBZ2 +PLAIN_FILE: +#endif + { + in = fopen(pathname, "rb"); + handle = (void *)in; + frtype = FR_PLAIN; + } + +/* All the opening methods return errno when they fail. */ + +if (handle == NULL) + { + if (!silent) + fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname, + strerror(errno)); + return 2; + } + +/* Now grep the file */ + +rc = pcregrep(handle, frtype, pathname, (filenames > FN_DEFAULT || + (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL); + +/* Close in an appropriate manner. */ + +#ifdef SUPPORT_LIBZ +if (frtype == FR_LIBZ) + gzclose(ingz); +else +#endif + +/* 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 == 3) + { + int errnum; + const char *err = BZ2_bzerror(inbz2, &errnum); + if (errnum == BZ_DATA_ERROR_MAGIC) + { + BZ2_bzclose(inbz2); + goto PLAIN_FILE; + } + 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); + } +else +#endif + +/* Normal file close */ + +fclose(in); + +/* Pass back the yield from pcregrep(). */ + +return rc; +} + + + +/************************************************* +* Handle a single-letter, no data option * +*************************************************/ + +static int +handle_option(int letter, int options) +{ +switch(letter) + { + case N_FOFFSETS: file_offsets = TRUE; break; + case N_HELP: help(); pcregrep_exit(0); + 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; + case 'L': filenames = FN_NOMATCH_ONLY; break; + case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break; + case 'n': number = TRUE; break; + + case 'o': + only_matching_last = add_number(0, only_matching_last); + if (only_matching == NULL) only_matching = only_matching_last; + break; + + case 'q': quiet = TRUE; break; + case 'r': dee_action = dee_RECURSE; break; + case 's': silent = TRUE; break; + case 'u': options |= PCRE_UTF8; utf8 = TRUE; break; + case 'v': invert = TRUE; break; + case 'w': process_options |= PO_WORD_MATCH; break; + case 'x': process_options |= PO_LINE_MATCH; break; + + case 'V': + fprintf(stdout, "pcregrep version %s\n", pcre_version()); + pcregrep_exit(0); + break; + + default: + fprintf(stderr, "pcregrep: Unknown option -%c\n", letter); + pcregrep_exit(usage(2)); + } + +return options; +} + + + + +/************************************************* +* Construct printed ordinal * +*************************************************/ + +/* This turns a number into "1st", "3rd", etc. */ + +static char * +ordin(int n) +{ +static char buffer[8]; +char *p = buffer; +sprintf(p, "%d", n); +while (*p != 0) p++; +switch (n%10) + { + case 1: strcpy(p, "st"); break; + case 2: strcpy(p, "nd"); break; + case 3: strcpy(p, "rd"); break; + default: strcpy(p, "th"); break; + } +return buffer; +} + + + +/************************************************* +* Compile a single pattern * +*************************************************/ + +/* Do nothing if the pattern has already been compiled. This is the case for +include/exclude patterns read from a file. + +When the -F option has been used, each "pattern" may be a list of strings, +separated by line breaks. They will be matched literally. We split such a +string and compile the first substring, inserting an additional block into the +pattern chain. + +Arguments: + p points to the pattern block + options the PCRE options + popts the processing options + fromfile TRUE if the pattern was read from a file + fromtext file name or identifying text (e.g. "include") + count 0 if this is the only command line pattern, or + number of the command line pattern, or + linenumber for a pattern from a file + +Returns: TRUE on success, FALSE after an error +*/ + +static BOOL +compile_pattern(patstr *p, int options, int popts, int fromfile, + const char *fromtext, int count) +{ +char buffer[PATBUFSIZE]; +const char *error; +char *ps = p->string; +int patlen = strlen(ps); +int errptr; + +if (p->compiled != NULL) return TRUE; + +if ((popts & PO_FIXED_STRINGS) != 0) + { + int ellength; + char *eop = ps + patlen; + char *pe = end_of_line(ps, eop, &ellength); + + if (ellength != 0) + { + if (add_pattern(pe, p) == NULL) return FALSE; + patlen = (int)(pe - ps - ellength); + } + } + +sprintf(buffer, "%s%.*s%s", prefix[popts], patlen, ps, suffix[popts]); +p->compiled = pcre_compile(buffer, options, &error, &errptr, pcretables); +if (p->compiled != NULL) return TRUE; + +/* Handle compile errors */ + +errptr -= (int)strlen(prefix[popts]); +if (errptr > patlen) errptr = patlen; + +if (fromfile) + { + fprintf(stderr, "pcregrep: Error in regex in line %d of %s " + "at offset %d: %s\n", count, fromtext, errptr, error); + } +else + { + if (count == 0) + fprintf(stderr, "pcregrep: Error in %s regex at offset %d: %s\n", + fromtext, errptr, error); + else + fprintf(stderr, "pcregrep: Error in %s %s regex at offset %d: %s\n", + ordin(count), fromtext, errptr, error); + } + +return FALSE; +} + + + +/************************************************* +* Read and compile a file of patterns * +*************************************************/ + +/* This is used for --filelist, --include-from, and --exclude-from. + +Arguments: + name the name of the file; "-" is stdin + patptr pointer to the pattern chain anchor + patlastptr pointer to the last pattern pointer + popts the process options to pass to pattern_compile() + +Returns: TRUE if all went well +*/ + +static BOOL +read_pattern_file(char *name, patstr **patptr, patstr **patlastptr, int popts) +{ +int linenumber = 0; +FILE *f; +char *filename; +char buffer[PATBUFSIZE]; + +if (strcmp(name, "-") == 0) + { + f = stdin; + filename = stdin_name; + } +else + { + f = fopen(name, "r"); + if (f == NULL) + { + fprintf(stderr, "pcregrep: Failed to open %s: %s\n", name, strerror(errno)); + return FALSE; + } + filename = name; + } + +while (fgets(buffer, PATBUFSIZE, f) != NULL) + { + char *s = buffer + (int)strlen(buffer); + while (s > buffer && isspace((unsigned char)(s[-1]))) s--; + *s = 0; + linenumber++; + if (buffer[0] == 0) continue; /* Skip blank lines */ + + /* Note: this call to add_pattern() puts a pointer to the local variable + "buffer" into the pattern chain. However, that pointer is used only when + compiling the pattern, which happens immediately below, so we flatten it + afterwards, as a precaution against any later code trying to use it. */ + + *patlastptr = add_pattern(buffer, *patlastptr); + if (*patlastptr == NULL) return FALSE; + if (*patptr == NULL) *patptr = *patlastptr; + + /* This loop is needed because compiling a "pattern" when -F is set may add + on additional literal patterns if the original contains a newline. In the + common case, it never will, because fgets() stops at a newline. However, + the -N option can be used to give pcregrep a different newline setting. */ + + for(;;) + { + if (!compile_pattern(*patlastptr, pcre_options, popts, TRUE, filename, + linenumber)) + return FALSE; + (*patlastptr)->string = NULL; /* Insurance */ + if ((*patlastptr)->next == NULL) break; + *patlastptr = (*patlastptr)->next; + } + } + +if (f != stdin) fclose(f); +return TRUE; +} + + + +/************************************************* +* Main program * +*************************************************/ + +/* Returns 0 if something matched, 1 if nothing matched, 2 after an error. */ + +int +main(int argc, char **argv) +{ +int i, j; +int rc = 1; +BOOL only_one_at_top; +patstr *cp; +fnstr *fn; +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 +codes, are the same in EBCDIC environments, so we must use the actual values +rather than escapes such as as '\r'. */ + +(void)pcre_config(PCRE_CONFIG_NEWLINE, &i); +switch(i) + { + default: newline = (char *)"lf"; break; + case 13: newline = (char *)"cr"; break; + case (13 << 8) | 10: newline = (char *)"crlf"; break; + case -1: newline = (char *)"any"; break; + case -2: newline = (char *)"anycrlf"; break; + } + +/* Process the options */ + +for (i = 1; i < argc; i++) + { + option_item *op = NULL; + char *option_data = (char *)""; /* default to keep compiler happy */ + BOOL longop; + BOOL longopwasequals = FALSE; + + if (argv[i][0] != '-') break; + + /* If we hit an argument that is just "-", it may be a reference to STDIN, + but only if we have previously had -e or -f to define the patterns. */ + + if (argv[i][1] == 0) + { + if (pattern_files != NULL || patterns != NULL) break; + else pcregrep_exit(usage(2)); + } + + /* Handle a long name option, or -- to terminate the options */ + + if (argv[i][1] == '-') + { + char *arg = argv[i] + 2; + char *argequals = strchr(arg, '='); + + if (*arg == 0) /* -- terminates options */ + { + i++; + break; /* out of the options-handling loop */ + } + + longop = TRUE; + + /* Some long options have data that follows after =, for example file=name. + Some options have variations in the long name spelling: specifically, we + allow "regexp" because GNU grep allows it, though I personally go along + with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p". + These options are entered in the table as "regex(p)". Options can be in + both these categories. */ + + for (op = optionlist; op->one_char != 0; op++) + { + char *opbra = strchr(op->long_name, '('); + char *equals = strchr(op->long_name, '='); + + /* Handle options with only one spelling of the name */ + + if (opbra == NULL) /* Does not contain '(' */ + { + if (equals == NULL) /* Not thing=data case */ + { + if (strcmp(arg, op->long_name) == 0) break; + } + else /* Special case xxx=data */ + { + int oplen = (int)(equals - op->long_name); + int arglen = (argequals == NULL)? + (int)strlen(arg) : (int)(argequals - arg); + if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0) + { + option_data = arg + arglen; + if (*option_data == '=') + { + option_data++; + longopwasequals = TRUE; + } + break; + } + } + } + + /* Handle options with an alternate spelling of the name */ + + else + { + char buff1[24]; + char buff2[24]; + + int baselen = (int)(opbra - op->long_name); + int fulllen = (int)(strchr(op->long_name, ')') - op->long_name + 1); + int arglen = (argequals == NULL || equals == NULL)? + (int)strlen(arg) : (int)(argequals - arg); + + sprintf(buff1, "%.*s", baselen, op->long_name); + sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1); + + if (strncmp(arg, buff1, arglen) == 0 || + strncmp(arg, buff2, arglen) == 0) + { + if (equals != NULL && argequals != NULL) + { + option_data = argequals; + if (*option_data == '=') + { + option_data++; + longopwasequals = TRUE; + } + } + break; + } + } + } + + if (op->one_char == 0) + { + fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]); + pcregrep_exit(usage(2)); + } + } + + /* Jeffrey Friedl's debugging harness uses these additional options which + are not in the right form for putting in the option table because they use + only one hyphen, yet are more than one character long. By putting them + separately here, they will not get displayed as part of the help() output, + but I don't think Jeffrey will care about that. */ + +#ifdef JFRIEDL_DEBUG + else if (strcmp(argv[i], "-pre") == 0) { + jfriedl_prefix = argv[++i]; + continue; + } else if (strcmp(argv[i], "-post") == 0) { + jfriedl_postfix = argv[++i]; + continue; + } else if (strcmp(argv[i], "-XT") == 0) { + sscanf(argv[++i], "%d", &jfriedl_XT); + continue; + } else if (strcmp(argv[i], "-XR") == 0) { + sscanf(argv[++i], "%d", &jfriedl_XR); + continue; + } +#endif + + + /* One-char options; many that have no data may be in a single argument; we + continue till we hit the last one or one that needs data. */ + + else + { + char *s = argv[i] + 1; + longop = FALSE; + + while (*s != 0) + { + for (op = optionlist; op->one_char != 0; op++) + { + if (*s == op->one_char) break; + } + if (op->one_char == 0) + { + fprintf(stderr, "pcregrep: Unknown option letter '%c' in \"%s\"\n", + *s, argv[i]); + pcregrep_exit(usage(2)); + } + + option_data = s+1; + + /* Break out if this is the last character in the string; it's handled + below like a single multi-char option. */ + + if (*option_data == 0) break; + + /* Check for a single-character option that has data: OP_OP_NUMBER(S) + are used for ones that either have a numerical number or defaults, i.e. + the data is optional. If a digit follows, there is data; if not, carry on + with other single-character options in the same string. */ + + if (op->type == OP_OP_NUMBER || op->type == OP_OP_NUMBERS) + { + if (isdigit((unsigned char)s[1])) break; + } + else /* Check for an option with data */ + { + if (op->type != OP_NODATA) break; + } + + /* Handle a single-character option with no data, then loop for the + next character in the string. */ + + pcre_options = handle_option(*s++, pcre_options); + } + } + + /* At this point we should have op pointing to a matched option. If the type + is NO_DATA, it means that there is no data, and the option might set + something in the PCRE options. */ + + if (op->type == OP_NODATA) + { + pcre_options = handle_option(op->one_char, pcre_options); + continue; + } + + /* If the option type is OP_OP_STRING or OP_OP_NUMBER(S), it's an option that + either has a value or defaults to something. It cannot have data in a + separate item. At the moment, the only such options are "colo(u)r", + "only-matching", and Jeffrey Friedl's special -S debugging option. */ + + if (*option_data == 0 && + (op->type == OP_OP_STRING || op->type == OP_OP_NUMBER || + op->type == OP_OP_NUMBERS)) + { + switch (op->one_char) + { + case N_COLOUR: + colour_option = (char *)"auto"; + break; + + case 'o': + only_matching_last = add_number(0, only_matching_last); + if (only_matching == NULL) only_matching = only_matching_last; + break; + +#ifdef JFRIEDL_DEBUG + case 'S': + S_arg = 0; + break; +#endif + } + continue; + } + + /* Otherwise, find the data string for the option. */ + + if (*option_data == 0) + { + if (i >= argc - 1 || longopwasequals) + { + fprintf(stderr, "pcregrep: Data missing after %s\n", argv[i]); + pcregrep_exit(usage(2)); + } + option_data = argv[++i]; + } + + /* If the option type is OP_OP_NUMBERS, the value is a number that is to be + added to a chain of numbers. */ + + if (op->type == OP_OP_NUMBERS) + { + unsigned long int n = decode_number(option_data, op, longop); + omdatastr *omd = (omdatastr *)op->dataptr; + *(omd->lastptr) = add_number((int)n, *(omd->lastptr)); + if (*(omd->anchor) == NULL) *(omd->anchor) = *(omd->lastptr); + } + + /* If the option type is OP_PATLIST, it's the -e option, or one of the + include/exclude options, which can be called multiple times to create lists + of patterns. */ + + else if (op->type == OP_PATLIST) + { + patdatastr *pd = (patdatastr *)op->dataptr; + *(pd->lastptr) = add_pattern(option_data, *(pd->lastptr)); + if (*(pd->lastptr) == NULL) goto EXIT2; + if (*(pd->anchor) == NULL) *(pd->anchor) = *(pd->lastptr); + } + + /* If the option type is OP_FILELIST, it's one of the options that names a + file. */ + + else if (op->type == OP_FILELIST) + { + fndatastr *fd = (fndatastr *)op->dataptr; + fn = (fnstr *)malloc(sizeof(fnstr)); + if (fn == NULL) + { + fprintf(stderr, "pcregrep: malloc failed\n"); + goto EXIT2; + } + fn->next = NULL; + fn->name = option_data; + if (*(fd->anchor) == NULL) + *(fd->anchor) = fn; + else + (*(fd->lastptr))->next = fn; + *(fd->lastptr) = fn; + } + + /* 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 a single string or numeric data value. */ + + else if (op->type != OP_NUMBER && op->type != OP_LONGNUMBER && + op->type != OP_OP_NUMBER) + { + *((char **)op->dataptr) = option_data; + } + else + { + unsigned long int n = decode_number(option_data, op, longop); + if (op->type == OP_LONGNUMBER) *((unsigned long int *)op->dataptr) = n; + else *((int *)op->dataptr) = n; + } + } + +/* Options have been decoded. If -C was used, its value is used as a default +for -A and -B. */ + +if (both_context > 0) + { + if (after_context == 0) after_context = both_context; + if (before_context == 0) before_context = both_context; + } + +/* Only one of --only-matching, --file-offsets, or --line-offsets is permitted. +However, all three set show_only_matching because they display, each in their +own way, only the data that has matched. */ + +if ((only_matching != NULL && (file_offsets || line_offsets)) || + (file_offsets && line_offsets)) + { + fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets " + "and/or --line-offsets\n"); + pcregrep_exit(usage(2)); + } + +if (only_matching != NULL || file_offsets || line_offsets) + show_only_matching = TRUE; + +/* If a locale has not been provided as an option, see if the LC_CTYPE or +LC_ALL environment variable is set, and if so, use it. */ + +if (locale == NULL) + { + locale = getenv("LC_ALL"); + locale_from = "LCC_ALL"; + } + +if (locale == NULL) + { + locale = getenv("LC_CTYPE"); + locale_from = "LC_CTYPE"; + } + +/* If a locale has been provided, set it, and generate the tables the PCRE +needs. Otherwise, pcretables==NULL, which causes the use of default tables. */ + +if (locale != NULL) + { + if (setlocale(LC_CTYPE, locale) == NULL) + { + fprintf(stderr, "pcregrep: Failed to set locale %s (obtained from %s)\n", + locale, locale_from); + return 2; + } + pcretables = pcre_maketables(); + } + +/* Sort out colouring */ + +if (colour_option != NULL && strcmp(colour_option, "never") != 0) + { + if (strcmp(colour_option, "always") == 0) do_colour = TRUE; + else if (strcmp(colour_option, "auto") == 0) do_colour = is_stdout_tty(); + else + { + fprintf(stderr, "pcregrep: Unknown colour setting \"%s\"\n", + colour_option); + return 2; + } + if (do_colour) + { + char *cs = getenv("PCREGREP_COLOUR"); + if (cs == NULL) cs = getenv("PCREGREP_COLOR"); + if (cs != NULL) colour_string = cs; + } + } + +/* Interpret the newline type; the default settings are Unix-like. */ + +if (strcmp(newline, "cr") == 0 || strcmp(newline, "CR") == 0) + { + pcre_options |= PCRE_NEWLINE_CR; + endlinetype = EL_CR; + } +else if (strcmp(newline, "lf") == 0 || strcmp(newline, "LF") == 0) + { + pcre_options |= PCRE_NEWLINE_LF; + endlinetype = EL_LF; + } +else if (strcmp(newline, "crlf") == 0 || strcmp(newline, "CRLF") == 0) + { + pcre_options |= PCRE_NEWLINE_CRLF; + endlinetype = EL_CRLF; + } +else if (strcmp(newline, "any") == 0 || strcmp(newline, "ANY") == 0) + { + pcre_options |= PCRE_NEWLINE_ANY; + endlinetype = EL_ANY; + } +else if (strcmp(newline, "anycrlf") == 0 || strcmp(newline, "ANYCRLF") == 0) + { + pcre_options |= PCRE_NEWLINE_ANYCRLF; + endlinetype = EL_ANYCRLF; + } +else + { + fprintf(stderr, "pcregrep: Invalid newline specifier \"%s\"\n", newline); + return 2; + } + +/* Interpret the text values for -d and -D */ + +if (dee_option != NULL) + { + if (strcmp(dee_option, "read") == 0) dee_action = dee_READ; + else if (strcmp(dee_option, "recurse") == 0) dee_action = dee_RECURSE; + else if (strcmp(dee_option, "skip") == 0) dee_action = dee_SKIP; + else + { + fprintf(stderr, "pcregrep: Invalid value \"%s\" for -d\n", dee_option); + return 2; + } + } + +if (DEE_option != NULL) + { + if (strcmp(DEE_option, "read") == 0) DEE_action = DEE_READ; + else if (strcmp(DEE_option, "skip") == 0) DEE_action = DEE_SKIP; + else + { + fprintf(stderr, "pcregrep: Invalid value \"%s\" for -D\n", DEE_option); + return 2; + } + } + +/* Check the values for Jeffrey Friedl's debugging options. */ + +#ifdef JFRIEDL_DEBUG +if (S_arg > 9) + { + fprintf(stderr, "pcregrep: bad value for -S option\n"); + return 2; + } +if (jfriedl_XT != 0 || jfriedl_XR != 0) + { + if (jfriedl_XT == 0) jfriedl_XT = 1; + if (jfriedl_XR == 0) jfriedl_XR = 1; + } +#endif + +/* Get memory for the main buffer. */ + +bufsize = 3*bufthird; +main_buffer = (char *)malloc(bufsize); + +if (main_buffer == NULL) + { + fprintf(stderr, "pcregrep: malloc failed\n"); + goto EXIT2; + } + +/* If no patterns were provided by -e, and there are no files provided by -f, +the first argument is the one and only pattern, and it must exist. */ + +if (patterns == NULL && pattern_files == NULL) + { + if (i >= argc) return usage(2); + patterns = patterns_last = add_pattern(argv[i++], NULL); + if (patterns == NULL) goto EXIT2; + } + +/* Compile the patterns that were provided on the command line, either by +multiple uses of -e or as a single unkeyed pattern. We cannot do this until +after all the command-line options are read so that we know which PCRE options +to use. When -F is used, compile_pattern() may add another block into the +chain, so we must not access the next pointer till after the compile. */ + +for (j = 1, cp = patterns; cp != NULL; j++, cp = cp->next) + { + if (!compile_pattern(cp, pcre_options, process_options, FALSE, "command-line", + (j == 1 && patterns->next == NULL)? 0 : j)) + goto EXIT2; + } + +/* Read and compile the regular expressions that are provided in files. */ + +for (fn = pattern_files; fn != NULL; fn = fn->next) + { + if (!read_pattern_file(fn->name, &patterns, &patterns_last, process_options)) + goto EXIT2; + } + +/* Study the regular expressions, as we will be running them many times. If an +extra block is needed for a limit, set PCRE_STUDY_EXTRA_NEEDED so that one is +returned, even if studying produces no data. */ + +if (match_limit > 0 || match_limit_recursion > 0) + study_options |= PCRE_STUDY_EXTRA_NEEDED; + +/* 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 = 1, cp = patterns; cp != NULL; j++, cp = cp->next) + { + cp->hint = pcre_study(cp->compiled, study_options, &error); + if (error != NULL) + { + char s[16]; + if (patterns->next == NULL) s[0] = 0; else sprintf(s, " number %d", j); + fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error); + goto EXIT2; + } +#ifdef SUPPORT_PCREGREP_JIT + if (jit_stack != NULL && cp->hint != NULL) + pcre_assign_jit_stack(cp->hint, NULL, jit_stack); +#endif + } + +/* If --match-limit or --recursion-limit was set, put the value(s) into the +pcre_extra block for each pattern. There will always be an extra block because +of the use of PCRE_STUDY_EXTRA_NEEDED above. */ + +for (cp = patterns; cp != NULL; cp = cp->next) + { + if (match_limit > 0) + { + cp->hint->flags |= PCRE_EXTRA_MATCH_LIMIT; + cp->hint->match_limit = match_limit; + } + + if (match_limit_recursion > 0) + { + cp->hint->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; + cp->hint->match_limit_recursion = match_limit_recursion; + } + } + +/* If there are include or exclude patterns read from the command line, compile +them. -F, -w, and -x do not apply, so the third argument of compile_pattern is +0. */ + +for (j = 0; j < 4; j++) + { + int k; + for (k = 1, cp = *(incexlist[j]); cp != NULL; k++, cp = cp->next) + { + if (!compile_pattern(cp, pcre_options, 0, FALSE, incexname[j], + (k == 1 && cp->next == NULL)? 0 : k)) + goto EXIT2; + } + } + +/* Read and compile include/exclude patterns from files. */ + +for (fn = include_from; fn != NULL; fn = fn->next) + { + if (!read_pattern_file(fn->name, &include_patterns, &include_patterns_last, 0)) + goto EXIT2; + } + +for (fn = exclude_from; fn != NULL; fn = fn->next) + { + if (!read_pattern_file(fn->name, &exclude_patterns, &exclude_patterns_last, 0)) + goto EXIT2; + } + +/* If there are no files that contain lists of files to search, and there are +no file arguments, search stdin, and then exit. */ + +if (file_lists == NULL && i >= argc) + { + rc = pcregrep(stdin, FR_PLAIN, stdin_name, + (filenames > FN_DEFAULT)? stdin_name : NULL); + goto EXIT; + } + +/* If any files that contains a list of files to search have been specified, +read them line by line and search the given files. */ + +for (fn = file_lists; fn != NULL; fn = fn->next) + { + char buffer[PATBUFSIZE]; + FILE *fl; + if (strcmp(fn->name, "-") == 0) fl = stdin; else + { + fl = fopen(fn->name, "rb"); + if (fl == NULL) + { + fprintf(stderr, "pcregrep: Failed to open %s: %s\n", fn->name, + 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); + } + +/* After handling file-list, work through remaining arguments. 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 && file_lists == NULL; + +for (; i < argc; i++) + { + int frc = grep_or_recurse(argv[i], dee_action == dee_RECURSE, + only_one_at_top); + if (frc > 1) rc = frc; + else if (frc == 0 && rc == 1) rc = 0; + } + +EXIT: +#ifdef SUPPORT_PCREGREP_JIT +if (jit_stack != NULL) pcre_jit_stack_free(jit_stack); +#endif + +if (main_buffer != NULL) free(main_buffer); + +free_pattern_chain(patterns); +free_pattern_chain(include_patterns); +free_pattern_chain(include_dir_patterns); +free_pattern_chain(exclude_patterns); +free_pattern_chain(exclude_dir_patterns); + +free_file_chain(exclude_from); +free_file_chain(include_from); +free_file_chain(pattern_files); +free_file_chain(file_lists); + +while (only_matching != NULL) + { + omstr *this = only_matching; + only_matching = this->next; + free(this); + } + +pcregrep_exit(rc); + +EXIT2: +rc = 2; +goto EXIT; +} + +/* End of pcregrep */ diff --git a/tools/pcre/pcreposix.c b/tools/pcre/pcreposix.c new file mode 100644 index 00000000..15195c0e --- /dev/null +++ b/tools/pcre/pcreposix.c @@ -0,0 +1,419 @@ +/************************************************* +* 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 is a wrapper that provides a POSIX API to the underlying PCRE +functions. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +/* Ensure that the PCREPOSIX_EXP_xxx macros are set appropriately for +compiling these functions. This must come before including pcreposix.h, where +they are set for an application (using these functions) if they have not +previously been set. */ + +#if defined(_WIN32) && !defined(PCRE_STATIC) +# define PCREPOSIX_EXP_DECL extern __declspec(dllexport) +# define PCREPOSIX_EXP_DEFN __declspec(dllexport) +#endif + +/* We include pcre.h before pcre_internal.h so that the PCRE library functions +are declared as "import" for Windows by defining PCRE_EXP_DECL as "import". +This is needed even though pcre_internal.h itself includes pcre.h, because it +does so after it has set PCRE_EXP_DECL to "export" if it is not already set. */ + +#include "pcre.h" +#include "pcre_internal.h" +#include "pcreposix.h" + + +/* Table to translate PCRE compile time error codes into POSIX error codes. */ + +static const int eint[] = { + 0, /* no error */ + REG_EESCAPE, /* \ at end of pattern */ + REG_EESCAPE, /* \c at end of pattern */ + REG_EESCAPE, /* unrecognized character follows \ */ + REG_BADBR, /* numbers out of order in {} quantifier */ + /* 5 */ + REG_BADBR, /* number too big in {} quantifier */ + REG_EBRACK, /* missing terminating ] for character class */ + REG_ECTYPE, /* invalid escape sequence in character class */ + REG_ERANGE, /* range out of order in character class */ + REG_BADRPT, /* nothing to repeat */ + /* 10 */ + REG_BADRPT, /* operand of unlimited repeat could match the empty string */ + REG_ASSERT, /* internal error: unexpected repeat */ + REG_BADPAT, /* unrecognized character after (? */ + REG_BADPAT, /* POSIX named classes are supported only within a class */ + REG_EPAREN, /* missing ) */ + /* 15 */ + REG_ESUBREG, /* reference to non-existent subpattern */ + REG_INVARG, /* erroffset passed as NULL */ + REG_INVARG, /* unknown option bit(s) set */ + REG_EPAREN, /* missing ) after comment */ + REG_ESIZE, /* parentheses nested too deeply */ + /* 20 */ + REG_ESIZE, /* regular expression too large */ + REG_ESPACE, /* failed to get memory */ + REG_EPAREN, /* unmatched parentheses */ + REG_ASSERT, /* internal error: code overflow */ + REG_BADPAT, /* unrecognized character after (?< */ + /* 25 */ + REG_BADPAT, /* lookbehind assertion is not fixed length */ + REG_BADPAT, /* malformed number or name after (?( */ + REG_BADPAT, /* conditional group contains more than two branches */ + REG_BADPAT, /* assertion expected after (?( */ + REG_BADPAT, /* (?R or (?[+-]digits must be followed by ) */ + /* 30 */ + REG_ECTYPE, /* unknown POSIX class name */ + REG_BADPAT, /* POSIX collating elements are not supported */ + REG_INVARG, /* this version of PCRE is not compiled with PCRE_UTF8 support */ + REG_BADPAT, /* spare error */ + REG_BADPAT, /* character value in \x{...} sequence is too large */ + /* 35 */ + REG_BADPAT, /* invalid condition (?(0) */ + REG_BADPAT, /* \C not allowed in lookbehind assertion */ + REG_EESCAPE, /* PCRE does not support \L, \l, \N, \U, or \u */ + REG_BADPAT, /* number after (?C is > 255 */ + REG_BADPAT, /* closing ) for (?C expected */ + /* 40 */ + REG_BADPAT, /* recursive call could loop indefinitely */ + REG_BADPAT, /* unrecognized character after (?P */ + REG_BADPAT, /* syntax error in subpattern name (missing terminator) */ + REG_BADPAT, /* two named subpatterns have the same name */ + REG_BADPAT, /* invalid UTF-8 string */ + /* 45 */ + REG_BADPAT, /* support for \P, \p, and \X has not been compiled */ + REG_BADPAT, /* malformed \P or \p sequence */ + REG_BADPAT, /* unknown property name after \P or \p */ + REG_BADPAT, /* subpattern name is too long (maximum 32 characters) */ + REG_BADPAT, /* too many named subpatterns (maximum 10,000) */ + /* 50 */ + REG_BADPAT, /* repeated subpattern is too long */ + REG_BADPAT, /* octal value is greater than \377 (not in UTF-8 mode) */ + REG_BADPAT, /* internal error: overran compiling workspace */ + REG_BADPAT, /* internal error: previously-checked referenced subpattern not found */ + REG_BADPAT, /* DEFINE group contains more than one branch */ + /* 55 */ + REG_BADPAT, /* repeating a DEFINE group is not allowed */ + REG_INVARG, /* inconsistent NEWLINE options */ + REG_BADPAT, /* \g is not followed followed by an (optionally braced) non-zero number */ + REG_BADPAT, /* a numbered reference must not be zero */ + REG_BADPAT, /* an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) */ + /* 60 */ + REG_BADPAT, /* (*VERB) not recognized */ + REG_BADPAT, /* number is too big */ + REG_BADPAT, /* subpattern name expected */ + REG_BADPAT, /* digit expected after (?+ */ + REG_BADPAT, /* ] is an invalid data character in JavaScript compatibility mode */ + /* 65 */ + REG_BADPAT, /* different names for subpatterns of the same number are not allowed */ + 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/32 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 */ + REG_BADPAT /* invalid UTF-32 string (should not occur) */ +}; + +/* Table of texts corresponding to POSIX error codes */ + +static const char *const pstring[] = { + "", /* Dummy for value 0 */ + "internal error", /* REG_ASSERT */ + "invalid repeat counts in {}", /* BADBR */ + "pattern error", /* BADPAT */ + "? * + invalid", /* BADRPT */ + "unbalanced {}", /* EBRACE */ + "unbalanced []", /* EBRACK */ + "collation error - not relevant", /* ECOLLATE */ + "bad class", /* ECTYPE */ + "bad escape sequence", /* EESCAPE */ + "empty expression", /* EMPTY */ + "unbalanced ()", /* EPAREN */ + "bad range inside []", /* ERANGE */ + "expression too big", /* ESIZE */ + "failed to get memory", /* ESPACE */ + "bad back reference", /* ESUBREG */ + "bad argument", /* INVARG */ + "match failed" /* NOMATCH */ +}; + + + + +/************************************************* +* Translate error code to string * +*************************************************/ + +PCREPOSIX_EXP_DEFN size_t PCRE_CALL_CONVENTION +regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) +{ +const char *message, *addmessage; +size_t length, addlength; + +message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))? + "unknown error code" : pstring[errcode]; +length = strlen(message) + 1; + +addmessage = " at offset "; +addlength = (preg != NULL && (int)preg->re_erroffset != -1)? + strlen(addmessage) + 6 : 0; + +if (errbuf_size > 0) + { + if (addlength > 0 && errbuf_size >= length + addlength) + sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset); + else + { + strncpy(errbuf, message, errbuf_size - 1); + errbuf[errbuf_size-1] = 0; + } + } + +return length + addlength; +} + + + + +/************************************************* +* Free store held by a regex * +*************************************************/ + +PCREPOSIX_EXP_DEFN void PCRE_CALL_CONVENTION +regfree(regex_t *preg) +{ +(PUBL(free))(preg->re_pcre); +} + + + + +/************************************************* +* Compile a regular expression * +*************************************************/ + +/* +Arguments: + preg points to a structure for recording the compiled expression + pattern the pattern to compile + cflags compilation flags + +Returns: 0 on success + various non-zero codes on failure +*/ + +PCREPOSIX_EXP_DEFN int PCRE_CALL_CONVENTION +regcomp(regex_t *preg, const char *pattern, int cflags) +{ +const char *errorptr; +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; +if ((cflags & REG_DOTALL) != 0) options |= PCRE_DOTALL; +if ((cflags & REG_NOSUB) != 0) options |= PCRE_NO_AUTO_CAPTURE; +if ((cflags & REG_UTF8) != 0) options |= PCRE_UTF8; +if ((cflags & REG_UCP) != 0) options |= PCRE_UCP; +if ((cflags & REG_UNGREEDY) != 0) options |= PCRE_UNGREEDY; + +preg->re_pcre = pcre_compile2(pattern, options, &errorcode, &errorptr, + &erroffset, NULL); +preg->re_erroffset = erroffset; + +/* Safety: if the error code is too big for the translation vector (which +should not happen, but we all make mistakes), return REG_BADPAT. */ + +if (preg->re_pcre == NULL) + { + return (errorcode < (int)(sizeof(eint)/sizeof(const int)))? + eint[errorcode] : REG_BADPAT; + } + +(void)pcre_fullinfo((const pcre *)preg->re_pcre, NULL, PCRE_INFO_CAPTURECOUNT, + &re_nsub); +preg->re_nsub = (size_t)re_nsub; +return 0; +} + + + + +/************************************************* +* Match a regular expression * +*************************************************/ + +/* Unfortunately, PCRE requires 3 ints of working space for each captured +substring, so we have to get and release working store instead of just using +the POSIX structures as was done in earlier releases when PCRE needed only 2 +ints. However, if the number of possible capturing brackets is small, use a +block of store on the stack, to reduce the use of malloc/free. The threshold is +in a macro that can be changed at configure time. + +If REG_NOSUB was specified at compile time, the PCRE_NO_AUTO_CAPTURE flag will +be set. When this is the case, the nmatch and pmatch arguments are ignored, and +the only result is yes/no/error. */ + +PCREPOSIX_EXP_DEFN int PCRE_CALL_CONVENTION +regexec(const regex_t *preg, const char *string, size_t nmatch, + regmatch_t pmatch[], int eflags) +{ +int rc, so, eo; +int options = 0; +int *ovector = NULL; +int small_ovector[POSIX_MALLOC_THRESHOLD * 3]; +BOOL allocated_ovector = FALSE; +BOOL nosub = + (REAL_PCRE_OPTIONS((const pcre *)preg->re_pcre) & PCRE_NO_AUTO_CAPTURE) != 0; + +if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL; +if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL; +if ((eflags & REG_NOTEMPTY) != 0) options |= PCRE_NOTEMPTY; + +((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */ + +/* When no string data is being returned, or no vector has been passed in which +to put it, ensure that nmatch is zero. Otherwise, ensure the vector for holding +the return data is large enough. */ + +if (nosub || pmatch == NULL) nmatch = 0; + +else if (nmatch > 0) + { + if (nmatch <= POSIX_MALLOC_THRESHOLD) + { + ovector = &(small_ovector[0]); + } + else + { + if (nmatch > INT_MAX/(sizeof(int) * 3)) return REG_ESPACE; + ovector = (int *)malloc(sizeof(int) * nmatch * 3); + if (ovector == NULL) return REG_ESPACE; + allocated_ovector = TRUE; + } + } + +/* REG_STARTEND is a BSD extension, to allow for non-NUL-terminated strings. +The man page from OS X says "REG_STARTEND affects only the location of the +string, not how it is matched". That is why the "so" value is used to bump the +start location rather than being passed as a PCRE "starting offset". */ + +if ((eflags & REG_STARTEND) != 0) + { + so = pmatch[0].rm_so; + eo = pmatch[0].rm_eo; + } +else + { + so = 0; + eo = (int)strlen(string); + } + +rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string + so, (eo - so), + 0, options, ovector, (int)(nmatch * 3)); + +if (rc == 0) rc = (int)nmatch; /* All captured slots were filled in */ + +/* Successful match */ + +if (rc >= 0) + { + size_t i; + if (!nosub) + { + for (i = 0; i < (size_t)rc; i++) + { + pmatch[i].rm_so = ovector[i*2]; + pmatch[i].rm_eo = ovector[i*2+1]; + } + if (allocated_ovector) free(ovector); + for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; + } + return 0; + } + +/* Unsuccessful match */ + +if (allocated_ovector) free(ovector); +switch(rc) + { +/* ========================================================================== */ + /* These cases are never obeyed. This is a fudge that causes a compile-time + error if the vector eint, which is indexed by compile-time error number, is + 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. + As all the PCRE_ERROR_xxx values are negative, we can use 0 and 1. */ + + case 0: + case (sizeof(eint)/sizeof(int) == ERRCOUNT): + return REG_ASSERT; +/* ========================================================================== */ + + case PCRE_ERROR_NOMATCH: return REG_NOMATCH; + case PCRE_ERROR_NULL: return REG_INVARG; + case PCRE_ERROR_BADOPTION: return REG_INVARG; + case PCRE_ERROR_BADMAGIC: return REG_INVARG; + case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT; + case PCRE_ERROR_NOMEMORY: return REG_ESPACE; + 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; + } +} + +/* End of pcreposix.c */ diff --git a/tools/pcre/pcreposix.h b/tools/pcre/pcreposix.h new file mode 100644 index 00000000..c77c0b05 --- /dev/null +++ b/tools/pcre/pcreposix.h @@ -0,0 +1,146 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +#ifndef _PCREPOSIX_H +#define _PCREPOSIX_H + +/* This is the header for the POSIX wrapper interface to the PCRE Perl- +Compatible Regular Expression library. It defines the things POSIX says should +be there. I hope. + + 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. +----------------------------------------------------------------------------- +*/ + +/* Have to include stdlib.h in order to ensure that size_t is defined. */ + +#include + +/* Allow for C++ users */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Options, mostly defined by POSIX, but with some extras. */ + +#define REG_ICASE 0x0001 /* Maps to PCRE_CASELESS */ +#define REG_NEWLINE 0x0002 /* Maps to PCRE_MULTILINE */ +#define REG_NOTBOL 0x0004 /* Maps to PCRE_NOTBOL */ +#define REG_NOTEOL 0x0008 /* Maps to PCRE_NOTEOL */ +#define REG_DOTALL 0x0010 /* NOT defined by POSIX; maps to PCRE_DOTALL */ +#define REG_NOSUB 0x0020 /* Maps to PCRE_NO_AUTO_CAPTURE */ +#define REG_UTF8 0x0040 /* NOT defined by POSIX; maps to PCRE_UTF8 */ +#define REG_STARTEND 0x0080 /* BSD feature: pass subject string by so,eo */ +#define REG_NOTEMPTY 0x0100 /* NOT defined by POSIX; maps to PCRE_NOTEMPTY */ +#define REG_UNGREEDY 0x0200 /* NOT defined by POSIX; maps to PCRE_UNGREEDY */ +#define REG_UCP 0x0400 /* NOT defined by POSIX; maps to PCRE_UCP */ + +/* This is not used by PCRE, but by defining it we make it easier +to slot PCRE into existing programs that make POSIX calls. */ + +#define REG_EXTENDED 0 + +/* Error values. Not all these are relevant or used by the wrapper. */ + +enum { + REG_ASSERT = 1, /* internal error ? */ + REG_BADBR, /* invalid repeat counts in {} */ + REG_BADPAT, /* pattern error */ + REG_BADRPT, /* ? * + invalid */ + REG_EBRACE, /* unbalanced {} */ + REG_EBRACK, /* unbalanced [] */ + REG_ECOLLATE, /* collation error - not relevant */ + REG_ECTYPE, /* bad class */ + REG_EESCAPE, /* bad escape sequence */ + REG_EMPTY, /* empty expression */ + REG_EPAREN, /* unbalanced () */ + REG_ERANGE, /* bad range inside [] */ + REG_ESIZE, /* expression too big */ + REG_ESPACE, /* failed to get memory */ + REG_ESUBREG, /* bad back reference */ + REG_INVARG, /* bad argument */ + REG_NOMATCH /* match failed */ +}; + + +/* The structure representing a compiled regular expression. */ + +typedef struct { + void *re_pcre; + size_t re_nsub; + size_t re_erroffset; +} regex_t; + +/* The structure in which a captured offset is returned. */ + +typedef int regoff_t; + +typedef struct { + regoff_t rm_so; + regoff_t rm_eo; +} regmatch_t; + +/* 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 +export settings are needed, and are set in pcreposix.c before including this +file. */ + +#if defined(_WIN32) && !defined(PCRE_STATIC) && !defined(PCREPOSIX_EXP_DECL) +# define PCREPOSIX_EXP_DECL extern __declspec(dllimport) +# define PCREPOSIX_EXP_DEFN __declspec(dllimport) +#endif + +/* By default, we use the standard "extern" declarations. */ + +#ifndef PCREPOSIX_EXP_DECL +# ifdef __cplusplus +# define PCREPOSIX_EXP_DECL extern "C" +# define PCREPOSIX_EXP_DEFN extern "C" +# else +# define PCREPOSIX_EXP_DECL extern +# define PCREPOSIX_EXP_DEFN extern +# endif +#endif + +/* The functions */ + +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 regerror(int, const regex_t *, char *, size_t); +PCREPOSIX_EXP_DECL void regfree(regex_t *); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* End of pcreposix.h */ diff --git a/tools/pcre/pcretest.c b/tools/pcre/pcretest.c new file mode 100644 index 00000000..0b6c821a --- /dev/null +++ b/tools/pcre/pcretest.c @@ -0,0 +1,5488 @@ +/************************************************* +* PCRE testing program * +*************************************************/ + +/* 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. The +addition of 16-bit support has made it even worse. :-( + +----------------------------------------------------------------------------- +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 program now supports the testing of all of the 8-bit, 16-bit, and +32-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 two modes are enabled, for example, pcre_compile.c is compiled +twice. 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, COMPILE_PCRE16, or COMPILE_PCRE32. It does, however, make use of +SUPPORT_PCRE8, SUPPORT_PCRE16, and SUPPORT_PCRE32 to ensure that it calls only +supported library functions. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +/* 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 +environments, so it was added for release 5.0 to both the input and output. (It +makes no difference on Unix-like systems.) Later I was told that it is wrong +for the input on Windows. I've now abstracted the modes into two macros that +are set here, to make it easier to fiddle with them, and removed "b" from the +input mode under Windows. */ + +#if defined(_WIN32) || defined(WIN32) +#include /* For _setmode() */ +#include /* For _O_BINARY */ +#define INPUT_MODE "r" +#define OUTPUT_MODE "wb" + +#ifndef isatty +#define isatty _isatty /* This is what Windows calls them, I'm told, */ +#endif /* though in some environments they seem to */ + /* be already defined, hence the #ifndefs. */ +#ifndef fileno +#define fileno _fileno +#endif + +/* A user sent this fix for Borland Builder 5 under Windows. */ + +#ifdef __BORLANDC__ +#define _setmode(handle, mode) setmode(handle, mode) +#endif + +/* Not Windows */ + +#else +#include /* These two includes are needed */ +#include /* for setrlimit(). */ +#if defined NATIVE_ZOS /* z/OS uses non-binary I/O */ +#define INPUT_MODE "r" +#define OUTPUT_MODE "w" +#else +#define INPUT_MODE "rb" +#define OUTPUT_MODE "wb" +#endif +#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 +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" + +/* 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-, 16- or 32-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 +#ifdef SUPPORT_PCRE32 +void pcre32_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 files here, changing the names of the +external symbols to prevent clashes. */ + +#define PCRE_INCLUDED + +#include "pcre_tables.c" +#include "pcre_ucd.c" + +/* 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 +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. */ + +#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 or 32 bit only mode. */ +#if !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 +Makefile. */ + +#if !defined NOPOSIX +#include "pcreposix.h" +#endif + +/* 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/16/32-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, cn32, 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) + +#define pcre8_maketables pcre_maketables + +#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, cn32, 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 */ + +/* -----------------------------------------------------------*/ + +#ifdef SUPPORT_PCRE32 + +#define PCHARS32(lv, p, offset, len, f) \ + lv = pchars32((PCRE_SPTR32)(p) + offset, len, use_utf, f) + +#define PCHARSV32(p, offset, len, f) \ + (void)pchars32((PCRE_SPTR32)(p) + offset, len, use_utf, f) + +#define READ_CAPTURE_NAME32(p, cn8, cn16, cn32, re) \ + p = read_capture_name32(p, cn32, re) + +#define STRLEN32(p) ((int)strlen32((PCRE_SPTR32)p)) + +#define SET_PCRE_CALLOUT32(callout) \ + pcre32_callout = (int (*)(pcre32_callout_block *))callout + +#define PCRE_ASSIGN_JIT_STACK32(extra, callback, userdata) \ + pcre32_assign_jit_stack((pcre32_extra *)extra, \ + (pcre32_jit_callback)callback, userdata) + +#define PCRE_COMPILE32(re, pat, options, error, erroffset, tables) \ + re = (pcre *)pcre32_compile((PCRE_SPTR32)pat, options, error, erroffset, \ + tables) + +#define PCRE_COPY_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \ + namesptr, cbuffer, size) \ + rc = pcre32_copy_named_substring((pcre32 *)re, (PCRE_SPTR32)bptr, offsets, \ + count, (PCRE_SPTR32)namesptr, (PCRE_UCHAR32 *)cbuffer, size/2) + +#define PCRE_COPY_SUBSTRING32(rc, bptr, offsets, count, i, cbuffer, size) \ + rc = pcre32_copy_substring((PCRE_SPTR32)bptr, offsets, count, i, \ + (PCRE_UCHAR32 *)cbuffer, size/2) + +#define PCRE_DFA_EXEC32(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets, workspace, size_workspace) \ + count = pcre32_dfa_exec((pcre32 *)re, (pcre32_extra *)extra, \ + (PCRE_SPTR32)bptr, len, start_offset, options, offsets, size_offsets, \ + workspace, size_workspace) + +#define PCRE_EXEC32(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets) \ + count = pcre32_exec((pcre32 *)re, (pcre32_extra *)extra, (PCRE_SPTR32)bptr, \ + len, start_offset, options, offsets, size_offsets) + +#define PCRE_FREE_STUDY32(extra) \ + pcre32_free_study((pcre32_extra *)extra) + +#define PCRE_FREE_SUBSTRING32(substring) \ + pcre32_free_substring((PCRE_SPTR32)substring) + +#define PCRE_FREE_SUBSTRING_LIST32(listptr) \ + pcre32_free_substring_list((PCRE_SPTR32 *)listptr) + +#define PCRE_GET_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr) \ + rc = pcre32_get_named_substring((pcre32 *)re, (PCRE_SPTR32)bptr, offsets, \ + count, (PCRE_SPTR32)getnamesptr, (PCRE_SPTR32 *)(void*)subsptr) + +#define PCRE_GET_STRINGNUMBER32(n, rc, ptr) \ + n = pcre32_get_stringnumber(re, (PCRE_SPTR32)ptr) + +#define PCRE_GET_SUBSTRING32(rc, bptr, offsets, count, i, subsptr) \ + rc = pcre32_get_substring((PCRE_SPTR32)bptr, offsets, count, i, \ + (PCRE_SPTR32 *)(void*)subsptr) + +#define PCRE_GET_SUBSTRING_LIST32(rc, bptr, offsets, count, listptr) \ + rc = pcre32_get_substring_list((PCRE_SPTR32)bptr, offsets, count, \ + (PCRE_SPTR32 **)(void*)listptr) + +#define PCRE_PATTERN_TO_HOST_BYTE_ORDER32(rc, re, extra, tables) \ + rc = pcre32_pattern_to_host_byte_order((pcre32 *)re, (pcre32_extra *)extra, \ + tables) + +#define PCRE_PRINTINT32(re, outfile, debug_lengths) \ + pcre32_printint(re, outfile, debug_lengths) + +#define PCRE_STUDY32(extra, re, options, error) \ + extra = (pcre_extra *)pcre32_study((pcre32 *)re, options, error) + +#define PCRE_JIT_STACK_ALLOC32(startsize, maxsize) \ + (pcre_jit_stack *)pcre32_jit_stack_alloc(startsize, maxsize) + +#define PCRE_JIT_STACK_FREE32(stack) \ + pcre32_jit_stack_free((pcre32_jit_stack *)stack) + +#endif /* SUPPORT_PCRE32 */ + + +/* ----- More than one mode is supported; a runtime test is needed, except for +pcre_config(), and the JIT stack functions, when it doesn't matter which +available version is called. ----- */ + +enum { + PCRE8_MODE, + PCRE16_MODE, + PCRE32_MODE +}; + +#if (defined (SUPPORT_PCRE8) + defined (SUPPORT_PCRE16) + \ + defined (SUPPORT_PCRE32)) >= 2 + +#define CHAR_SIZE (1 << pcre_mode) + +/* There doesn't seem to be an easy way of writing these macros that can cope +with the 3 pairs of bit sizes plus all three bit sizes. So just handle all the +cases separately. */ + +/* ----- All three modes supported ----- */ + +#if defined(SUPPORT_PCRE8) && defined(SUPPORT_PCRE16) && defined(SUPPORT_PCRE32) + +#define PCHARS(lv, p, offset, len, f) \ + if (pcre_mode == PCRE32_MODE) \ + PCHARS32(lv, p, offset, len, f); \ + else if (pcre_mode == PCRE16_MODE) \ + PCHARS16(lv, p, offset, len, f); \ + else \ + PCHARS8(lv, p, offset, len, f) + +#define PCHARSV(p, offset, len, f) \ + if (pcre_mode == PCRE32_MODE) \ + PCHARSV32(p, offset, len, f); \ + else if (pcre_mode == PCRE16_MODE) \ + PCHARSV16(p, offset, len, f); \ + else \ + PCHARSV8(p, offset, len, f) + +#define READ_CAPTURE_NAME(p, cn8, cn16, cn32, re) \ + if (pcre_mode == PCRE32_MODE) \ + READ_CAPTURE_NAME32(p, cn8, cn16, cn32, re); \ + else if (pcre_mode == PCRE16_MODE) \ + READ_CAPTURE_NAME16(p, cn8, cn16, cn32, re); \ + else \ + READ_CAPTURE_NAME8(p, cn8, cn16, cn32, re) + +#define SET_PCRE_CALLOUT(callout) \ + if (pcre_mode == PCRE32_MODE) \ + SET_PCRE_CALLOUT32(callout); \ + else if (pcre_mode == PCRE16_MODE) \ + SET_PCRE_CALLOUT16(callout); \ + else \ + SET_PCRE_CALLOUT8(callout) + +#define STRLEN(p) (pcre_mode == PCRE32_MODE ? STRLEN32(p) : pcre_mode == PCRE16_MODE ? STRLEN16(p) : STRLEN8(p)) + +#define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \ + if (pcre_mode == PCRE32_MODE) \ + PCRE_ASSIGN_JIT_STACK32(extra, callback, userdata); \ + else if (pcre_mode == PCRE16_MODE) \ + 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 (pcre_mode == PCRE32_MODE) \ + PCRE_COMPILE32(re, pat, options, error, erroffset, tables); \ + else if (pcre_mode == PCRE16_MODE) \ + 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 (pcre_mode == PCRE32_MODE) \ + PCRE_COPY_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \ + namesptr, cbuffer, size); \ + else if (pcre_mode == PCRE16_MODE) \ + 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 (pcre_mode == PCRE32_MODE) \ + PCRE_COPY_SUBSTRING32(rc, bptr, offsets, count, i, cbuffer, size); \ + else if (pcre_mode == PCRE16_MODE) \ + 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 (pcre_mode == PCRE32_MODE) \ + PCRE_DFA_EXEC32(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets, workspace, size_workspace); \ + else if (pcre_mode == PCRE16_MODE) \ + 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 (pcre_mode == PCRE32_MODE) \ + PCRE_EXEC32(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets); \ + else if (pcre_mode == PCRE16_MODE) \ + 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 (pcre_mode == PCRE32_MODE) \ + PCRE_FREE_STUDY32(extra); \ + else if (pcre_mode == PCRE16_MODE) \ + PCRE_FREE_STUDY16(extra); \ + else \ + PCRE_FREE_STUDY8(extra) + +#define PCRE_FREE_SUBSTRING(substring) \ + if (pcre_mode == PCRE32_MODE) \ + PCRE_FREE_SUBSTRING32(substring); \ + else if (pcre_mode == PCRE16_MODE) \ + PCRE_FREE_SUBSTRING16(substring); \ + else \ + PCRE_FREE_SUBSTRING8(substring) + +#define PCRE_FREE_SUBSTRING_LIST(listptr) \ + if (pcre_mode == PCRE32_MODE) \ + PCRE_FREE_SUBSTRING_LIST32(listptr); \ + else if (pcre_mode == PCRE16_MODE) \ + PCRE_FREE_SUBSTRING_LIST16(listptr); \ + else \ + PCRE_FREE_SUBSTRING_LIST8(listptr) + +#define PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr) \ + if (pcre_mode == PCRE32_MODE) \ + PCRE_GET_NAMED_SUBSTRING32(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr); \ + else if (pcre_mode == PCRE16_MODE) \ + 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 (pcre_mode == PCRE32_MODE) \ + PCRE_GET_STRINGNUMBER32(n, rc, ptr); \ + else if (pcre_mode == PCRE16_MODE) \ + 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 (pcre_mode == PCRE32_MODE) \ + PCRE_GET_SUBSTRING32(rc, bptr, use_offsets, count, i, subsptr); \ + else if (pcre_mode == PCRE16_MODE) \ + 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 (pcre_mode == PCRE32_MODE) \ + PCRE_GET_SUBSTRING_LIST32(rc, bptr, offsets, count, listptr); \ + else if (pcre_mode == PCRE16_MODE) \ + 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) \ + (pcre_mode == PCRE32_MODE ? \ + PCRE_JIT_STACK_ALLOC32(startsize, maxsize) \ + : pcre_mode == PCRE16_MODE ? \ + PCRE_JIT_STACK_ALLOC16(startsize, maxsize) \ + : PCRE_JIT_STACK_ALLOC8(startsize, maxsize)) + +#define PCRE_JIT_STACK_FREE(stack) \ + if (pcre_mode == PCRE32_MODE) \ + PCRE_JIT_STACK_FREE32(stack); \ + else if (pcre_mode == PCRE16_MODE) \ + PCRE_JIT_STACK_FREE16(stack); \ + else \ + PCRE_JIT_STACK_FREE8(stack) + +#define PCRE_MAKETABLES \ + (pcre_mode == PCRE32_MODE ? pcre32_maketables() : pcre_mode == PCRE16_MODE ? pcre16_maketables() : pcre_maketables()) + +#define PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, tables) \ + if (pcre_mode == PCRE32_MODE) \ + PCRE_PATTERN_TO_HOST_BYTE_ORDER32(rc, re, extra, tables); \ + else if (pcre_mode == PCRE16_MODE) \ + 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 (pcre_mode == PCRE32_MODE) \ + PCRE_PRINTINT32(re, outfile, debug_lengths); \ + else if (pcre_mode == PCRE16_MODE) \ + PCRE_PRINTINT16(re, outfile, debug_lengths); \ + else \ + PCRE_PRINTINT8(re, outfile, debug_lengths) + +#define PCRE_STUDY(extra, re, options, error) \ + if (pcre_mode == PCRE32_MODE) \ + PCRE_STUDY32(extra, re, options, error); \ + else if (pcre_mode == PCRE16_MODE) \ + PCRE_STUDY16(extra, re, options, error); \ + else \ + PCRE_STUDY8(extra, re, options, error) + + +/* ----- Two out of three modes are supported ----- */ + +#else + +/* We can use some macro trickery to make a single set of definitions work in +the three different cases. */ + +/* ----- 32-bit and 16-bit but not 8-bit supported ----- */ + +#if defined(SUPPORT_PCRE32) && defined(SUPPORT_PCRE16) +#define BITONE 32 +#define BITTWO 16 + +/* ----- 32-bit and 8-bit but not 16-bit supported ----- */ + +#elif defined(SUPPORT_PCRE32) && defined(SUPPORT_PCRE8) +#define BITONE 32 +#define BITTWO 8 + +/* ----- 16-bit and 8-bit but not 32-bit supported ----- */ + +#else +#define BITONE 16 +#define BITTWO 8 +#endif + +#define glue(a,b) a##b +#define G(a,b) glue(a,b) + + +/* ----- Common macros for two-mode cases ----- */ + +#define PCHARS(lv, p, offset, len, f) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCHARS,BITONE)(lv, p, offset, len, f); \ + else \ + G(PCHARS,BITTWO)(lv, p, offset, len, f) + +#define PCHARSV(p, offset, len, f) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCHARSV,BITONE)(p, offset, len, f); \ + else \ + G(PCHARSV,BITTWO)(p, offset, len, f) + +#define READ_CAPTURE_NAME(p, cn8, cn16, cn32, re) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(READ_CAPTURE_NAME,BITONE)(p, cn8, cn16, cn32, re); \ + else \ + G(READ_CAPTURE_NAME,BITTWO)(p, cn8, cn16, cn32, re) + +#define SET_PCRE_CALLOUT(callout) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(SET_PCRE_CALLOUT,BITONE)(callout); \ + else \ + G(SET_PCRE_CALLOUT,BITTWO)(callout) + +#define STRLEN(p) ((pcre_mode == G(G(PCRE,BITONE),_MODE)) ? \ + G(STRLEN,BITONE)(p) : G(STRLEN,BITTWO)(p)) + +#define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_ASSIGN_JIT_STACK,BITONE)(extra, callback, userdata); \ + else \ + G(PCRE_ASSIGN_JIT_STACK,BITTWO)(extra, callback, userdata) + +#define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_COMPILE,BITONE)(re, pat, options, error, erroffset, tables); \ + else \ + G(PCRE_COMPILE,BITTWO)(re, pat, options, error, erroffset, tables) + +#define PCRE_CONFIG G(G(pcre,BITONE),_config) + +#define PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \ + namesptr, cbuffer, size) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_COPY_NAMED_SUBSTRING,BITONE)(rc, re, bptr, offsets, count, \ + namesptr, cbuffer, size); \ + else \ + G(PCRE_COPY_NAMED_SUBSTRING,BITTWO)(rc, re, bptr, offsets, count, \ + namesptr, cbuffer, size) + +#define PCRE_COPY_SUBSTRING(rc, bptr, offsets, count, i, cbuffer, size) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_COPY_SUBSTRING,BITONE)(rc, bptr, offsets, count, i, cbuffer, size); \ + else \ + G(PCRE_COPY_SUBSTRING,BITTWO)(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 (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_DFA_EXEC,BITONE)(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets, workspace, size_workspace); \ + else \ + G(PCRE_DFA_EXEC,BITTWO)(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 (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_EXEC,BITONE)(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets); \ + else \ + G(PCRE_EXEC,BITTWO)(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets) + +#define PCRE_FREE_STUDY(extra) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_FREE_STUDY,BITONE)(extra); \ + else \ + G(PCRE_FREE_STUDY,BITTWO)(extra) + +#define PCRE_FREE_SUBSTRING(substring) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_FREE_SUBSTRING,BITONE)(substring); \ + else \ + G(PCRE_FREE_SUBSTRING,BITTWO)(substring) + +#define PCRE_FREE_SUBSTRING_LIST(listptr) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_FREE_SUBSTRING_LIST,BITONE)(listptr); \ + else \ + G(PCRE_FREE_SUBSTRING_LIST,BITTWO)(listptr) + +#define PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_GET_NAMED_SUBSTRING,BITONE)(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr); \ + else \ + G(PCRE_GET_NAMED_SUBSTRING,BITTWO)(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr) + +#define PCRE_GET_STRINGNUMBER(n, rc, ptr) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_GET_STRINGNUMBER,BITONE)(n, rc, ptr); \ + else \ + G(PCRE_GET_STRINGNUMBER,BITTWO)(n, rc, ptr) + +#define PCRE_GET_SUBSTRING(rc, bptr, use_offsets, count, i, subsptr) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_GET_SUBSTRING,BITONE)(rc, bptr, use_offsets, count, i, subsptr); \ + else \ + G(PCRE_GET_SUBSTRING,BITTWO)(rc, bptr, use_offsets, count, i, subsptr) + +#define PCRE_GET_SUBSTRING_LIST(rc, bptr, offsets, count, listptr) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_GET_SUBSTRING_LIST,BITONE)(rc, bptr, offsets, count, listptr); \ + else \ + G(PCRE_GET_SUBSTRING_LIST,BITTWO)(rc, bptr, offsets, count, listptr) + +#define PCRE_JIT_STACK_ALLOC(startsize, maxsize) \ + (pcre_mode == G(G(PCRE,BITONE),_MODE)) ? \ + G(PCRE_JIT_STACK_ALLOC,BITONE)(startsize, maxsize) \ + : G(PCRE_JIT_STACK_ALLOC,BITTWO)(startsize, maxsize) + +#define PCRE_JIT_STACK_FREE(stack) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_JIT_STACK_FREE,BITONE)(stack); \ + else \ + G(PCRE_JIT_STACK_FREE,BITTWO)(stack) + +#define PCRE_MAKETABLES \ + (pcre_mode == G(G(PCRE,BITONE),_MODE)) ? \ + G(G(pcre,BITONE),_maketables)() : G(G(pcre,BITTWO),_maketables)() + +#define PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, tables) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_PATTERN_TO_HOST_BYTE_ORDER,BITONE)(rc, re, extra, tables); \ + else \ + G(PCRE_PATTERN_TO_HOST_BYTE_ORDER,BITTWO)(rc, re, extra, tables) + +#define PCRE_PRINTINT(re, outfile, debug_lengths) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_PRINTINT,BITONE)(re, outfile, debug_lengths); \ + else \ + G(PCRE_PRINTINT,BITTWO)(re, outfile, debug_lengths) + +#define PCRE_STUDY(extra, re, options, error) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(PCRE_STUDY,BITONE)(extra, re, options, error); \ + else \ + G(PCRE_STUDY,BITTWO)(extra, re, options, error) + +#endif /* Two out of three modes */ + +/* ----- End of cases where more than one mode is supported ----- */ + + +/* ----- 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 ----- */ + +#elif defined SUPPORT_PCRE16 +#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 + +/* ----- Only 32-bit mode is supported ----- */ + +#elif defined SUPPORT_PCRE32 +#define CHAR_SIZE 4 +#define PCHARS PCHARS32 +#define PCHARSV PCHARSV32 +#define READ_CAPTURE_NAME READ_CAPTURE_NAME32 +#define SET_PCRE_CALLOUT SET_PCRE_CALLOUT32 +#define STRLEN STRLEN32 +#define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK32 +#define PCRE_COMPILE PCRE_COMPILE32 +#define PCRE_CONFIG pcre32_config +#define PCRE_COPY_NAMED_SUBSTRING PCRE_COPY_NAMED_SUBSTRING32 +#define PCRE_COPY_SUBSTRING PCRE_COPY_SUBSTRING32 +#define PCRE_DFA_EXEC PCRE_DFA_EXEC32 +#define PCRE_EXEC PCRE_EXEC32 +#define PCRE_FREE_STUDY PCRE_FREE_STUDY32 +#define PCRE_FREE_SUBSTRING PCRE_FREE_SUBSTRING32 +#define PCRE_FREE_SUBSTRING_LIST PCRE_FREE_SUBSTRING_LIST32 +#define PCRE_GET_NAMED_SUBSTRING PCRE_GET_NAMED_SUBSTRING32 +#define PCRE_GET_STRINGNUMBER PCRE_GET_STRINGNUMBER32 +#define PCRE_GET_SUBSTRING PCRE_GET_SUBSTRING32 +#define PCRE_GET_SUBSTRING_LIST PCRE_GET_SUBSTRING_LIST32 +#define PCRE_JIT_STACK_ALLOC PCRE_JIT_STACK_ALLOC32 +#define PCRE_JIT_STACK_FREE PCRE_JIT_STACK_FREE32 +#define PCRE_MAKETABLES pcre32_maketables() +#define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER32 +#define PCRE_PRINTINT PCRE_PRINTINT32 +#define PCRE_STUDY PCRE_STUDY32 + +#endif + +/* ----- End of mode-specific function call macros ----- */ + + +/* Other parameters */ + +#ifndef CLOCKS_PER_SEC +#ifdef CLK_TCK +#define CLOCKS_PER_SEC CLK_TCK +#else +#define CLOCKS_PER_SEC 100 +#endif +#endif + +#if !defined NODFA +#define DFA_WS_DIMENSION 1000 +#endif + +/* This is the default loop count for timing. */ + +#define LOOPREPEAT 500000 + +/* Static variables */ + +static FILE *outfile; +static int log_store = 0; +static int callout_count; +static int callout_extra; +static int callout_fail_count; +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_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 pcre_uint8 *buffer = NULL; +static pcre_uint8 *pbuffer = NULL; + +/* Just as a safety check, make sure that COMPILE_PCRE[16|32] are *not* set. */ + +#ifdef COMPILE_PCRE16 +#error COMPILE_PCRE16 must not be set when compiling pcretest.c +#endif + +#ifdef COMPILE_PCRE32 +#error COMPILE_PCRE32 must not be set when compiling pcretest.c +#endif + +/* We need buffers for building 16/32-bit strings, and the tables of operator +lengths that are used for 16/32-bit compiling, in order to swap bytes in a +pattern for saving/reloading testing. Luckily, the data for these tables is +defined as a macro. However, we must ensure that LINK_SIZE and IMM2_SIZE (which +are used in the tables) are adjusted appropriately for the 16/32-bit world. +LINK_SIZE is also used later in this program. */ + +#ifdef SUPPORT_PCRE16 +#undef IMM2_SIZE +#define IMM2_SIZE 1 + +#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 + +static int buffer16_size = 0; +static pcre_uint16 *buffer16 = NULL; +static const pcre_uint16 OP_lengths16[] = { OP_LENGTHS }; +#endif /* SUPPORT_PCRE16 */ + +#ifdef SUPPORT_PCRE32 +#undef IMM2_SIZE +#define IMM2_SIZE 1 +#undef LINK_SIZE +#define LINK_SIZE 1 + +static int buffer32_size = 0; +static pcre_uint32 *buffer32 = NULL; +static const pcre_uint32 OP_lengths32[] = { OP_LENGTHS }; +#endif /* SUPPORT_PCRE32 */ + +/* If we have 8-bit support, default to it; if there is also 16-or 32-bit +support, it can be changed by an option. If there is no 8-bit support, there +must be 16-or 32-bit support, so default it to 1. */ + +#if defined SUPPORT_PCRE8 +static int pcre_mode = PCRE8_MODE; +#elif defined SUPPORT_PCRE16 +static int pcre_mode = PCRE16_MODE; +#elif defined SUPPORT_PCRE32 +static int pcre_mode = PCRE32_MODE; +#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 +}; + +#define PCRE_STUDY_ALLJIT (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", + "bad JIT option", + "bad length" +}; + + +/************************************************* +* Alternate character tables * +*************************************************/ + +/* By default, the "tables" pointer when calling PCRE is set to NULL, thereby +using the default tables of the library. However, the T option can be used to +select alternate sets of tables, for different kinds of testing. Note also that +the L (locale) option also adjusts the tables. */ + +/* This is the set of tables distributed as default with PCRE. It recognizes +only ASCII characters. */ + +static const pcre_uint8 tables0[] = { + +/* This table is a lower casing table. */ + + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122, 91, 92, 93, 94, 95, + 96, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122,123,124,125,126,127, + 128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151, + 152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167, + 168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183, + 184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231, + 232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255, + +/* This table is a case flipping table. */ + + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119, + 120,121,122, 91, 92, 93, 94, 95, + 96, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90,123,124,125,126,127, + 128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151, + 152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167, + 168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183, + 184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231, + 232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255, + +/* This table contains bit maps for various character classes. Each map is 32 +bytes long and the bits run from the least significant end of each byte. The +classes that have their own maps are: space, xdigit, digit, upper, lower, word, +graph, print, punct, and cntrl. Other classes are built from combinations. */ + + 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, + 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, + 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + +/* This table identifies various classes of character by individual bits: + 0x01 white space character + 0x02 letter + 0x04 decimal digit + 0x08 hexadecimal digit + 0x10 alphanumeric or '_' + 0x80 regular expression metacharacter or binary zero +*/ + + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ + 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ + 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ + 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ + 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ + 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ + 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ + 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ + 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ + 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ + +/* This is a set of tables that came orginally from a Windows user. It seems to +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 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, +24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39, +40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55, +56,57,58,59,60,61,62,63, +64,97,98,99,100,101,102,103, +104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119, +120,121,122,91,92,93,94,95, +96,97,98,99,100,101,102,103, +104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119, +120,121,122,123,124,125,126,127, +128,129,130,131,132,133,134,135, +136,137,138,139,140,141,142,143, +144,145,146,147,148,149,150,151, +152,153,154,155,156,157,158,159, +160,161,162,163,164,165,166,167, +168,169,170,171,172,173,174,175, +176,177,178,179,180,181,182,183, +184,185,186,187,188,189,190,191, +224,225,226,227,228,229,230,231, +232,233,234,235,236,237,238,239, +240,241,242,243,244,245,246,215, +248,249,250,251,252,253,254,223, +224,225,226,227,228,229,230,231, +232,233,234,235,236,237,238,239, +240,241,242,243,244,245,246,247, +248,249,250,251,252,253,254,255, +0,1,2,3,4,5,6,7, +8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23, +24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39, +40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55, +56,57,58,59,60,61,62,63, +64,97,98,99,100,101,102,103, +104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119, +120,121,122,91,92,93,94,95, +96,65,66,67,68,69,70,71, +72,73,74,75,76,77,78,79, +80,81,82,83,84,85,86,87, +88,89,90,123,124,125,126,127, +128,129,130,131,132,133,134,135, +136,137,138,139,140,141,142,143, +144,145,146,147,148,149,150,151, +152,153,154,155,156,157,158,159, +160,161,162,163,164,165,166,167, +168,169,170,171,172,173,174,175, +176,177,178,179,180,181,182,183, +184,185,186,187,188,189,190,191, +224,225,226,227,228,229,230,231, +232,233,234,235,236,237,238,239, +240,241,242,243,244,245,246,215, +248,249,250,251,252,253,254,223, +192,193,194,195,196,197,198,199, +200,201,202,203,204,205,206,207, +208,209,210,211,212,213,214,247, +216,217,218,219,220,221,222,255, +0,62,0,0,1,0,0,0, +0,0,0,0,0,0,0,0, +32,0,0,0,1,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,255,3, +126,0,0,0,126,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,255,3, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,12,2, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +254,255,255,7,0,0,0,0, +0,0,0,0,0,0,0,0, +255,255,127,127,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,254,255,255,7, +0,0,0,0,0,4,32,4, +0,0,0,128,255,255,127,255, +0,0,0,0,0,0,255,3, +254,255,255,135,254,255,255,7, +0,0,0,0,0,4,44,6, +255,255,127,255,255,255,127,255, +0,0,0,0,254,255,255,255, +255,255,255,255,255,255,255,127, +0,0,0,0,254,255,255,255, +255,255,255,255,255,255,255,255, +0,2,0,0,255,255,255,255, +255,255,255,255,255,255,255,127, +0,0,0,0,255,255,255,255, +255,255,255,255,255,255,255,255, +0,0,0,0,254,255,0,252, +1,0,0,248,1,0,0,120, +0,0,0,0,254,255,255,255, +0,0,128,0,0,0,128,0, +255,255,255,255,0,0,0,0, +0,0,0,0,0,0,0,128, +255,255,255,255,0,0,0,0, +0,0,0,0,0,0,0,0, +128,0,0,0,0,0,0,0, +0,1,1,0,1,1,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +1,0,0,0,128,0,0,0, +128,128,128,128,0,0,128,0, +28,28,28,28,28,28,28,28, +28,28,0,0,0,0,0,128, +0,26,26,26,26,26,26,18, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18, +18,18,18,128,128,0,128,16, +0,26,26,26,26,26,26,18, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18, +18,18,18,128,128,0,0,0, +0,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0, +0,0,18,0,0,0,0,0, +0,0,20,20,0,18,0,0, +0,20,18,0,0,0,0,0, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,0, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,0, +18,18,18,18,18,18,18,18 +}; + + + + +#ifndef HAVE_STRERROR +/************************************************* +* Provide strerror() for non-ANSI libraries * +*************************************************/ + +/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() +in their libraries, but can provide the same facility by this simple +alternative function. */ + +extern int sys_nerr; +extern char *sys_errlist[]; + +char * +strerror(int n) +{ +if (n < 0 || n >= sys_nerr) return "unknown error number"; +return sys_errlist[n]; +} +#endif /* HAVE_STRERROR */ + + + +/************************************************* +* Print newline configuration * +*************************************************/ + +/* +Arguments: + rc the return code from PCRE_CONFIG_NEWLINE + isc TRUE if called from "-C newline" +Returns: nothing +*/ + +static void +print_newline_config(int rc, BOOL isc) +{ +const char *s = NULL; +if (!isc) printf(" Newline sequence is "); +switch(rc) + { + case CHAR_CR: s = "CR"; break; + case CHAR_LF: s = "LF"; break; + case (CHAR_CR<<8 | CHAR_LF): s = "CRLF"; break; + case -1: s = "ANY"; break; + case -2: s = "ANYCRLF"; break; + + default: + printf("a non-standard value: 0x%04x\n", rc); + return; + } + +printf("%s\n", s); +} + + + +/************************************************* +* 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 || defined SUPPORT_PCRE32 +/************************************************* +* 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, pcre_uint32 *vptr) +{ +pcre_uint32 c = *utf8bytes++; +pcre_uint32 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 <= (pcre_uint32)utf8_table1[j]) break; +if (j != i) return -(i+1); + +/* Valid value */ + +*vptr = d; +return i+1; +} +#endif /* NOUTF || SUPPORT_PCRE16 */ + + + +#if defined SUPPORT_PCRE8 && !defined NOUTF +/************************************************* +* 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(pcre_uint32 cvalue, pcre_uint8 *utf8bytes) +{ +register int i, j; +if (cvalue > 0x7fffffffu) + return -1; +for (i = 0; i < utf8_table1_size; i++) + if (cvalue <= (pcre_uint32)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 + { + pcre_uint32 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 + +#ifdef SUPPORT_PCRE32 +/************************************************* +* Convert a string to 32-bit * +*************************************************/ + +/* In non-UTF mode, the space needed for a 32-bit string is exactly four times the +8-bit size. For a UTF-8 string, the size needed for UTF-32 is no more than four +times, because up to 0xffff uses no more than 3 bytes in UTF-8 but possibly 4 +in UTF-32. Higher values use 4 bytes in UTF-8 and up to 4 bytes in UTF-32. The +result is always left in buffer32. + +Note that this function does not object to surrogate values. This is +deliberate; it makes it possible to construct UTF-32 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-32) + len number of bytes in the string (excluding trailing zero) + +Returns: number of 32-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 an ill-formed value is encountered (i.e. a surrogate) +*/ + +static int +to32(int data, pcre_uint8 *p, int utf, int len) +{ +pcre_uint32 *pp; + +if (buffer32_size < 4*len + 4) + { + if (buffer32 != NULL) free(buffer32); + buffer32_size = 4*len + 4; + buffer32 = (pcre_uint32 *)malloc(buffer32_size); + if (buffer32 == NULL) + { + fprintf(stderr, "pcretest: malloc(%d) failed for buffer32\n", buffer32_size); + exit(1); + } + } + +pp = buffer32; + +if (!utf && !data) + { + while (len-- > 0) *pp++ = *p++; + } + +else + { + pcre_uint32 c = 0; + while (len > 0) + { + int chlen = utf82ord(p, &c); + if (chlen <= 0) return -1; + if (utf) + { + if (c > 0x10ffff) return -2; + if (!data && (c & 0xfffff800u) == 0xd800u) return -3; + } + + p += chlen; + len -= chlen; + *pp++ = c; + } + } + +*pp = 0; +return pp - buffer32; +} + +/* Check that a 32-bit character string is valid UTF-32. + +Arguments: + string points to the string + length length of string, or -1 if the string is zero-terminated + +Returns: TRUE if the string is a valid UTF-32 string + FALSE otherwise +*/ + +#ifdef NEVER + +#ifdef SUPPORT_UTF +static BOOL +valid_utf32(pcre_uint32 *string, int length) +{ +register pcre_uint32 *p; +register pcre_uint32 c; + +for (p = string; length-- > 0; p++) + { + c = *p; + + if (c > 0x10ffffu) + return FALSE; + + /* A surrogate */ + if ((c & 0xfffff800u) == 0xd800u) + return FALSE; + + /* Non-character */ + if ((c & 0xfffeu) == 0xfffeu || (c >= 0xfdd0u && c <= 0xfdefu)) + return FALSE; + } + +return TRUE; +} +#endif /* SUPPORT_UTF */ + +#endif /* NEVER */ + + +#endif + +/************************************************* +* Read or extend an input line * +*************************************************/ + +/* Input lines are read into buffer, but both patterns and data lines can be +continued over multiple input lines. In addition, if the buffer fills up, we +want to automatically expand it so as to be able to handle extremely large +lines that are needed for certain stress tests. When the input buffer is +expanded, the other two buffers must also be expanded likewise, and the +contents of pbuffer, which are a copy of the input for callouts, must be +preserved (for when expansion happens for a data line). This is not the most +optimal way of handling this, but hey, this is just a test program! + +Arguments: + f the file to read + start where in buffer to start (this *must* be within buffer) + prompt for stdin or readline() + +Returns: pointer to the start of new data + could be a copy of start, or could be moved + NULL if no data read and EOF reached +*/ + +static pcre_uint8 * +extend_inputline(FILE *f, pcre_uint8 *start, const char *prompt) +{ +pcre_uint8 *here = start; + +for (;;) + { + size_t rlen = (size_t)(buffer_size - (here - buffer)); + + if (rlen > 1000) + { + int dlen; + + /* 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(). */ + +#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) + if (isatty(fileno(f))) + { + size_t len; + char *s = readline(prompt); + if (s == NULL) return (here == start)? NULL : start; + len = strlen(s); + if (len > 0) add_history(s); + if (len > rlen - 1) len = rlen - 1; + memcpy(here, s, len); + here[len] = '\n'; + here[len+1] = 0; + free(s); + } + else +#endif + + /* Read the next line by normal means, prompting if the file is stdin. */ + + { + if (f == stdin) printf("%s", prompt); + if (fgets((char *)here, rlen, f) == NULL) + return (here == start)? NULL : start; + } + + dlen = (int)strlen((char *)here); + if (dlen > 0 && here[dlen - 1] == '\n') return start; + here += dlen; + } + + else + { + int new_buffer_size = 2*buffer_size; + pcre_uint8 *new_buffer = (pcre_uint8 *)malloc(new_buffer_size); + pcre_uint8 *new_pbuffer = (pcre_uint8 *)malloc(new_buffer_size); + + if (new_buffer == NULL || new_pbuffer == NULL) + { + fprintf(stderr, "pcretest: malloc(%d) failed\n", new_buffer_size); + exit(1); + } + + memcpy(new_buffer, buffer, buffer_size); + memcpy(new_pbuffer, pbuffer, buffer_size); + + buffer_size = new_buffer_size; + + start = new_buffer + (start - buffer); + here = new_buffer + (here - buffer); + + free(buffer); + free(pbuffer); + + buffer = new_buffer; + pbuffer = new_pbuffer; + } + } + +return NULL; /* Control never gets here */ +} + + + +/************************************************* +* Read number from string * +*************************************************/ + +/* We don't use strtoul() because SunOS4 doesn't have it. Rather than mess +around with conditional compilation, just do the job by hand. It is only used +for unpicking arguments, so just keep it simple. + +Arguments: + str string to be converted + endptr where to put the end pointer + +Returns: the unsigned long +*/ + +static int +get_value(pcre_uint8 *str, pcre_uint8 **endptr) +{ +int result = 0; +while(*str != 0 && isspace(*str)) str++; +while (isdigit(*str)) result = result * 10 + (int)(*str++ - '0'); +*endptr = str; +return(result); +} + + + +/************************************************* +* Print one character * +*************************************************/ + +/* Print a single character either literally, or as a hex escape. */ + +static int pchar(pcre_uint32 c, FILE *f) +{ +int n = 0; +if (PRINTOK(c)) + { + if (f != NULL) fprintf(f, "%c", c); + return 1; + } + +if (c < 0x100) + { + 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 (f != NULL) n = fprintf(f, "\\x{%02x}", c); +return n >= 0 ? n : 0; +} + + + +#ifdef SUPPORT_PCRE8 +/************************************************* +* Print 8-bit character string * +*************************************************/ + +/* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed. +If handed a NULL file, just counts chars without printing. */ + +static int pchars(pcre_uint8 *p, int length, FILE *f) +{ +pcre_uint32 c = 0; +int yield = 0; + +if (length < 0) + length = strlen((char *)p); + +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 +/************************************************* +* Find length of 0-terminated 16-bit string * +*************************************************/ + +static int strlen16(PCRE_SPTR16 p) +{ +int len = 0; +while (*p++ != 0) len++; +return len; +} +#endif /* SUPPORT_PCRE16 */ + + + +#ifdef SUPPORT_PCRE32 +/************************************************* +* Find length of 0-terminated 32-bit string * +*************************************************/ + +static int strlen32(PCRE_SPTR32 p) +{ +int len = 0; +while (*p++ != 0) len++; +return len; +} +#endif /* SUPPORT_PCRE32 */ + + + +#ifdef SUPPORT_PCRE16 +/************************************************* +* Print 16-bit character string * +*************************************************/ + +/* 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 pchars16(PCRE_SPTR16 p, int length, FILE *f) +{ +int yield = 0; + +if (length < 0) + length = strlen16(p); + +while (length-- > 0) + { + pcre_uint32 c = *p++ & 0xffff; +#if !defined NOUTF + if (use_utf && c >= 0xD800 && c < 0xDC00 && length > 0) + { + int d = *p & 0xffff; + if (d >= 0xDC00 && d < 0xDFFF) + { + c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000; + length--; + p++; + } + } +#endif + yield += pchar(c, f); + } + +return yield; +} +#endif /* SUPPORT_PCRE16 */ + + + +#ifdef SUPPORT_PCRE32 +/************************************************* +* Print 32-bit character string * +*************************************************/ + +/* Must handle UTF-32 strings in utf mode. Yields number of characters printed. +If handed a NULL file, just counts chars without printing. */ + +static int pchars32(PCRE_SPTR32 p, int length, BOOL utf, FILE *f) +{ +int yield = 0; + +(void)(utf); /* Avoid compiler warning */ + +if (length < 0) + length = strlen32(p); + +while (length-- > 0) + { + pcre_uint32 c = *p++; + yield += pchar(c, f); + } + +return yield; +} +#endif /* SUPPORT_PCRE32 */ + + + +#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"); + } + +*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 */ + + + +#ifdef SUPPORT_PCRE32 +/************************************************* +* Read a capture name (32-bit) and check it * +*************************************************/ + +/* Note that the text being read is 8-bit. */ + +static pcre_uint8 * +read_capture_name32(pcre_uint8 *p, pcre_uint32 **pp, pcre *re) +{ +pcre_uint32 *npp = *pp; +while (isalnum(*p)) *npp++ = *p++; +*npp++ = 0; +*npp = 0; +if (pcre32_get_stringnumber((pcre32 *)re, (PCRE_SPTR32)(*pp)) < 0) + { + fprintf(outfile, "no parentheses with name \""); + PCHARSV(*pp, 0, -1, outfile); + fprintf(outfile, "\"\n"); + } +*pp = npp; +return p; +} +#endif /* SUPPORT_PCRE32 */ + + + +/************************************************* +* Callout function * +*************************************************/ + +/* Called from PCRE as a result of the (?C) item. We print out where we are in +the match. Yield zero unless more callouts than the fail count, or the callout +data is not zero. */ + +static int callout(pcre_callout_block *cb) +{ +FILE *f = (first_callout | callout_extra)? outfile : NULL; +int i, pre_start, post_start, subject_length; + +if (callout_extra) + { + fprintf(f, "Callout %d: last capture = %d\n", + cb->callout_number, cb->capture_last); + + for (i = 0; i < cb->capture_top * 2; i += 2) + { + if (cb->offset_vector[i] < 0) + fprintf(f, "%2d: \n", i/2); + else + { + fprintf(f, "%2d: ", i/2); + PCHARSV(cb->subject, cb->offset_vector[i], + cb->offset_vector[i+1] - cb->offset_vector[i], f); + fprintf(f, "\n"); + } + } + } + +/* Re-print the subject in canonical form, the first time or if giving full +datails. On subsequent calls in the same match, we use pchars just to find the +printed lengths of the substrings. */ + +if (f != NULL) fprintf(f, "--->"); + +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); + +PCHARS(subject_length, cb->subject, 0, cb->subject_length, NULL); + +PCHARSV(cb->subject, cb->current_position, + cb->subject_length - cb->current_position, f); + +if (f != NULL) fprintf(f, "\n"); + +/* Always print appropriate indicators, with callout number if not already +shown. For automatic callouts, show the pattern offset. */ + +if (cb->callout_number == 255) + { + fprintf(outfile, "%+3d ", cb->pattern_position); + if (cb->pattern_position > 99) fprintf(outfile, "\n "); + } +else + { + if (callout_extra) fprintf(outfile, " "); + else fprintf(outfile, "%3d ", cb->callout_number); + } + +for (i = 0; i < pre_start; i++) fprintf(outfile, " "); +fprintf(outfile, "^"); + +if (post_start > 0) + { + for (i = 0; i < post_start - 1; i++) fprintf(outfile, " "); + fprintf(outfile, "^"); + } + +for (i = 0; i < subject_length - pre_start - post_start + 4; i++) + fprintf(outfile, " "); + +fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length, + pbuffer + cb->pattern_position); + +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)); + if (callout_data != 0) + { + fprintf(outfile, "Callout data = %d\n", callout_data); + return callout_data; + } + } + +return (cb->callout_number != callout_fail_id)? 0 : + (++callout_count >= callout_fail_count)? 1 : 0; +} + + +/************************************************* +* Local malloc functions * +*************************************************/ + +/* 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; +} + +static void new_free(void *block) +{ +if (show_malloc) + fprintf(outfile, "free %p\n", block); +free(block); +} + +/* For recursion malloc/free, to test stacking calls */ + +static void *stack_malloc(size_t size) +{ +void *block = malloc(size); +if (show_malloc) + fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block); +return block; +} + +static void stack_free(void *block) +{ +if (show_malloc) + fprintf(outfile, "stack_free %p\n", block); +free(block); +} + + +/************************************************* +* Call pcre_fullinfo() * +*************************************************/ + +/* Get one piece of information from the pcre_fullinfo() function. When only +one of 8-, 16- or 32-bit is supported, pcre_mode 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 int +new_info(pcre *re, pcre_extra *study, int option, void *ptr) +{ +int rc; + +if (pcre_mode == PCRE32_MODE) +#ifdef SUPPORT_PCRE32 + rc = pcre32_fullinfo((pcre32 *)re, (pcre32_extra *)study, option, ptr); +#else + rc = PCRE_ERROR_BADMODE; +#endif +else if (pcre_mode == PCRE16_MODE) +#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, + pcre_mode == PCRE32_MODE ? "32" : pcre_mode == PCRE16_MODE ? "16" : "", option); + if (rc == PCRE_ERROR_BADMODE) + fprintf(outfile, "Running in %d-bit mode but pattern was compiled in " + "%d-bit mode\n", 8 * CHAR_SIZE, + 8 * (REAL_PCRE_FLAGS(re) & PCRE_MODE_MASK)); + } + +return rc; +} + + + +/************************************************* +* Swap byte functions * +*************************************************/ + +/* 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) +{ +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); +} + + + +/************************************************* +* 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. */ + +#if defined SUPPORT_PCRE8 || defined SUPPORT_PCRE16 +static void +regexflip8_or_16(pcre *ere, pcre_extra *extra) +{ +real_pcre8_or_16 *re = (real_pcre8_or_16 *)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 (pcre_mode != PCRE16_MODE) 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 */ +} +#endif /* SUPPORT_PCRE[8|16] */ + + + +#if defined SUPPORT_PCRE32 +static void +regexflip_32(pcre *ere, pcre_extra *extra) +{ +real_pcre32 *re = (real_pcre32 *)ere; +int op; +pcre_uint32 *ptr = (pcre_uint32 *)re + re->name_table_offset; +int length = re->name_count * re->name_entry_size; + +/* 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_uint32(re->first_char); +re->req_char = swap_uint32(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 32-bit mode we must swap bytes in the name table, if present, and then in +the pattern itself. */ + +while(TRUE) + { + /* Swap previous characters. */ + while (length-- > 0) + { + *ptr = swap_uint32(*ptr); + ptr++; + } + + /* Get next opcode. */ + + length = 0; + op = *ptr; + *ptr++ = swap_uint32(op); + + switch (op) + { + case OP_END: + return; + + default: + length = OP_lengths32[op] - 1; + break; + + case OP_CLASS: + case OP_NCLASS: + /* Skip the character bit map. */ + ptr += 32/sizeof(pcre_uint32); + length = 0; + break; + + case OP_XCLASS: + /* LINK_SIZE can only be 1 in 32-bit mode. */ + length = (int)((unsigned int)(ptr[0]) - (1 + LINK_SIZE + 1)); + + /* Reverse the size of the XCLASS instance. */ + *ptr = swap_uint32(*ptr); + ptr++; + + op = *ptr; + *ptr = swap_uint32(op); + ptr++; + if ((op & XCL_MAP) != 0) + { + /* Skip the character bit map. */ + ptr += 32/sizeof(pcre_uint32); + length -= 32/sizeof(pcre_uint32); + } + break; + } + } +/* Control should never reach here in 32 bit mode. */ +} + +#endif /* SUPPORT_PCRE32 */ + + + +static void +regexflip(pcre *ere, pcre_extra *extra) +{ +#if defined SUPPORT_PCRE32 + if (REAL_PCRE_FLAGS(ere) & PCRE_MODE32) + regexflip_32(ere, extra); +#endif +#if defined SUPPORT_PCRE8 || defined SUPPORT_PCRE16 + if (REAL_PCRE_FLAGS(ere) & (PCRE_MODE8 | PCRE_MODE16)) + regexflip8_or_16(ere, extra); +#endif +} + + + +/************************************************* +* Check match or recursion limit * +*************************************************/ + +static int +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) +{ +int count; +int min = 0; +int mid = 64; +int max = -1; + +extra->flags |= flag; + +for (;;) + { + *limit = mid; + + PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, + use_offsets, use_size_offsets); + + if (count == errnumber) + { + /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */ + min = mid; + mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2; + } + + else if (count >= 0 || count == PCRE_ERROR_NOMATCH || + count == PCRE_ERROR_PARTIAL) + { + if (mid == min + 1) + { + fprintf(outfile, "Minimum %s limit = %d\n", msg, mid); + break; + } + /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */ + max = mid; + mid = (min + mid)/2; + } + else break; /* Some other error */ + } + +extra->flags &= ~flag; +return count; +} + + + +/************************************************* +* Case-independent strncmp() function * +*************************************************/ + +/* +Arguments: + s first string + t second string + n number of characters to compare + +Returns: < 0, = 0, or > 0, according to the comparison +*/ + +static int +strncmpic(pcre_uint8 *s, pcre_uint8 *t, int n) +{ +while (n--) + { + int c = tolower(*s++) - tolower(*t++); + if (c) return c; + } +return 0; +} + + + +/************************************************* +* Check newline indicator * +*************************************************/ + +/* This is used both at compile and run-time to check for escapes. Print +a message and return 0 if there is no match. + +Arguments: + p points after the leading '<' + f file for error message + +Returns: appropriate PCRE_NEWLINE_xxx flags, or 0 +*/ + +static int +check_newline(pcre_uint8 *p, FILE *f) +{ +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; +} + + + +/************************************************* +* Usage function * +*************************************************/ + +static void +usage(void) +{ +printf("Usage: pcretest [options] [ []]\n\n"); +printf("Input and output default to stdin and stdout.\n"); +#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"); +#ifdef SUPPORT_PCRE16 +printf(" -16 use the 16-bit library\n"); +#endif +#ifdef SUPPORT_PCRE32 +printf(" -32 use the 32-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(" pcre32 32 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"); +#endif +printf(" -help show usage information\n"); +printf(" -i show information about compiled patterns\n" + " -M find MATCH_LIMIT minimum for each subject\n" + " -m output memory used information\n" + " -o set size of offsets vector to \n"); +#if !defined NOPOSIX +printf(" -p use POSIX interface\n"); +#endif +printf(" -q quiet: do not output PCRE version number at start\n"); +printf(" -S set stack size to megabytes\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"); +printf(" -tm time execution (matching) only, repeating times\n"); +} + + + +/************************************************* +* Main Program * +*************************************************/ + +/* Read lines from named file or stdin and write to named file or stdout; lines +consist of a regular expression, in delimiters and optionally followed by +options, followed by a set of test data, terminated by an empty line. */ + +int main(int argc, char **argv) +{ +FILE *infile = stdin; +const char *version; +int options = 0; +int study_options = 0; +int default_find_match_limit = FALSE; +int op = 1; +int timeit = 0; +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; +int debug = 0; +int done = 0; +int all_use_dfa = 0; +int verify_jit = 0; +int yield = 0; +int stack_size; +pcre_uint8 *dbuffer = NULL; +size_t dbuffer_size = 1u << 14; + +#if !defined NOPOSIX +int posix = 0; +#endif +#if !defined NODFA +int *dfa_workspace = NULL; +#endif + +pcre_jit_stack *jit_stack = NULL; + +/* 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-, 16- and 32-bit versions, using the 32-bit version +for the actual memory, to ensure alignment. */ + +pcre_uint32 copynames[1024]; +pcre_uint32 getnames[1024]; + +#ifdef SUPPORT_PCRE32 +pcre_uint32 *cn32ptr; +pcre_uint32 *gn32ptr; +#endif + +#ifdef SUPPORT_PCRE16 +pcre_uint16 *copynames16 = (pcre_uint16 *)copynames; +pcre_uint16 *getnames16 = (pcre_uint16 *)getnames; +pcre_uint16 *cn16ptr; +pcre_uint16 *gn16ptr; +#endif + +#ifdef SUPPORT_PCRE8 +pcre_uint8 *copynames8 = (pcre_uint8 *)copynames; +pcre_uint8 *getnames8 = (pcre_uint8 *)getnames; +pcre_uint8 *cn8ptr; +pcre_uint8 *gn8ptr; +#endif + +/* Get buffers from malloc() so that valgrind will check their misuse when +debugging. They grow automatically when very long lines are read. The 16- +and 32-bit buffers (buffer16, buffer32) are obtained only if needed. */ + +buffer = (pcre_uint8 *)malloc(buffer_size); +pbuffer = (pcre_uint8 *)malloc(buffer_size); + +/* The outfile variable is static so that new_malloc can use it. */ + +outfile = stdout; + +/* The following _setmode() stuff is some Windows magic that tells its runtime +library to translate CRLF into a single LF character. At least, that's what +I've been told: never having used Windows I take this all on trust. Originally +it set 0x8000, but then I was advised that _O_BINARY was better. */ + +#if defined(_WIN32) || defined(WIN32) +_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. */ + +#if defined SUPPORT_PCRE8 +version = pcre_version(); +#elif defined SUPPORT_PCRE16 +version = pcre16_version(); +#elif defined SUPPORT_PCRE32 +version = pcre32_version(); +#endif + +/* Scan options */ + +while (argc > 1 && argv[op][0] == '-') + { + pcre_uint8 *endptr; + char *arg = argv[op]; + + if (strcmp(arg, "-m") == 0) showstore = 1; + else if (strcmp(arg, "-s") == 0) force_study = 0; + + 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, "-8") == 0) + { +#ifdef SUPPORT_PCRE8 + pcre_mode = PCRE8_MODE; +#else + printf("** This version of PCRE was built without 8-bit support\n"); + exit(1); +#endif + } + else if (strcmp(arg, "-16") == 0) + { +#ifdef SUPPORT_PCRE16 + pcre_mode = PCRE16_MODE; +#else + printf("** This version of PCRE was built without 16-bit support\n"); + exit(1); +#endif + } + else if (strcmp(arg, "-32") == 0) + { +#ifdef SUPPORT_PCRE32 + pcre_mode = PCRE32_MODE; +#else + printf("** This version of PCRE was built without 32-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(arg, "-dfa") == 0) all_use_dfa = 1; +#endif + 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(arg, "-t") == 0 || strcmp(arg, "-tm") == 0) + { + int both = arg[2] == 0; + int temp; + if (argc > 2 && (temp = get_value((pcre_uint8 *)argv[op+1], &endptr), + *endptr == 0)) + { + timeitm = temp; + op++; + argc--; + } + else timeitm = LOOPREPEAT; + if (both) timeit = timeitm; + } + 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) || defined(__minix) || defined(NATIVE_ZOS) + printf("PCRE: -S not supported on this OS\n"); + exit(1); +#else + int rc; + struct rlimit rlim; + getrlimit(RLIMIT_STACK, &rlim); + rlim.rlim_cur = stack_size * 1024 * 1024; + rc = setrlimit(RLIMIT_STACK, &rlim); + if (rc != 0) + { + printf("PCRE: setrlimit() failed with error %d\n", rc); + exit(1); + } + op++; + argc--; +#endif + } +#if !defined NOPOSIX + else if (strcmp(arg, "-p") == 0) posix = 1; +#endif + else if (strcmp(arg, "-C") == 0) + { + int rc; + unsigned long int lrc; + + if (argc > 2) + { + if (strcmp(argv[op + 1], "linksize") == 0) + { + (void)PCRE_CONFIG(PCRE_CONFIG_LINK_SIZE, &rc); + printf("%d\n", rc); + yield = rc; + } + else if (strcmp(argv[op + 1], "pcre8") == 0) + { +#ifdef SUPPORT_PCRE8 + printf("1\n"); + yield = 1; +#else + printf("0\n"); + yield = 0; +#endif + goto EXIT; + } + else if (strcmp(argv[op + 1], "pcre16") == 0) + { +#ifdef SUPPORT_PCRE16 + printf("1\n"); + yield = 1; +#else + printf("0\n"); + yield = 0; +#endif + goto EXIT; + } + else if (strcmp(argv[op + 1], "pcre32") == 0) + { +#ifdef SUPPORT_PCRE32 + printf("1\n"); + yield = 1; +#else + printf("0\n"); + yield = 0; +#endif + goto EXIT; + } + if (strcmp(argv[op + 1], "utf") == 0) + { +#ifdef SUPPORT_PCRE8 + if (pcre_mode == PCRE8_MODE) + (void)pcre_config(PCRE_CONFIG_UTF8, &rc); +#endif +#ifdef SUPPORT_PCRE16 + if (pcre_mode == PCRE16_MODE) + (void)pcre16_config(PCRE_CONFIG_UTF16, &rc); +#endif +#ifdef SUPPORT_PCRE32 + if (pcre_mode == PCRE32_MODE) + (void)pcre32_config(PCRE_CONFIG_UTF32, &rc); +#endif + printf("%d\n", rc); + yield = rc; + goto EXIT; + } + else if (strcmp(argv[op + 1], "ucp") == 0) + { + (void)PCRE_CONFIG(PCRE_CONFIG_UNICODE_PROPERTIES, &rc); + printf("%d\n", rc); + yield = rc; + } + else if (strcmp(argv[op + 1], "jit") == 0) + { + (void)PCRE_CONFIG(PCRE_CONFIG_JIT, &rc); + printf("%d\n", rc); + yield = rc; + } + else if (strcmp(argv[op + 1], "newline") == 0) + { + (void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &rc); + print_newline_config(rc, TRUE); + } + else if (strcmp(argv[op + 1], "ebcdic") == 0) + { +#ifdef EBCDIC + printf("1\n"); + yield = 1; +#else + printf("0\n"); +#endif + } + else if (strcmp(argv[op + 1], "ebcdic-nl") == 0) + { +#ifdef EBCDIC + printf("0x%02x\n", CHAR_LF); +#else + printf("0\n"); +#endif + } + else + { + printf("Unknown -C option: %s\n", argv[op + 1]); + } + goto EXIT; + } + + /* No argument for -C: output all configuration information. */ + + printf("PCRE version %s\n", version); + printf("Compiled with\n"); + +#ifdef EBCDIC + printf(" EBCDIC code support: LF is 0x%02x\n", CHAR_LF); +#endif + +/* 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. */ + +#ifdef SUPPORT_PCRE8 + printf(" 8-bit support\n"); + (void)pcre_config(PCRE_CONFIG_UTF8, &rc); + printf (" %sUTF-8 support\n", rc ? "" : "No "); +#endif +#ifdef SUPPORT_PCRE16 + printf(" 16-bit support\n"); + (void)pcre16_config(PCRE_CONFIG_UTF16, &rc); + printf (" %sUTF-16 support\n", rc ? "" : "No "); +#endif +#ifdef SUPPORT_PCRE32 + printf(" 32-bit support\n"); + (void)pcre32_config(PCRE_CONFIG_UTF32, &rc); + printf (" %sUTF-32 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_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); + print_newline_config(rc, FALSE); + (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); + printf(" Internal link size = %d\n", 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); + printf(" Default match limit = %ld\n", 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", 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(arg, "-help") == 0 || + strcmp(arg, "--help") == 0) + { + usage(); + goto EXIT; + } + else + { + BAD_ARG: + printf("** Unknown or malformed option %s\n", arg); + usage(); + yield = 1; + goto EXIT; + } + op++; + argc--; + } + +/* Get the store for the offsets vector, and remember what it was */ + +size_offsets_max = size_offsets; +offsets = (int *)malloc(size_offsets_max * sizeof(int)); +if (offsets == NULL) + { + printf("** Failed to get %d bytes of memory for offsets vector\n", + (int)(size_offsets_max * sizeof(int))); + yield = 1; + goto EXIT; + } + +/* Sort out the input and output files */ + +if (argc > 1) + { + infile = fopen(argv[op], INPUT_MODE); + if (infile == NULL) + { + printf("** Failed to open %s\n", argv[op]); + yield = 1; + goto EXIT; + } + } + +if (argc > 2) + { + outfile = fopen(argv[op+1], OUTPUT_MODE); + if (outfile == NULL) + { + printf("** Failed to open %s\n", argv[op+1]); + yield = 1; + goto EXIT; + } + } + +/* 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 + +#ifdef SUPPORT_PCRE32 +pcre32_malloc = new_malloc; +pcre32_free = new_free; +pcre32_stack_malloc = stack_malloc; +pcre32_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", version); + +/* Main loop */ + +while (!done) + { + pcre *re = NULL; + pcre_extra *extra = NULL; + +#if !defined NOPOSIX /* There are still compilers that require no indent */ + regex_t preg; + int do_posix = 0; +#endif + + const char *error; + 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; + +#if !defined NODFA + int dfa_matched = 0; +#endif + + use_utf = 0; + debug_lengths = 1; + + if (extend_inputline(infile, buffer, " re> ") == NULL) break; + if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); + fflush(outfile); + + p = buffer; + while (isspace(*p)) p++; + if (*p == 0) continue; + + /* See if the pattern is to be loaded pre-compiled from a file. */ + + if (*p == '<' && strchr((char *)(p+1), '<') == NULL) + { + 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; + + f = fopen((char *)p, "rb"); + if (f == NULL) + { + fprintf(outfile, "Failed to open %s: %s\n", p, strerror(errno)); + continue; + } + + first_gotten_store = 0; + if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ; + + true_size = + (sbuf[0] << 24) | (sbuf[1] << 16) | (sbuf[2] << 8) | sbuf[3]; + true_study_size = + (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7]; + + re = (pcre *)new_malloc(true_size); + if (re == NULL) + { + printf("** Failed to get %d bytes of memory for pcre object\n", + (int)true_size); + yield = 1; + goto EXIT; + } + regex_gotten_store = first_gotten_store; + + if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ; + + magic = REAL_PCRE_MAGIC(re); + if (magic != MAGIC_NUMBER) + { + if (swap_uint32(magic) == MAGIC_NUMBER) + { + do_flip = 1; + } + else + { + fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p); + new_free(re); + fclose(f); + continue; + } + } + + /* 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); + + /* Now see if there is any following study data. */ + + if (true_study_size != 0) + { + pcre_study_data *psd; + + extra = (pcre_extra *)new_malloc(sizeof(pcre_extra) + true_study_size); + extra->flags = PCRE_EXTRA_STUDY_DATA; + + psd = (pcre_study_data *)(((char *)extra) + sizeof(pcre_extra)); + extra->study_data = psd; + + if (fread(psd, 1, true_study_size, f) != true_study_size) + { + FAIL_READ: + fprintf(outfile, "Failed to read data from %s\n", p); + if (extra != NULL) + { + PCRE_FREE_STUDY(extra); + } + new_free(re); + fclose(f); + continue; + } + fprintf(outfile, "Study data loaded from %s\n", p); + do_study = 1; /* To get the data output if requested */ + } + 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) + { + pcre_uint16 flags_in_host_byte_order; + if (REAL_PCRE_MAGIC(re) == MAGIC_NUMBER) + flags_in_host_byte_order = REAL_PCRE_FLAGS(re); + else + flags_in_host_byte_order = swap_uint16(REAL_PCRE_FLAGS(re)); + /* Simulate the result of the function call below. */ + fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc, + pcre_mode == PCRE32_MODE ? "32" : pcre_mode == PCRE16_MODE ? "16" : "", + PCRE_INFO_OPTIONS); + fprintf(outfile, "Running in %d-bit mode but pattern was compiled in " + "%d-bit mode\n", 8 * CHAR_SIZE, 8 * (flags_in_host_byte_order & PCRE_MODE_MASK)); + new_free(re); + fclose(f); + continue; + } + } + + /* Need to know if UTF-8 for printing data strings. */ + + if (new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options) < 0) + { + new_free(re); + fclose(f); + 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 it isn't complete, read more. */ + + delimiter = *p++; + + if (isalnum(delimiter) || delimiter == '\\') + { + fprintf(outfile, "** Delimiter must not be alphanumeric or \\\n"); + goto SKIP_DATA; + } + + pp = p; + poffset = (int)(p - buffer); + + for(;;) + { + while (*pp != 0) + { + if (*pp == '\\' && pp[1] != 0) pp++; + else if (*pp == delimiter) break; + pp++; + } + if (*pp != 0) break; + if ((pp = extend_inputline(infile, pp, " > ")) == NULL) + { + fprintf(outfile, "** Unexpected EOF\n"); + done = 1; + goto CONTINUE; + } + if (infile != stdin) fprintf(outfile, "%s", (char *)pp); + } + + /* The buffer may have moved while being extended; reset the start of data + pointer to the correct relative point in the buffer. */ + + p = buffer + poffset; + + /* If the first character after the delimiter is backslash, make + the pattern end with backslash. This is purely to provide a way + of testing for the error message when a pattern ends with backslash. */ + + if (pp[1] == '\\') *pp++ = '\\'; + + /* Terminate the pattern at the delimiter, and save a copy of the pattern + for callouts. */ + + *pp++ = 0; + strcpy((char *)pbuffer, (char *)p); + + /* Look for options after final delimiter */ + + options = 0; + study_options = force_study_options; + log_store = showstore; /* default from command line */ + + while (*pp != 0) + { + switch (*pp++) + { + case 'f': options |= PCRE_FIRSTLINE; break; + case 'g': do_g = 1; break; + case 'i': options |= PCRE_CASELESS; break; + case 'm': options |= PCRE_MULTILINE; break; + case 's': options |= PCRE_DOTALL; break; + case 'x': options |= PCRE_EXTENDED; 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; + case 'D': do_debug = do_showinfo = 1; break; + case 'E': options |= PCRE_DOLLAR_ENDONLY; break; + case 'F': do_flip = 1; break; + case 'G': do_G = 1; break; + case 'I': do_showinfo = 1; break; + case 'J': options |= PCRE_DUPNAMES; break; + case 'K': do_mark = 1; break; + case 'M': log_store = 1; break; + case 'N': options |= PCRE_NO_AUTO_CAPTURE; break; + +#if !defined NOPOSIX + case 'P': do_posix = 1; break; +#endif + + case 'S': + do_study = 1; + for (;;) + { + switch (*pp++) + { + case 'S': + do_study = 0; + no_force_study = 1; + break; + + case '!': + study_options |= PCRE_STUDY_EXTRA_NEEDED; + break; + + case '+': + 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]; + break; + + case '-': + study_options &= ~PCRE_STUDY_ALLJIT; + break; + + default: + pp--; + goto ENDLOOP; + } + } + ENDLOOP: + 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_utf = 1; break; + case '?': options |= PCRE_NO_UTF8_CHECK; break; + + case 'T': + switch (*pp++) + { + case '0': tables = tables0; break; + case '1': tables = tables1; break; + + case '\r': + case '\n': + case ' ': + case 0: + fprintf(outfile, "** Missing table number after /T\n"); + goto SKIP_DATA; + + default: + fprintf(outfile, "** Bad table number \"%c\" after /T\n", pp[-1]); + goto SKIP_DATA; + } + break; + + case 'L': + ppp = pp; + /* The '\r' test here is so that it works on Windows. */ + /* The '0' test is just in case this is an unterminated line. */ + while (*ppp != 0 && *ppp != '\n' && *ppp != '\r' && *ppp != ' ') ppp++; + *ppp = 0; + if (setlocale(LC_CTYPE, (const char *)pp) == NULL) + { + fprintf(outfile, "** Failed to set locale \"%s\"\n", pp); + goto SKIP_DATA; + } + locale_set = 1; + tables = PCRE_MAKETABLES; + pp = ppp; + break; + + case '>': + to_file = pp; + while (*pp != 0) pp++; + while (isspace(pp[-1])) pp--; + *pp = 0; + break; + + case '<': + { + if (strncmpic(pp, (pcre_uint8 *)"JS>", 3) == 0) + { + options |= PCRE_JAVASCRIPT_COMPAT; + pp += 3; + } + else + { + int x = check_newline(pp, outfile); + if (x == 0) goto SKIP_DATA; + options |= x; + while (*pp++ != '>'); + } + } + break; + + case '\r': /* So that it works in Windows */ + case '\n': + case ' ': + break; + + default: + fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); + goto SKIP_DATA; + } + } + + /* 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. Neither does it have 16-bit support. */ + +#if !defined NOPOSIX + if (posix || do_posix) + { + int rc; + int cflags = 0; + + if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE; + if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE; + if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL; + if ((options & PCRE_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB; + if ((options & PCRE_UTF8) != 0) cflags |= REG_UTF8; + 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 + if non-interactive. */ + + if (rc != 0) + { + (void)regerror(rc, &preg, (char *)buffer, buffer_size); + fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); + goto SKIP_DATA; + } + } + + /* Handle compiling via the native interface */ + + else +#endif /* !defined NOPOSIX */ + + { + /* In 16- or 32-bit mode, convert the input. */ + +#ifdef SUPPORT_PCRE16 + if (pcre_mode == PCRE16_MODE) + { + 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 + +#ifdef SUPPORT_PCRE32 + if (pcre_mode == PCRE32_MODE) + { + switch(to32(FALSE, p, options & PCRE_UTF32, (int)strlen((char *)p))) + { + case -1: + fprintf(outfile, "**Failed: invalid UTF-8 string cannot be " + "converted to UTF-32\n"); + goto SKIP_DATA; + + case -2: + fprintf(outfile, "**Failed: character value greater than 0x10ffff " + "cannot be converted to UTF-32\n"); + goto SKIP_DATA; + + case -3: + fprintf(outfile, "**Failed: character value is ill-formed UTF-32\n"); + goto SKIP_DATA; + + default: + break; + } + p = (pcre_uint8 *)buffer32; + } +#endif + + /* Compile many times when timing */ + + if (timeit > 0) + { + register int i; + clock_t time_taken; + clock_t start_time = clock(); + for (i = 0; i < timeit; i++) + { + PCRE_COMPILE(re, p, options, &error, &erroroffset, tables); + if (re != NULL) free(re); + } + time_taken = clock() - start_time; + fprintf(outfile, "Compile time %.4f milliseconds\n", + (((double)time_taken * 1000.0) / (double)timeit) / + (double)CLOCKS_PER_SEC); + } + + 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. */ + + if (re == NULL) + { + fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset); + SKIP_DATA: + if (infile != stdin) + { + for (;;) + { + if (extend_inputline(infile, buffer, NULL) == NULL) + { + done = 1; + goto CONTINUE; + } + len = (int)strlen((char *)buffer); + while (len > 0 && isspace(buffer[len-1])) len--; + if (len == 0) break; + } + fprintf(outfile, "\n"); + } + goto CONTINUE; + } + + /* Compilation succeeded. It is now possible to set the UTF-8 option from + within the regex; check for this so that we know how to process the data + lines. */ + + 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_SIZE(re); + regex_gotten_store = first_gotten_store; + + /* Output code size information if requested */ + + if (log_store) + { + int name_count, name_entry_size, real_pcre_size; + + new_info(re, NULL, PCRE_INFO_NAMECOUNT, &name_count); + new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &name_entry_size); + real_pcre_size = 0; +#ifdef SUPPORT_PCRE8 + if (REAL_PCRE_FLAGS(re) & PCRE_MODE8) + real_pcre_size = sizeof(real_pcre); +#endif +#ifdef SUPPORT_PCRE16 + if (REAL_PCRE_FLAGS(re) & PCRE_MODE16) + real_pcre_size = sizeof(real_pcre16); +#endif +#ifdef SUPPORT_PCRE32 + if (REAL_PCRE_FLAGS(re) & PCRE_MODE32) + real_pcre_size = sizeof(real_pcre32); +#endif + fprintf(outfile, "Memory allocation (code space): %d\n", + (int)(first_gotten_store - real_pcre_size - name_count * 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 || (force_study >= 0 && !no_force_study)) + { + if (timeit > 0) + { + register int i; + clock_t time_taken; + clock_t start_time = clock(); + for (i = 0; i < timeit; i++) + { + PCRE_STUDY(extra, re, study_options, &error); + } + time_taken = clock() - start_time; + 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); + } + PCRE_STUDY(extra, re, 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. */ + + if (do_mark) + { + if (extra == NULL) + { + extra = (pcre_extra *)malloc(sizeof(pcre_extra)); + extra->flags = 0; + } + extra->mark = &markptr; + extra->flags |= PCRE_EXTRA_MARK; + } + + /* Extract and display information from the compiled data if required. */ + + SHOW_INFO: + + if (do_debug) + { + fprintf(outfile, "------------------------------------------------------------------\n"); + PCRE_PRINTINT(re, outfile, debug_lengths); + } + + /* We already have the options in get_options (see above) */ + + if (do_showinfo) + { + unsigned long int all_options; + pcre_uint32 first_char, need_char; + int count, backrefmax, first_char_set, need_char_set, okpartial, jchanged, + hascrorlf, maxlookbehind; + int nameentrysize, namecount; + const pcre_uint8 *nametable; + + 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_FIRSTCHARACTER, &first_char) + + new_info(re, NULL, PCRE_INFO_FIRSTCHARACTERFLAGS, &first_char_set) + + new_info(re, NULL, PCRE_INFO_REQUIREDCHAR, &need_char) + + new_info(re, NULL, PCRE_INFO_REQUIREDCHARFLAGS, &need_char_set) + + 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", + (int)size, (int)regex_gotten_store); + + fprintf(outfile, "Capturing subpattern count = %d\n", count); + if (backrefmax > 0) + fprintf(outfile, "Max back reference = %d\n", backrefmax); + + if (namecount > 0) + { + fprintf(outfile, "Named capturing subpatterns:\n"); + while (namecount-- > 0) + { + int imm2_size = pcre_mode == PCRE8_MODE ? 2 : 1; + int length = (int)STRLEN(nametable + imm2_size); + fprintf(outfile, " "); + PCHARSV(nametable, imm2_size, length, outfile); + while (length++ < nameentrysize - imm2_size) putc(' ', outfile); +#ifdef SUPPORT_PCRE32 + if (pcre_mode == PCRE32_MODE) + fprintf(outfile, "%3d\n", (int)(((PCRE_SPTR32)nametable)[0])); +#endif +#ifdef SUPPORT_PCRE16 + if (pcre_mode == PCRE16_MODE) + fprintf(outfile, "%3d\n", (int)(((PCRE_SPTR16)nametable)[0])); +#endif +#ifdef SUPPORT_PCRE8 + if (pcre_mode == PCRE8_MODE) + fprintf(outfile, "%3d\n", ((int)nametable[0] << 8) | (int)nametable[1]); +#endif + nametable += nameentrysize * CHAR_SIZE; + } + } + + if (!okpartial) fprintf(outfile, "Partial matching not supported\n"); + if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n"); + + all_options = REAL_PCRE_OPTIONS(re); + 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", + ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", + ((get_options & PCRE_CASELESS) != 0)? " caseless" : "", + ((get_options & PCRE_EXTENDED) != 0)? " extended" : "", + ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "", + ((get_options & PCRE_FIRSTLINE) != 0)? " firstline" : "", + ((get_options & PCRE_DOTALL) != 0)? " dotall" : "", + ((get_options & PCRE_BSR_ANYCRLF) != 0)? " bsr_anycrlf" : "", + ((get_options & PCRE_BSR_UNICODE) != 0)? " bsr_unicode" : "", + ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", + ((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)? " utf" : "", + ((get_options & PCRE_UCP) != 0)? " ucp" : "", + ((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" : ""); + + if (jchanged) fprintf(outfile, "Duplicate name status changes\n"); + + switch (get_options & PCRE_NEWLINE_BITS) + { + case PCRE_NEWLINE_CR: + fprintf(outfile, "Forced newline sequence: CR\n"); + break; + + case PCRE_NEWLINE_LF: + fprintf(outfile, "Forced newline sequence: LF\n"); + break; + + case PCRE_NEWLINE_CRLF: + fprintf(outfile, "Forced newline sequence: CRLF\n"); + break; + + case PCRE_NEWLINE_ANYCRLF: + fprintf(outfile, "Forced newline sequence: ANYCRLF\n"); + break; + + case PCRE_NEWLINE_ANY: + fprintf(outfile, "Forced newline sequence: ANY\n"); + break; + + default: + break; + } + + if (first_char_set == 2) + { + fprintf(outfile, "First char at start or follows newline\n"); + } + else if (first_char_set == 1) + { + const char *caseless = + ((REAL_PCRE_FLAGS(re) & PCRE_FCH_CASELESS) == 0)? + "" : " (caseless)"; + + if (PRINTOK(first_char)) + fprintf(outfile, "First char = \'%c\'%s\n", first_char, caseless); + else + { + fprintf(outfile, "First char = "); + pchar(first_char, outfile); + fprintf(outfile, "%s\n", caseless); + } + } + else + { + fprintf(outfile, "No first char\n"); + } + + if (need_char_set == 0) + { + fprintf(outfile, "No need char\n"); + } + else + { + const char *caseless = + ((REAL_PCRE_FLAGS(re) & PCRE_RCH_CASELESS) == 0)? + "" : " (caseless)"; + + if (PRINTOK(need_char)) + fprintf(outfile, "Need char = \'%c\'%s\n", need_char, caseless); + else + { + 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.) 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 || (force_study >= 0 && showinfo && !no_force_study)) + { + if (extra == NULL) + fprintf(outfile, "Study returned NULL\n"); + else + { + pcre_uint8 *start_bits = NULL; + int minlength; + + if (new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength) == 0) + fprintf(outfile, "Subject length lower bound = %d\n", minlength); + + if (new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits) == 0) + { + if (start_bits == NULL) + fprintf(outfile, "No set of starting bytes\n"); + else + { + int i; + int c = 24; + fprintf(outfile, "Starting byte set: "); + for (i = 0; i < 256; i++) + { + if ((start_bits[i/8] & (1<<(i&7))) != 0) + { + 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"); + } + } + } + + /* Show this only if the JIT was set by /S, not by -s. */ + + if ((study_options & PCRE_STUDY_ALLJIT) != 0 && + (force_study_options & PCRE_STUDY_ALLJIT) == 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 + } + } + } + } + + /* If the '>' option was present, we write out the regex to a file, and + that is all. The first 8 bytes of the file are the regex length and then + the study length, in big-endian order. */ + + if (to_file != NULL) + { + FILE *f = fopen((char *)to_file, "wb"); + if (f == NULL) + { + fprintf(outfile, "Unable to open %s: %s\n", to_file, strerror(errno)); + } + else + { + 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) + { + fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno)); + } + else + { + 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) < + true_study_size) + { + fprintf(outfile, "Write error on %s: %s\n", to_file, + strerror(errno)); + } + else fprintf(outfile, "Study data written to %s\n", to_file); + } + } + fclose(f); + } + + new_free(re); + if (extra != NULL) + { + PCRE_FREE_STUDY(extra); + } + if (locale_set) + { + new_free((void *)tables); + setlocale(LC_CTYPE, "C"); + locale_set = 0; + } + continue; /* With next regex */ + } + } /* End of non-POSIX compile */ + + /* Read data lines and test them */ + + for (;;) + { +#ifdef SUPPORT_PCRE8 + pcre_uint8 *q8; +#endif +#ifdef SUPPORT_PCRE16 + pcre_uint16 *q16; +#endif +#ifdef SUPPORT_PCRE32 + pcre_uint32 *q32; +#endif + pcre_uint8 *bptr; + int *use_offsets = offsets; + int use_size_offsets = size_offsets; + int callout_data = 0; + int callout_data_set = 0; + int count; + pcre_uint32 c; + int copystrings = 0; + int find_match_limit = default_find_match_limit; + int getstrings = 0; + int getlist = 0; + int gmatched = 0; + int start_offset = 0; + int start_offset_sign = 1; + int g_notempty = 0; + int use_dfa = 0; + + *copynames = 0; + *getnames = 0; + +#ifdef SUPPORT_PCRE32 + cn32ptr = copynames; + gn32ptr = getnames; +#endif +#ifdef SUPPORT_PCRE16 + cn16ptr = copynames16; + gn16ptr = getnames16; +#endif +#ifdef SUPPORT_PCRE8 + cn8ptr = copynames8; + gn8ptr = getnames8; +#endif + + 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); + + len = 0; + for (;;) + { + if (extend_inputline(infile, buffer + len, "data> ") == NULL) + { + if (len > 0) /* Reached EOF without hitting a newline */ + { + fprintf(outfile, "\n"); + break; + } + done = 1; + goto CONTINUE; + } + if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); + len = (int)strlen((char *)buffer); + if (buffer[len-1] == '\n') break; + } + + while (len > 0 && isspace(buffer[len-1])) len--; + buffer[len] = 0; + if (len == 0) break; + + p = buffer; + while (isspace(*p)) p++; + +#ifndef NOUTF + /* Check that the data is well-formed UTF-8 if we're in UTF mode. To create + invalid input to pcre_exec, you must use \x?? or \x{} sequences. */ + if (use_utf) + { + pcre_uint8 *q; + pcre_uint32 cc; + int n = 1; + + for (q = p; n > 0 && *q; q += n) n = utf82ord(q, &cc); + if (n <= 0) + { + fprintf(outfile, "**Failed: invalid UTF-8 string cannot be used as input in UTF mode\n"); + goto NEXT_DATA; + } + } +#endif + +#ifdef SUPPORT_VALGRIND + /* Mark the dbuffer as addressable but undefined again. */ + if (dbuffer != NULL) + { + VALGRIND_MAKE_MEM_UNDEFINED(dbuffer, dbuffer_size * CHAR_SIZE); + } +#endif + + /* Allocate a buffer to hold the data line. len+1 is an upper bound on + the number of pcre_uchar units that will be needed. */ + if (dbuffer == NULL || (size_t)len >= dbuffer_size) + { + dbuffer_size *= 2; + dbuffer = (pcre_uint8 *)realloc(dbuffer, dbuffer_size * CHAR_SIZE); + if (dbuffer == NULL) + { + fprintf(stderr, "pcretest: malloc(%d) failed\n", (int)dbuffer_size); + exit(1); + } + } + +#ifdef SUPPORT_PCRE8 + q8 = (pcre_uint8 *) dbuffer; +#endif +#ifdef SUPPORT_PCRE16 + q16 = (pcre_uint16 *) dbuffer; +#endif +#ifdef SUPPORT_PCRE32 + q32 = (pcre_uint32 *) dbuffer; +#endif + + while ((c = *p++) != 0) + { + int i = 0; + int n = 0; + + /* 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 or 32-bit mode. */ + + if (c != '\\') + { +#ifndef NOUTF + if (use_utf && HASUTF8EXTRALEN(c)) { GETUTF8INC(c, p); } +#endif + } + + /* Handle backslash escapes */ + + else switch ((c = *p++)) + { + case 'a': c = 7; break; + case 'b': c = '\b'; break; + case 'e': c = 27; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c -= '0'; + while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') + c = c * 8 + *p++ - '0'; + break; + + case 'x': + if (*p == '{') + { + pcre_uint8 *pt = p; + c = 0; + + /* 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 == '}') + { + p = pt + 1; + break; + } + /* Not correct form for \x{...}; fall through */ + } + + /* \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/32-bit mode. */ + + c = 0; + while (i++ < 2 && isxdigit(*p)) + { + c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'a' - 10); + p++; + } +#if !defined NOUTF && defined SUPPORT_PCRE8 + if (use_utf && (pcre_mode == PCRE8_MODE)) + { + *q8++ = c; + continue; + } +#endif + break; + + case 0: /* \ followed by EOF allows for an empty line */ + p--; + continue; + + case '>': + if (*p == '-') + { + start_offset_sign = -1; + p++; + } + while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0'; + start_offset *= start_offset_sign; + continue; + + case 'A': /* Option setting */ + options |= PCRE_ANCHORED; + continue; + + case 'B': + options |= PCRE_NOTBOL; + continue; + + case 'C': + if (isdigit(*p)) /* Set copy string */ + { + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + copystrings |= 1 << n; + } + else if (isalnum(*p)) + { + READ_CAPTURE_NAME(p, &cn8ptr, &cn16ptr, &cn32ptr, re); + } + else if (*p == '+') + { + callout_extra = 1; + p++; + } + else if (*p == '-') + { + SET_PCRE_CALLOUT(NULL); + p++; + } + else if (*p == '!') + { + callout_fail_id = 0; + p++; + while(isdigit(*p)) + callout_fail_id = callout_fail_id * 10 + *p++ - '0'; + callout_fail_count = 0; + if (*p == '!') + { + p++; + while(isdigit(*p)) + callout_fail_count = callout_fail_count * 10 + *p++ - '0'; + } + } + else if (*p == '*') + { + int sign = 1; + callout_data = 0; + if (*(++p) == '-') { sign = -1; p++; } + while(isdigit(*p)) + callout_data = callout_data * 10 + *p++ - '0'; + callout_data *= sign; + callout_data_set = 1; + } + continue; + +#if !defined NODFA + case 'D': +#if !defined NOPOSIX + if (posix || do_posix) + printf("** Can't use dfa matching in POSIX mode: \\D ignored\n"); + else +#endif + use_dfa = 1; + continue; +#endif + +#if !defined NODFA + case 'F': + options |= PCRE_DFA_SHORTEST; + continue; +#endif + + case 'G': + if (isdigit(*p)) + { + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + getstrings |= 1 << n; + } + else if (isalnum(*p)) + { + READ_CAPTURE_NAME(p, &gn8ptr, &gn16ptr, &gn32ptr, 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; + + case 'L': + getlist = 1; + continue; + + case 'M': + find_match_limit = 1; + continue; + + case 'N': + if ((options & PCRE_NOTEMPTY) != 0) + options = (options & ~PCRE_NOTEMPTY) | PCRE_NOTEMPTY_ATSTART; + else + options |= PCRE_NOTEMPTY; + continue; + + case 'O': + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + if (n > size_offsets_max) + { + size_offsets_max = n; + free(offsets); + use_offsets = offsets = (int *)malloc(size_offsets_max * sizeof(int)); + if (offsets == NULL) + { + printf("** Failed to get %d bytes of memory for offsets vector\n", + (int)(size_offsets_max * sizeof(int))); + yield = 1; + goto EXIT; + } + } + 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': + options |= ((options & PCRE_PARTIAL_SOFT) == 0)? + PCRE_PARTIAL_SOFT : PCRE_PARTIAL_HARD; + continue; + + case 'Q': + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + if (extra == NULL) + { + extra = (pcre_extra *)malloc(sizeof(pcre_extra)); + extra->flags = 0; + } + extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; + extra->match_limit_recursion = n; + continue; + + case 'q': + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + if (extra == NULL) + { + extra = (pcre_extra *)malloc(sizeof(pcre_extra)); + extra->flags = 0; + } + extra->flags |= PCRE_EXTRA_MATCH_LIMIT; + extra->match_limit = n; + continue; + +#if !defined NODFA + case 'R': + options |= PCRE_DFA_RESTART; + continue; +#endif + + case 'S': + show_malloc = 1; + continue; + + case 'Y': + options |= PCRE_NO_START_OPTIMIZE; + continue; + + case 'Z': + options |= PCRE_NOTEOL; + continue; + + case '?': + options |= PCRE_NO_UTF8_CHECK; + continue; + + case '<': + { + int x = check_newline(p, outfile); + if (x == 0) goto NEXT_DATA; + options |= x; + while (*p++ != '>'); + } + continue; + } + + /* We now have a character value in c that may be greater than 255. + 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. */ + +#ifdef SUPPORT_PCRE8 + if (pcre_mode == PCRE8_MODE) + { +#ifndef NOUTF + if (use_utf) + { + if (c > 0x7fffffff) + { + fprintf(outfile, "** Character \\x{%x} is greater than 0x7fffffff " + "and so cannot be converted to UTF-8\n", c); + goto NEXT_DATA; + } + q8 += ord2utf8(c, q8); + } + else +#endif + { + if (c > 0xffu) + { + 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"); + } + *q8++ = c; + } + } +#endif +#ifdef SUPPORT_PCRE16 + if (pcre_mode == PCRE16_MODE) + { +#ifndef NOUTF + if (use_utf) + { + if (c > 0x10ffffu) + { + fprintf(outfile, "** Failed: character \\x{%x} is greater than " + "0x10ffff and so cannot be converted to UTF-16\n", c); + goto NEXT_DATA; + } + else if (c >= 0x10000u) + { + c-= 0x10000u; + *q16++ = 0xD800 | (c >> 10); + *q16++ = 0xDC00 | (c & 0x3ff); + } + else + *q16++ = c; + } + else +#endif + { + if (c > 0xffffu) + { + fprintf(outfile, "** Character \\x{%x} is greater than 0xffff " + "and UTF-16 mode is not enabled.\n", c); + fprintf(outfile, "** Truncation will probably give the wrong " + "result.\n"); + } + + *q16++ = c; + } + } +#endif +#ifdef SUPPORT_PCRE32 + if (pcre_mode == PCRE32_MODE) + { + *q32++ = c; + } +#endif + + } + + /* Reached end of subject string */ + +#ifdef SUPPORT_PCRE8 + if (pcre_mode == PCRE8_MODE) + { + *q8 = 0; + len = (int)(q8 - (pcre_uint8 *)dbuffer); + } +#endif +#ifdef SUPPORT_PCRE16 + if (pcre_mode == PCRE16_MODE) + { + *q16 = 0; + len = (int)(q16 - (pcre_uint16 *)dbuffer); + } +#endif +#ifdef SUPPORT_PCRE32 + if (pcre_mode == PCRE32_MODE) + { + *q32 = 0; + len = (int)(q32 - (pcre_uint32 *)dbuffer); + } +#endif + + /* If we're compiling with explicit valgrind support, Mark the data from after + its end to the end of the buffer as unaddressable, so that a read over the end + of the buffer will be seen by valgrind, even if it doesn't cause a crash. + If we're not building with valgrind support, at least move the data to the end + of the buffer so that it might at least cause a crash. + If we are using the POSIX interface, we must include the terminating zero. */ + + bptr = dbuffer; + +#if !defined NOPOSIX + if (posix || do_posix) + { +#ifdef SUPPORT_VALGRIND + VALGRIND_MAKE_MEM_NOACCESS(dbuffer + len + 1, dbuffer_size - (len + 1)); +#else + memmove(bptr + dbuffer_size - len - 1, bptr, len + 1); + bptr += dbuffer_size - len - 1; +#endif + } + else +#endif + { +#ifdef SUPPORT_VALGRIND + VALGRIND_MAKE_MEM_NOACCESS(dbuffer + len * CHAR_SIZE, (dbuffer_size - len) * CHAR_SIZE); +#else + bptr = memmove(bptr + (dbuffer_size - len) * CHAR_SIZE, bptr, len * CHAR_SIZE); +#endif + } + + if ((all_use_dfa || use_dfa) && find_match_limit) + { + printf("**Match limit not relevant for DFA matching: ignored\n"); + find_match_limit = 0; + } + + /* Handle matching via the POSIX interface, which does not + support timing or playing with the match limit or callout data. */ + +#if !defined NOPOSIX + if (posix || do_posix) + { + int rc; + int eflags = 0; + regmatch_t *pmatch = NULL; + if (use_size_offsets > 0) + pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets); + if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; + if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; + if ((options & PCRE_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY; + + rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags); + + if (rc != 0) + { + (void)regerror(rc, &preg, (char *)buffer, buffer_size); + fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); + } + else if ((REAL_PCRE_OPTIONS(preg.re_pcre) & PCRE_NO_AUTO_CAPTURE) != 0) + { + fprintf(outfile, "Matched with REG_NOSUB\n"); + } + else + { + size_t i; + for (i = 0; i < (size_t)use_size_offsets; i++) + { + if (pmatch[i].rm_so >= 0) + { + fprintf(outfile, "%2d: ", (int)i); + PCHARSV(dbuffer, pmatch[i].rm_so, + pmatch[i].rm_eo - pmatch[i].rm_so, outfile); + fprintf(outfile, "\n"); + if (do_showcaprest || (i == 0 && do_showrest)) + { + fprintf(outfile, "%2d+ ", (int)i); + PCHARSV(dbuffer, pmatch[i].rm_eo, len - pmatch[i].rm_eo, + outfile); + fprintf(outfile, "\n"); + } + } + } + } + free(pmatch); + goto NEXT_DATA; + } + +#endif /* !defined NOPOSIX */ + + /* Handle matching via the native interface - repeats for /g and /G */ + + /* 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) + { + register int i; + clock_t time_taken; + clock_t start_time = clock(); + +#if !defined NODFA + if (all_use_dfa || use_dfa) + { + 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++) + { + 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++) + { + 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) / + (double)CLOCKS_PER_SEC); + } + + /* 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. 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) + { + if (extra != NULL) { PCRE_FREE_STUDY(extra); } + extra = (pcre_extra *)malloc(sizeof(pcre_extra)); + extra->flags = 0; + + (void)check_match_limit(re, extra, bptr, len, start_offset, + options|g_notempty, use_offsets, use_size_offsets, + PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit), + PCRE_ERROR_MATCHLIMIT, "match()"); + + count = check_match_limit(re, extra, bptr, len, start_offset, + options|g_notempty, use_offsets, use_size_offsets, + PCRE_EXTRA_MATCH_LIMIT_RECURSION, &(extra->match_limit_recursion), + PCRE_ERROR_RECURSIONLIMIT, "match() recursion"); + } + + /* If callout_data is set, use the interface with additional data */ + + else if (callout_data_set) + { + if (extra == NULL) + { + extra = (pcre_extra *)malloc(sizeof(pcre_extra)); + extra->flags = 0; + } + extra->flags |= PCRE_EXTRA_CALLOUT_DATA; + extra->callout_data = &callout_data; + PCRE_EXEC(count, re, extra, bptr, len, start_offset, + options | g_notempty, use_offsets, use_size_offsets); + extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA; + } + + /* The normal case is just to do the match once, with the default + value of match_limit. */ + +#if !defined NODFA + else if (all_use_dfa || use_dfa) + { + 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"); + count = use_size_offsets/2; + } + } +#endif + + else + { + 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"); + count = use_size_offsets/3; + } + } + + /* Matched */ + + if (count >= 0) + { + int i, maxcount; + void *cnptr, *gnptr; + +#if !defined NODFA + if (all_use_dfa || use_dfa) maxcount = use_size_offsets/2; else +#endif + maxcount = use_size_offsets/3; + + /* This is a check against a lunatic return value. */ + + if (count > maxcount) + { + fprintf(outfile, + "** PCRE error: returned count %d is too big for offset size %d\n", + count, use_size_offsets); + count = use_size_offsets/3; + if (do_g || do_G) + { + fprintf(outfile, "** /%c loop abandoned\n", do_g? 'g' : 'G'); + do_g = do_G = FALSE; /* Break g/G loop */ + } + } + + /* 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); + 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 (do_showcaprest || (i == 0 && do_showrest)) + { + 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: "); + PCHARSV(markptr, 0, -1, outfile); + fprintf(outfile, "\n"); + } + + for (i = 0; i < 32; i++) + { + if ((copystrings & (1 << i)) != 0) + { + int rc; + char copybuffer[256]; + 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 ", i); + PCHARSV(copybuffer, 0, rc, outfile); + fprintf(outfile, " (%d)\n", rc); + } + } + } + + cnptr = copynames; + for (;;) + { + int rc; + char copybuffer[256]; + +#ifdef SUPPORT_PCRE32 + if (pcre_mode == PCRE32_MODE) + { + if (*(pcre_uint32 *)cnptr == 0) break; + } +#endif +#ifdef SUPPORT_PCRE16 + if (pcre_mode == PCRE16_MODE) + { + if (*(pcre_uint16 *)cnptr == 0) break; + } +#endif +#ifdef SUPPORT_PCRE8 + if (pcre_mode == PCRE8_MODE) + { + if (*(pcre_uint8 *)cnptr == 0) break; + } +#endif + + PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, use_offsets, count, + cnptr, copybuffer, sizeof(copybuffer)); + + if (rc < 0) + { + fprintf(outfile, "copy substring "); + PCHARSV(cnptr, 0, -1, outfile); + fprintf(outfile, " failed %d\n", rc); + } + else + { + 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; + 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 ", i); + PCHARSV(substring, 0, rc, outfile); + fprintf(outfile, " (%d)\n", rc); + PCRE_FREE_SUBSTRING(substring); + } + } + } + + gnptr = getnames; + for (;;) + { + int rc; + const char *substring; + +#ifdef SUPPORT_PCRE32 + if (pcre_mode == PCRE32_MODE) + { + if (*(pcre_uint32 *)gnptr == 0) break; + } +#endif +#ifdef SUPPORT_PCRE16 + if (pcre_mode == PCRE16_MODE) + { + if (*(pcre_uint16 *)gnptr == 0) break; + } +#endif +#ifdef SUPPORT_PCRE8 + if (pcre_mode == PCRE8_MODE) + { + if (*(pcre_uint8 *)gnptr == 0) break; + } +#endif + + PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, use_offsets, count, + gnptr, &substring); + if (rc < 0) + { + fprintf(outfile, "get substring "); + PCHARSV(gnptr, 0, -1, outfile); + fprintf(outfile, " failed %d\n", rc); + } + else + { + 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; + 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 ", i); + PCHARSV(stringlist[i], 0, -1, outfile); + putc('\n', outfile); + } + if (stringlist[i] != NULL) + fprintf(outfile, "string list not terminated by NULL\n"); + PCRE_FREE_SUBSTRING_LIST(stringlist); + } + } + } + + /* There was a partial match */ + + else if (count == PCRE_ERROR_PARTIAL) + { + if (markptr == NULL) fprintf(outfile, "Partial match"); + else + { + fprintf(outfile, "Partial match, mark="); + PCHARSV(markptr, 0, -1, outfile); + } + if (use_size_offsets > 1) + { + fprintf(outfile, ": "); + 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 */ + } + + /* Failed to match. If this is a /g or /G loop and we previously set + g_notempty after a null match, this is not necessarily the end. We want + to advance the start offset, and continue. We won't be at the end of the + string - that was checked before setting g_notempty. + + Complication arises in the case when the newline convention is "any", + "crlf", or "anycrlf". If the previous match was at the end of a line + 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 + find the default. + + Otherwise, in the case of UTF-8 matching, the advance must be one + character, not one byte. */ + + else + { + if (g_notempty != 0) + { + int onechar = 1; + unsigned int obits = REAL_PCRE_OPTIONS(re); + use_offsets[0] = start_offset; + if ((obits & PCRE_NEWLINE_BITS) == 0) + { + int 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 : + (d == 10)? PCRE_NEWLINE_LF : + (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF : + (d == -2)? PCRE_NEWLINE_ANYCRLF : + (d == -1)? PCRE_NEWLINE_ANY : 0; + } + if (((obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANY || + (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_CRLF || + (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANYCRLF) + && + start_offset < len - 1 && ( +#ifdef SUPPORT_PCRE8 + (pcre_mode == PCRE8_MODE && + bptr[start_offset] == '\r' && + bptr[start_offset + 1] == '\n') || +#endif +#ifdef SUPPORT_PCRE16 + (pcre_mode == PCRE16_MODE && + ((PCRE_SPTR16)bptr)[start_offset] == '\r' && + ((PCRE_SPTR16)bptr)[start_offset + 1] == '\n') || +#endif +#ifdef SUPPORT_PCRE32 + (pcre_mode == PCRE32_MODE && + ((PCRE_SPTR32)bptr)[start_offset] == '\r' && + ((PCRE_SPTR32)bptr)[start_offset + 1] == '\n') || +#endif + 0)) + onechar++; + else if (use_utf) + { + while (start_offset + onechar < len) + { + if ((bptr[start_offset+onechar] & 0xc0) != 0x80) break; + onechar++; + } + } + use_offsets[1] = start_offset + onechar; + } + else + { + switch(count) + { + case PCRE_ERROR_NOMATCH: + if (gmatched == 0) + { + 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-%d string)", count, + (count == PCRE_ERROR_BADUTF8)? "bad" : "short", + 8 * CHAR_SIZE); + 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-%d offset)\n", count, + 8 * CHAR_SIZE); + 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; + } + + break; /* Out of the /g loop */ + } + } + + /* If not /g or /G we are done */ + + if (!do_g && !do_G) break; + + /* If we have matched an empty string, first check to see if we are at + the end of the subject. If so, the /g loop is over. Otherwise, mimic what + Perl's /g options does. This turns out to be rather cunning. First we set + PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED and try the match again at the + same point. If this fails (picked up above) we advance to the next + character. */ + + g_notempty = 0; + + if (use_offsets[0] == use_offsets[1]) + { + if (use_offsets[0] == len) break; + g_notempty = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED; + } + + /* For /g, update the start offset, leaving the rest alone */ + + if (do_g) start_offset = use_offsets[1]; + + /* For /G, update the pointer and length */ + + else + { + bptr += use_offsets[1] * CHAR_SIZE; + len -= use_offsets[1]; + } + } /* End of loop for /g and /G */ + + NEXT_DATA: continue; + } /* End of loop for data lines */ + + CONTINUE: + +#if !defined NOPOSIX + if (posix || do_posix) regfree(&preg); +#endif + + if (re != NULL) new_free(re); + 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"); + +EXIT: + +if (infile != NULL && infile != stdin) fclose(infile); +if (outfile != NULL && outfile != stdout) fclose(outfile); + +free(buffer); +free(dbuffer); +free(pbuffer); +free(offsets); + +#ifdef SUPPORT_PCRE16 +if (buffer16 != NULL) free(buffer16); +#endif +#ifdef SUPPORT_PCRE32 +if (buffer32 != NULL) free(buffer32); +#endif + +#if !defined NODFA +if (dfa_workspace != NULL) + free(dfa_workspace); +#endif + +return yield; +} + +/* End of pcretest.c */ diff --git a/tools/pcre/perltest.pl b/tools/pcre/perltest.pl new file mode 100644 index 00000000..80ab1b8b --- /dev/null +++ b/tools/pcre/perltest.pl @@ -0,0 +1,237 @@ +#! /usr/bin/env perl + +# Program for testing regular expressions with perl to check that PCRE handles +# 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. + +#use utf8; +#require Encode; + +sub pchars { +my($t) = ""; + +if ($utf8) + { + @p = unpack('U*', $_[0]); + foreach $c (@p) + { + if ($c >= 32 && $c < 127) { $t .= chr $c; } + else { $t .= sprintf("\\x{%02x}", $c); + } + } + } +else + { + foreach $c (split(//, $_[0])) + { + if (ord $c >= 32 && ord $c < 127) { $t .= $c; } + else { $t .= sprintf("\\x%02x", ord $c); } + } + } + +$t; +} + + +# Read lines from named file or stdin and write to named file or stdout; lines +# consist of a regular expression, in delimiters and optionally followed by +# options, followed by a set of test data, terminated by an empty line. + +# Sort out the input and output files + +if (@ARGV > 0) + { + open(INFILE, "<$ARGV[0]") || die "Failed to open $ARGV[0]\n"; + $infile = "INFILE"; + } +else { $infile = "STDIN"; } + +if (@ARGV > 1) + { + open(OUTFILE, ">$ARGV[1]") || die "Failed to open $ARGV[1]\n"; + $outfile = "OUTFILE"; + } +else { $outfile = "STDOUT"; } + +printf($outfile "Perl $] Regular Expressions\n\n"); + +# Main loop + +NEXT_RE: +for (;;) + { + printf " re> " if $infile eq "STDIN"; + last if ! ($_ = <$infile>); + printf $outfile "$_" if $infile ne "STDIN"; + next if ($_ eq ""); + + $pattern = $_; + + while ($pattern !~ /^\s*(.).*\1/s) + { + printf " > " if $infile eq "STDIN"; + last if ! ($_ = <$infile>); + printf $outfile "$_" if $infile ne "STDIN"; + $pattern .= $_; + } + + chomp($pattern); + $pattern =~ s/\s+$//; + + # The private /+ modifier means "print $' afterwards". + + $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]*$)//; + + # Remove /J from a pattern with duplicate names. + + $pattern =~ s/J(?=[a-zA-Z]*$)//; + + # Remove /K from a pattern (asks pcretest to check MARK data) */ + + $pattern =~ s/K(?=[a-zA-Z]*$)//; + + # Remove /W from a pattern (asks pcretest to set PCRE_UCP) + + $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}"; + if ($@) + { + printf $outfile "Error: $@"; + next NEXT_RE; + } + + # If the /g modifier is present, we want to put a loop round the matching; + # otherwise just a single "if". + + $cmd = ($pattern =~ /g[a-z]*$/)? "while" : "if"; + + # If the pattern is actually the null string, Perl uses the most recently + # executed (and successfully compiled) regex is used instead. This is a + # nasty trap for the unwary! The PCRE test suite does contain null strings + # in places - if they are allowed through here all sorts of weird and + # unexpected effects happen. To avoid this, we replace such patterns with + # a non-null pattern that has the same effect. + + $pattern = "/(?#)/$2" if ($pattern =~ /^(.)\1(.*)$/); + + # Read data lines and test them + + for (;;) + { + printf "data> " if $infile eq "STDIN"; + last NEXT_RE if ! ($_ = <$infile>); + chomp; + printf $outfile "$_\n" if $infile ne "STDIN"; + + s/\s+$//; # Remove trailing space + s/^\s+//; # Remove leading space + s/\\Y//g; # Remove \Y (pcretest flag to set PCRE_NO_START_OPTIMIZE) + + last if ($_ eq ""); + $x = eval "\"$_\""; # To get escapes processed + + # Empty array for holding results, ensure $REGERROR and $REGMARK are + # unset, then do the matching. + + @subs = (); + + $pushes = "push \@subs,\$&;" . + "push \@subs,\$1;" . + "push \@subs,\$2;" . + "push \@subs,\$3;" . + "push \@subs,\$4;" . + "push \@subs,\$5;" . + "push \@subs,\$6;" . + "push \@subs,\$7;" . + "push \@subs,\$8;" . + "push \@subs,\$9;" . + "push \@subs,\$10;" . + "push \@subs,\$11;" . + "push \@subs,\$12;" . + "push \@subs,\$13;" . + "push \@subs,\$14;" . + "push \@subs,\$15;" . + "push \@subs,\$16;" . + "push \@subs,\$'; }"; + + undef $REGERROR; + undef $REGMARK; + + eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; + + if ($@) + { + printf $outfile "Error: $@\n"; + next NEXT_RE; + } + elsif (scalar(@subs) == 0) + { + printf $outfile "No match"; + if (defined $REGERROR && $REGERROR != 1) + { printf $outfile (", mark = %s", &pchars($REGERROR)); } + printf $outfile "\n"; + } + else + { + while (scalar(@subs) != 0) + { + printf $outfile (" 0: %s\n", &pchars($subs[0])); + printf $outfile (" 0+ %s\n", &pchars($subs[17])) if $showrest; + $last_printed = 0; + for ($i = 1; $i <= 16; $i++) + { + if (defined $subs[$i]) + { + while ($last_printed++ < $i-1) + { printf $outfile ("%2d: \n", $last_printed); } + printf $outfile ("%2d: %s\n", $i, &pchars($subs[$i])); + $last_printed = $i; + } + } + 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) + { + $xx = $REGMARK; + $xx = Encode::decode_utf8($xx) if $utf8; + printf $outfile ("MK: %s\n", &pchars($xx)); + } + } + } + } + +# printf $outfile "\n"; + +# End diff --git a/tools/pcre/sljit/sljitConfig.h b/tools/pcre/sljit/sljitConfig.h new file mode 100644 index 00000000..68bc59d0 --- /dev/null +++ b/tools/pcre/sljit/sljitConfig.h @@ -0,0 +1,110 @@ +/* + * 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_SPARC_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 --git a/tools/pcre/sljit/sljitConfigInternal.h b/tools/pcre/sljit/sljitConfigInternal.h new file mode 100644 index 00000000..2b6616ef --- /dev/null +++ b/tools/pcre/sljit/sljitConfigInternal.h @@ -0,0 +1,484 @@ +/* + * 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_sw/sljit_uw array by index + SLJIT_DOUBLE_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 + SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address + + Types and useful macros: + sljit_sb, sljit_ub : signed and unsigned 8 bit byte + sljit_sh, sljit_uh : signed and unsigned 16 bit half-word (short) type + sljit_si, sljit_ui : signed and unsigned 32 bit integer type + sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer + sljit_p : unsgined pointer value (usually the same as sljit_uw, but + some 64 bit ABIs may use 32 bit pointers) + sljit_s : single precision floating point value + sljit_d : double precision floating point value + 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_SPARC_32 && SLJIT_CONFIG_SPARC_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_SPARC_32 && SLJIT_CONFIG_SPARC_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__) || defined(_ARCH_PPC64) || (defined(_POWER) && defined(__64BIT__)) +#define SLJIT_CONFIG_PPC_64 1 +#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) +#define SLJIT_CONFIG_PPC_32 1 +#elif defined(__mips__) +#define SLJIT_CONFIG_MIPS_32 1 +#elif defined(__sparc__) || defined(__sparc) +#define SLJIT_CONFIG_SPARC_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)) + +#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + +/* The __clear_cache() implementation of GCC is a dummy function on Sparc. */ +#define SLJIT_CACHE_FLUSH(from, to) \ + sparc_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_sb; + +/* 16 bit half-word type. */ +typedef unsigned short int sljit_uh; +typedef signed short int sljit_sh; + +/* 32 bit integer type. */ +typedef unsigned int sljit_ui; +typedef signed int sljit_si; + +/* 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_sw; +#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_sw; +#else +#define SLJIT_64BIT_ARCHITECTURE 1 +#define SLJIT_WORD_SHIFT 3 +#ifdef _WIN32 +typedef unsigned __int64 sljit_uw; +typedef __int64 sljit_sw; +#else +typedef unsigned long int sljit_uw; +typedef long int sljit_sw; +#endif +#endif + +typedef sljit_uw sljit_p; + +/* Floating point types. */ +typedef float sljit_s; +typedef double sljit_d; + +/* Shift for pointer sized data. */ +#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT + +/* Shift for double precision sized data. */ +#define SLJIT_DOUBLE_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(_MSC_VER) + +#define SLJIT_CALL __fastcall +#define SLJIT_X86_32_FASTCALL 1 + +#elif defined(__BORLANDC__) + +#define SLJIT_CALL __msfastcall +#define SLJIT_X86_32_FASTCALL 1 + +#else /* Unknown compiler. */ + +/* The cdecl attribute is the default. */ +#define SLJIT_CALL + +#endif + +#else /* Non x86-32 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) \ + || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#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 + +#ifndef SLJIT_INDIRECT_CALL +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32 && defined _AIX) +/* It seems certain ppc compilers use an indirect addressing for functions + which makes things complicated. */ +#define SLJIT_INDIRECT_CALL 1 +#endif +#endif /* SLJIT_INDIRECT_CALL */ + +#ifndef SLJIT_RETURN_ADDRESS_OFFSET +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#define SLJIT_RETURN_ADDRESS_OFFSET 8 +#else +#define SLJIT_RETURN_ADDRESS_OFFSET 0 +#endif +#endif /* SLJIT_RETURN_ADDRESS_OFFSET */ + +#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_VERBOSE && SLJIT_VERBOSE) +#include +#endif + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + +#if !defined(SLJIT_ASSERT) || !defined(SLJIT_ASSERT_STOP) + +/* SLJIT_HALT_PROCESS must halt the process. */ +#ifndef SLJIT_HALT_PROCESS +#include + +#define SLJIT_HALT_PROCESS() \ + abort(); +#endif /* !SLJIT_HALT_PROCESS */ + +#include + +#endif /* !SLJIT_ASSERT || !SLJIT_ASSERT_STOP */ + +/* Feel free to redefine these two macros. */ +#ifndef SLJIT_ASSERT + +#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) */ + +/* Forcing empty, but valid statements. */ +#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 --git a/tools/pcre/sljit/sljitExecAllocator.c b/tools/pcre/sljit/sljitExecAllocator.c new file mode 100644 index 00000000..75a38991 --- /dev/null +++ b/tools/pcre/sljit/sljitExecAllocator.c @@ -0,0 +1,289 @@ +/* + * 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(NULL, 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 + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + void* retval; + +#ifdef MAP_ANON + retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); +#else + if (dev_zero < 0) { + if (open_dev_zero()) + return NULL; + } + retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0); +#endif + + 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); + if (!header) { + allocator_release_lock(); + return NULL; + } + + 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_sw)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_sw)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 --git a/tools/pcre/sljit/sljitLir.c b/tools/pcre/sljit/sljitLir.c new file mode 100644 index 00000000..69798410 --- /dev/null +++ b/tools/pcre/sljit/sljitLir.c @@ -0,0 +1,1766 @@ +/* + * 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_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) + +#define TYPE_CAST_NEEDED(op) \ + (((op) >= SLJIT_MOV_UB && (op) <= SLJIT_MOV_SH) || ((op) >= SLJIT_MOVU_UB && (op) <= SLJIT_MOVU_SH)) + +#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_COND 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 MOVABLE_INS 0 + /* 1 - 31 last destination register */ + /* no destination (i.e: store) */ +# define UNMOVABLE_INS 32 + /* FPU status register */ +# define FCSR_FCC 33 +#endif + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +# define IS_MOVABLE 0x04 +# define IS_COND 0x08 +# define IS_CALL 0x10 + +# define PATCH_B 0x20 +# define PATCH_CALL 0x40 + + /* instruction types */ +# define MOVABLE_INS 0 + /* 1 - 31 last destination register */ + /* no destination (i.e: store) */ +# define UNMOVABLE_INS 32 + +# define DST_INS_MASK 0xff + + /* ICC_SET is the same as SET_FLAGS. */ +# define ICC_IS_SET (1 << 23) +# define FCC_IS_SET (1 << 24) +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +#define SLJIT_HAS_VARIABLE_LOCALS_OFFSET 1 +#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) +#define FIXED_LOCALS_OFFSET (3 * sizeof(sljit_sw)) +#endif +#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 + 2) * sizeof(sljit_sw)) +#else +#define FIXED_LOCALS_OFFSET (sizeof(sljit_sw)) +#endif +#endif + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 +#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +#define FIXED_LOCALS_OFFSET ((6 + 8) * sizeof(sljit_sw)) +#else +#define FIXED_LOCALS_OFFSET (2 * sizeof(sljit_sw)) +#endif +#endif + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 +#define FIXED_LOCALS_OFFSET ((6 + 8) * sizeof(sljit_sw)) +#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_sw)) +#endif + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 +#define FIXED_LOCALS_OFFSET (23 * sizeof(sljit_sw)) +#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 sljit_si 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_sb) == 1 && sizeof(sljit_ub) == 1 + && sizeof(sljit_sh) == 2 && sizeof(sljit_uh) == 2 + && sizeof(sljit_si) == 4 && sizeof(sljit_ui) == 4 + && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8) + && sizeof(sljit_p) <= sizeof(sljit_sw) + && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8) + && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8), + invalid_integer_types); + SLJIT_COMPILE_ASSERT(SLJIT_INT_OP == SLJIT_SINGLE_OP, + int_op_and_single_op_must_be_the_same); + SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_SINGLE_OP, + rewritable_jump_and_single_op_must_not_be_the_same); + + /* 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->scratches = -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_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_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_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +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, sljit_uw size) +{ + sljit_ub *ret; + struct sljit_memory_fragment *new_frag; + + SLJIT_ASSERT(size <= 256); + if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) { + 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, sljit_uw size) +{ + sljit_ub *ret; + struct sljit_memory_fragment *new_frag; + + SLJIT_ASSERT(size <= 256); + if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) { + 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, sljit_si 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, sljit_si 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_CMPD: \ + SLJIT_ASSERT(!(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; \ + case SLJIT_BREAKPOINT: \ + case SLJIT_NOP: \ + case SLJIT_UMUL: \ + case SLJIT_SMUL: \ + case SLJIT_MOV: \ + case SLJIT_MOV_P: \ + case SLJIT_MOVU: \ + case SLJIT_MOVU_P: \ + /* 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; \ + default: \ + /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ + SLJIT_ASSERT(!(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_SCRATCH_REG1 && (r) <= SLJIT_SCRATCH_REG1 - 1 + compiler->scratches) || \ + ((r) >= SLJIT_SAVED_REG1 && (r) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds)) + +#define FUNCTION_CHECK_SRC(p, i) \ + SLJIT_ASSERT(compiler->scratches != -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->scratches != -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_REG6) \ + 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_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_P) { \ + 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", (char*)"float_r5", (char*)"float_r6" +}; + +#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*)"mov.p", + (char*)"movu", (char*)"movu.ub", (char*)"movu.sb", (char*)"movu.uh", + (char*)"movu.sh", (char*)"movu.ui", (char*)"movu.si", (char*)"movu.p", + (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*)"cmp", (char*)"mov", (char*)"neg", (char*)"abs", + /* fop2 */ + (char*)"add", (char*)"sub", (char*)"mul", (char*)"div" +}; + +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_unordered", (char*)"c_float_ordered", + (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, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(scratches); + SLJIT_UNUSED_ARG(saveds); + SLJIT_UNUSED_ARG(local_size); + + SLJIT_ASSERT(args >= 0 && args <= 3); + SLJIT_ASSERT(scratches >= 0 && scratches <= 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 scratches=%d saveds=%d local_size=%d\n", args, scratches, saveds, local_size); +#endif +} + +static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(scratches); + 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(scratches >= 0 && scratches <= 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 scratches=%d saveds=%d local_size=%d\n", args, scratches, saveds, local_size); +#endif +} + +static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw 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_P); + 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, sljit_si dst, sljit_sw 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, sljit_si src, sljit_sw 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, sljit_si 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, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw 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, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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(sljit_si 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, sljit_si 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, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw 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_CMPD && GET_OPCODE(op) <= SLJIT_ABSD); +#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%s ", op_names[GET_OPCODE(op)], (op & SLJIT_SINGLE_OP) ? "s" : "d", + !(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, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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_ADDD && GET_OPCODE(op) <= SLJIT_DIVD); +#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%s ", op_names[GET_OPCODE(op)], (op & SLJIT_SINGLE_OP) ? "s" : "d"); + 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, sljit_si 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, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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_REWRITABLE_JUMP | SLJIT_INT_OP))); + 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, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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_SINGLE_OP))); + SLJIT_ASSERT((type & 0xff) >= SLJIT_C_FLOAT_EQUAL && (type & 0xff) <= SLJIT_C_FLOAT_ORDERED); +#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, " %scmp%s<%s> ", (type & SLJIT_SINGLE_OP) ? "s" : "d", + !(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, sljit_si type, sljit_si src, sljit_sw 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); + +#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 >= 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_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si 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(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_UNUSED_ARG(type); + + SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP); + SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_UI || GET_OPCODE(op) == SLJIT_MOV_SI + || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); + SLJIT_ASSERT((op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C)) == 0); + SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS)); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + if (GET_OPCODE(op) < SLJIT_ADD) { + SLJIT_ASSERT(src == SLJIT_UNUSED && srcw == 0); + } else { + SLJIT_ASSERT(src == dst && srcw == dstw); + } + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " op_flags<%s%s%s%s> ", !(op & SLJIT_INT_OP) ? "" : "i", + op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + sljit_verbose_param(dst, dstw); + if (src != SLJIT_UNUSED) { + fprintf(compiler->verbose, ", "); + sljit_verbose_param(src, srcw); + } + fprintf(compiler->verbose, ", <%s>\n", jump_names[type]); + } +#endif +} + +static SLJIT_INLINE void check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw 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, sljit_si dst, sljit_sw dstw, sljit_sw 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 sljit_si emit_mov_before_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + /* Return if don't need to do anything. */ + if (op == SLJIT_UNUSED) + return SLJIT_SUCCESS; + +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) + /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */ + if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P)) + return SLJIT_SUCCESS; +#else + if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P)) + 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" +#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +# include "sljitNativeSPARC_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, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + /* Default compare for most architectures. */ + sljit_si flags, tmp_src, condition; + sljit_sw 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, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si flags, condition; + + check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w); + + condition = type & 0xff; + flags = (condition <= SLJIT_C_FLOAT_NOT_EQUAL) ? SLJIT_SET_E : SLJIT_SET_S; + if (type & SLJIT_SINGLE_OP) + flags |= SLJIT_SINGLE_OP; + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + sljit_emit_fop1(compiler, SLJIT_CMPD | 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 sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw 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(void) +{ + 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, sljit_si 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 sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(scratches); + 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, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(scratches); + SLJIT_UNUSED_ARG(saveds); + SLJIT_UNUSED_ARG(local_size); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw 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 sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw 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 sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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 sljit_si sljit_get_register_index(sljit_si reg) +{ + SLJIT_ASSERT_STOP(); + return reg; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(instruction); + SLJIT_UNUSED_ARG(size); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ + SLJIT_ASSERT_STOP(); + return 0; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw 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 sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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, sljit_si 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, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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 sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw 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 sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + 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_UNUSED_ARG(type); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw 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, sljit_si dst, sljit_sw dstw, sljit_sw 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_sw new_constant) +{ + SLJIT_UNUSED_ARG(addr); + SLJIT_UNUSED_ARG(new_constant); + SLJIT_ASSERT_STOP(); +} + +#endif diff --git a/tools/pcre/sljit/sljitLir.h b/tools/pcre/sljit/sljitLir.h new file mode 100644 index 00000000..3171d155 --- /dev/null +++ b/tools/pcre/sljit/sljitLir.h @@ -0,0 +1,985 @@ +/* + * 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, it is possible to jump to any label from anywhere, even from + a code fragment, which is compiled later, if both compiled code + shares the same context. See sljit_emit_enter for more details + - Supports self modifying code: target of (conditional) jump and call + instructions and some constant values can be dynamically modified + during runtime + - although it is not suggested to do it frequently + - can be used for inline caching: save an important value once + in the instruction stream + - since this feature limits the optimization possibilities, a + special flag must be passed at compile time when these + instructions are emitted + - 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: + - No automatic register allocation, and temporary results are + not stored on the stack. (hence the name comes) + - Limited number of registers (only 6+4 integer registers, max 3+2 + scratch, max 3+2 saved and 6 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 if it belongs + to another function) + - Hot 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 and context independent code (except some cases) + + 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 + +/* Scratch (temporary) registers whose may not preserve their values + across function calls. */ +#define SLJIT_SCRATCH_REG1 1 +#define SLJIT_SCRATCH_REG2 2 +#define SLJIT_SCRATCH_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 + on the stack. */ +#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_SCRATCH_REG1 + +/* x86 prefers specific registers for special purposes. In case of shift + by register it supports only SLJIT_SCRATCH_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_SCRATCH_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 or + single precision values. */ + +#define SLJIT_FLOAT_REG1 1 +#define SLJIT_FLOAT_REG2 2 +#define SLJIT_FLOAT_REG3 3 +#define SLJIT_FLOAT_REG4 4 +#define SLJIT_FLOAT_REG5 5 +#define SLJIT_FLOAT_REG6 6 + +/* --------------------------------------------------------------------- */ +/* Main structures and functions */ +/* --------------------------------------------------------------------- */ + +struct sljit_memory_fragment { + struct sljit_memory_fragment *next; + sljit_uw used_size; + /* Must be aligned to sljit_sw. */ + 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_sw flags; + union { + sljit_uw target; + struct sljit_label* label; + } u; +}; + +struct sljit_const { + struct sljit_const *next; + sljit_uw addr; +}; + +struct sljit_compiler { + sljit_si 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. */ + sljit_si scratches; + /* Used saved registers. */ + sljit_si saveds; + /* Local stack size. */ + sljit_si local_size; + /* Code size. */ + sljit_uw size; + /* For statistical purposes. */ + sljit_uw executable_size; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_si args; + sljit_si locals_offset; + sljit_si scratches_start; + sljit_si saveds_start; +#endif + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_si mode32; +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_si 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; + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_sw imm; + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + sljit_si delay_slot; + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + sljit_si delay_slot; + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + FILE* verbose; +#endif + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + /* Local size passed to the functions. */ + sljit_si logical_local_size; +#endif + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + sljit_si 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 compiled machine code. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler); + +/* Returns the current error code. If an error is occured, future sljit + calls which uses the same compiler argument returns early with the same + error code. Thus there is no need for checking the error after every + call, it is enough to do it before the code is compiled. Removing + these checks increases the performance of the compiling process. */ +static SLJIT_INLINE sljit_si 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_sw) 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. However, this return value does not + indicate that there is no more memory (does not set the current error code + of the compiler to out-of-memory status). +*/ +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si 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 machine code generation is finished 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 any error code. If there is no + error, they return with SLJIT_SUCCESS. */ + +/* + 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 scratch and + saved registers are passed in "scratches" 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 sljit_si sljit_emit_enter(struct sljit_compiler *compiler, + sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si 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 their context. + + Note: every call of sljit_emit_enter and sljit_set_context overwrites + the previous context. */ + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, + sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si 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_P (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 sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, + sljit_si src, sljit_sw srcw); + +/* Fast calling mechanism for utility functions (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 (the type of the value stored by this function + is sljit_p), 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 sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw); +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw 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_sw new_constant); + +/* --------------------------------------------------------------------- */ +/* Miscellaneous utility functions */ +/* --------------------------------------------------------------------- */ + +#define SLJIT_MAJOR_VERSION 0 +#define SLJIT_MINOR_VERSION 90 + +/* Get the human readable name of the platform. Can be useful on platforms + like ARM, where ARM and Thumb2 functions can be mixed, and + it is useful to know the type of the code generator. */ +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void); + +/* Portable helper function to get an offset of a member. */ +#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((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_sw 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_sw)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_sw*)(void*)func_name) + +/* For powerpc64, the function pointers point to a context descriptor. */ +struct sljit_function_context { + sljit_sw addr; + sljit_sw r2; + sljit_sw 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_sw addr, void* func); + +#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ + +#endif /* _SLJIT_LIR_H_ */ diff --git a/tools/pcre/sljit/sljitNativeARM_Thumb2.c b/tools/pcre/sljit/sljitNativeARM_Thumb2.c new file mode 100644 index 00000000..0a60dc2a --- /dev/null +++ b/tools/pcre/sljit/sljitNativeARM_Thumb2.c @@ -0,0 +1,2008 @@ +/* + * 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(void) +{ + return "ARM-Thumb2" SLJIT_CPUINFO; +} + +/* Length of an instruction word. */ +typedef sljit_ui sljit_ins; + +/* 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 (0) +#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 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, 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)) + +/* --------------------------------------------------------------------- */ +/* 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_F32 0xeeb00ac0 +#define VADD_F32 0xee300a00 +#define VCMP_F32 0xeeb40a40 +#define VDIV_F32 0xee800a00 +#define VMOV_F32 0xeeb00a40 +#define VMRS 0xeef1fa10 +#define VMUL_F32 0xee200a00 +#define VNEG_F32 0xeeb10a40 +#define VSTR_F32 0xed000a00 +#define VSUB_F32 0xee300a40 + +static sljit_si 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 sljit_si 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 sljit_si emit_imm32_const(struct sljit_compiler *compiler, sljit_si 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) +{ + sljit_si 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 sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code) +{ + sljit_sw 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_sw)jump->u.target - (sljit_sw)(code_ptr + 2)) >> 1; + } + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)) >> 1; + } + + if (jump->flags & IS_COND) { + 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, sljit_si 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) +{ + sljit_si type = (jump->flags >> 4) & 0xf; + sljit_sw diff; + sljit_uh *jump_inst; + sljit_si 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_sw)jump->u.target - (sljit_sw)(jump->addr + 4)) >> 1; + } + else + diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(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_COND)); + 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_COND)); + 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_COND); + *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_COND)); + 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_COND) ? 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 <= (sljit_sw)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. */ + sljit_si 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 sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si 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 sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si 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 */ + sljit_si 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_sw)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_sw)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_MOV_P: + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + case SLJIT_MOVU_P: + 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 sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw 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 sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_si 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 sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw 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 sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_r; + sljit_sw 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 sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw 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); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si size; + sljit_ins push; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + 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 (scratches >= 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_SCRATCH_REG1))); + if (args >= 2) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_SCRATCH_REG2))); + if (args >= 3) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_SCRATCH_REG3))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si size; + + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + 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 sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_ins pop; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, 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->scratches >= 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 int numerator, int unsigned denominator); +extern int __aeabi_idivmod(int numerator, int denominator); +#else +#error "Software divmod functions are needed" +#endif + +#ifdef __cplusplus +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si 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_SCRATCH_REG2] << 8) + | (reg_map[SLJIT_SCRATCH_REG1] << 12) + | (reg_map[SLJIT_SCRATCH_REG1] << 16) + | reg_map[SLJIT_SCRATCH_REG2]); + case SLJIT_UDIV: + case SLJIT_SDIV: + if (compiler->scratches >= 4) { + FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */)); + FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */)); + } else if (compiler->scratches >= 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->scratches >= 4) { + FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */)); + return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */); + } else if (compiler->scratches >= 3) + return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */); + return SLJIT_SUCCESS; + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r, flags; + sljit_si op_flags = GET_ALL_FLAGS(op); + + 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; + + dst_r = (dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REG3) ? dst : TMP_REG1; + + op = GET_OPCODE(op); + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + flags = WORD_SIZE; + break; + case SLJIT_MOV_UB: + flags = BYTE_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOV_SB: + flags = BYTE_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOV_UH: + flags = HALF_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOV_SH: + flags = HALF_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_sh)srcw; + break; + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + case SLJIT_MOVU_P: + flags = WORD_SIZE | UPDATE; + break; + case SLJIT_MOVU_UB: + flags = BYTE_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOVU_SB: + flags = BYTE_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOVU_UH: + flags = HALF_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOVU_SH: + flags = HALF_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_sh)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, 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 == 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 | op_flags, dst, dstw, SLJIT_IMM, 0, src, srcw); + } + + flags = (GET_FLAGS(op_flags) ? SET_FLAGS : 0) | ((op_flags & 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, 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 sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si 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_SCRATCH_REG1 && dst <= TMP_REG3) ? 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 sljit_si sljit_get_register_index(sljit_si reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si 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 sljit_si sljit_is_fpu_available(void) +{ + return 1; +} + +#define FPU_LOAD (1 << 20) + +static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_sw tmp; + sljit_uw imm; + sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + + 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) && (argw & 0x3) == 0) { + 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)); + } + } + + if (arg & 0xf) { + if (emit_set_delta(compiler, TMP_REG1, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg)); + } + imm = get_imm(argw & ~0x3fc); + if (imm != INVALID_IMM) { + FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & 0xf) | imm)); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2)); + } + imm = get_imm(-argw & ~0x3fc); + if (imm != INVALID_IMM) { + argw = -argw; + FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & 0xf) | imm)); + return push_inst32(compiler, inst | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2)); + } + } + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + if (SLJIT_UNLIKELY(!(arg & 0xf))) + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + 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 sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + op ^= SLJIT_SINGLE_OP; + + if (GET_OPCODE(op) == SLJIT_CMPD) { + if (dst & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, dst, dstw); + dst = TMP_FREG1; + } + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src, srcw); + src = TMP_FREG2; + } + FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst) | DM4(src))); + return push_inst32(compiler, VMRS); + } + + dst_r = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw); + src = dst_r; + } + + switch (GET_OPCODE(op)) { + case SLJIT_MOVD: + if (src != dst_r) + FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + break; + case SLJIT_NEGD: + FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + break; + case SLJIT_ABSD: + FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + break; + } + + if (dst & SLJIT_MEM) + return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r; + + CHECK_ERROR(); + check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + op ^= SLJIT_SINGLE_OP; + + dst_r = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + if (src1 & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); + src1 = TMP_FREG1; + } + if (src2 & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); + src2 = TMP_FREG2; + } + + switch (GET_OPCODE(op)) { + case SLJIT_ADDD: + FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_SUBD: + FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_MULD: + FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_DIVD: + FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + } + + if (dst & SLJIT_MEM) + return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return SLJIT_SUCCESS; +} + +#undef FPU_LOAD + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + 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) + return SLJIT_SUCCESS; + + if (dst <= TMP_REG3) + return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3)); + + /* Memory. */ + if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw)) + return compiler->error; + /* TMP_REG3 is used for caching. */ + 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); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src <= TMP_REG3) + 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(sljit_si 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_UNORDERED: + return 0x6; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_FLOAT_ORDERED: + 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, sljit_si type) +{ + struct sljit_jump *jump; + sljit_si 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_COND; + 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 sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw 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 <= TMP_REG3) + 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 sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_ins ins; + sljit_uw cc; + + CHECK_ERROR(); + check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + cc = get_cc(type); + dst_r = (dst <= TMP_REG3) ? dst : TMP_REG2; + + if (op < SLJIT_ADD) { + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); + if (reg_map[dst_r] > 7) { + FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 1)); + FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 0)); + } else { + FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 1)); + FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0)); + } + return dst_r == TMP_REG2 ? emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; + } + + ins = (op == SLJIT_AND ? ANDI : (op == SLJIT_OR ? ORRI : EORI)); + if ((op == SLJIT_OR || op == SLJIT_XOR) && dst <= TMP_REG3 && dst == src) { + /* Does not change the other bits. */ + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst) | 1)); + if (flags & SLJIT_SET_E) { + /* The condition must always be set, even if the ORRI/EORI is not executed above. */ + if (reg_map[dst] <= 7) + return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst)); + } + return SLJIT_SUCCESS; + } + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, WORD_SIZE, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } else if (src & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + srcw = 0; + } + + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 0)); + if (dst_r == TMP_REG2) + FAIL_IF(emit_op_mem2(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0)); + + if (flags & SLJIT_SET_E) { + /* The condition must always be set, even if the ORR/EORI is not executed above. */ + if (reg_map[dst_r] <= 7) + return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst_r)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r)); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si 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 <= TMP_REG3) ? 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_sw new_constant) +{ + sljit_uh* inst = (sljit_uh*)addr; + modify_imm32_const(inst, new_constant); + SLJIT_CACHE_FLUSH(inst, inst + 3); +} diff --git a/tools/pcre/sljit/sljitNativeARM_v5.c b/tools/pcre/sljit/sljitNativeARM_v5.c new file mode 100644 index 00000000..23a45a4c --- /dev/null +++ b/tools/pcre/sljit/sljitNativeARM_v5.c @@ -0,0 +1,2515 @@ +/* + * 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(void) +{ +#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 (0) +#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1) + +/* 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) / (sljit_si)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_F32 0xeeb00ac0 +#define VADD_F32 0xee300a00 +#define VCMP_F32 0xeeb40a40 +#define VDIV_F32 0xee800a00 +#define VMOV_F32 0xeeb00a40 +#define VMRS 0xeef1fa10 +#define VMUL_F32 0xee200a00 +#define VNEG_F32 0xeeb10a40 +#define VSTR_F32 0xed000a00 +#define VSUB_F32 0xee300a40 + +#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 sljit_si 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; + sljit_si 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 sljit_si 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 sljit_si 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 sljit_si 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 sljit_si 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 sljit_si 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 ((sljit_si)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; + sljit_si index; + sljit_si value; +}; + +static SLJIT_INLINE sljit_si resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) +{ + sljit_si value; + struct future_patch *curr_patch, *prev_patch; + + /* Using the values generated by patch_pc_relative_loads. */ + if (!*first_patch) + value = (sljit_si)cpool_start_address[cpool_current_index]; + else { + curr_patch = *first_patch; + prev_patch = 0; + while (1) { + if (!curr_patch) { + value = (sljit_si)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 sljit_si 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 sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si reg, sljit_sw 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 sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) +{ + sljit_sw 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_sw)jump->u.target - (sljit_sw)(code_ptr + 2)); + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(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_sw)jump->u.target - (sljit_sw)code_ptr); + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)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, sljit_si 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]; + sljit_si bl = (mov_pc & 0x0000f000) != RD(TMP_PC); + sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(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_imm(sljit_uw imm); + +static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_si 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_imm(new_constant); + if (src2) { + *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2; + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + return; + } + + src2 = get_imm(~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_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); + *buf_ptr |= (((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff; + } + else { + SLJIT_ASSERT(((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); + *buf_ptr |= (((sljit_sw)jump->u.target - (sljit_sw)(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 <= (sljit_si)size); + + SLJIT_CACHE_FLUSH(code, code_ptr); + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = size * sizeof(sljit_uw); + return code; +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +/* 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 sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w); + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si size; + sljit_uw push; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + 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 (scratches >= 5) + push |= 1 << 11; + if (scratches >= 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 (scratches >= 4) + size += (scratches - 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_SCRATCH_REG1))); + if (args >= 2) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG2))); + if (args >= 3) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG3))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si size; + + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + size = (1 + saveds) * sizeof(sljit_uw); + if (scratches >= 4) + size += (scratches - 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 sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_uw pop; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, 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->scratches >= 5) + pop |= 1 << 11; + if (compiler->scratches >= 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_sw 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 sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_si src2) +{ + sljit_sw mul_inst; + + switch (GET_OPCODE(op)) { + 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; + + 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); + } + 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_imm(sljit_uw imm) +{ + sljit_si 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 sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm, sljit_si positive) +{ + sljit_uw mask; + sljit_uw imm1; + sljit_uw imm2; + sljit_si 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 sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si 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_imm(imm); + if (tmp) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp)); + return SLJIT_SUCCESS; + } + + tmp = get_imm(~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 +} + +/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ +static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +{ + if (value >= 0) { + value = get_imm(value); + if (value) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, dst, reg, value)); + } + else { + value = get_imm(-value); + if (value) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, dst, reg, value)); + } + return SLJIT_ERR_UNSUPPORTED; +} + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_uw imm; + + if (arg & SLJIT_IMM) { + imm = get_imm(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_imm(~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 sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw 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 sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_r; + sljit_sw max_delta; + sljit_sw sign; + sljit_uw imm; + + 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. */ + imm = (sljit_uw)(argw - compiler->cache_argw); + if ((compiler->cache_arg & SLJIT_IMM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { + if (imm <= (sljit_uw)max_delta) { + sign = 1; + argw = argw - compiler->cache_argw; + } + else { + sign = 0; + argw = compiler->cache_argw - argw; + } + + GETPUT_ARG_DATA_TRANSFER(sign, 0, reg, TMP_REG3, 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). */ + imm = (sljit_uw)(argw - next_argw); + if ((next_arg & SLJIT_MEM) && (imm <= (sljit_uw)max_delta || imm >= (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; + } + + 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; + } + + imm = (sljit_uw)(argw - compiler->cache_argw); + if (compiler->cache_arg == arg && imm <= (sljit_uw)max_delta) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); + GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, imm); + return SLJIT_SUCCESS; + } + if (compiler->cache_arg == arg && imm >= (sljit_uw)-max_delta) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); + imm = (sljit_uw)-(sljit_sw)imm; + GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, imm); + return SLJIT_SUCCESS; + } + + imm = get_imm(argw & ~max_delta); + if (imm) { + TEST_WRITE_BACK(); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & 0xf, imm)); + GETPUT_ARG_DATA_TRANSFER(1, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta); + return SLJIT_SUCCESS; + } + + imm = get_imm(-argw & ~max_delta); + if (imm) { + argw = -argw; + TEST_WRITE_BACK(); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & 0xf, imm)); + GETPUT_ARG_DATA_TRANSFER(0, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta); + 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; + } + + imm = (sljit_uw)(argw - next_argw); + if (arg == next_arg && !(inp_flags & WRITE_BACK) && (imm <= (sljit_uw)max_delta || imm >= (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 SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw 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); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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. */ + sljit_si dst_r; + sljit_si src1_r; + sljit_si src2_r = 0; + sljit_si sugg_src2_r = TMP_REG2; + sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + /* Destination check. */ + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } + else if (dst <= TMP_REG3) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } + 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 <= TMP_REG3) + src1_r = src1; + else if (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_imm(src1w); + if (src2_r) { + flags |= ARGS_SWAPPED; + src1 = src2; + src1w = src2w; + break; + } + if (inp_flags & ALLOW_INV_IMM) { + src2_r = get_imm(~src1w); + if (src2_r) { + flags |= ARGS_SWAPPED | INV_IMM; + src1 = src2; + src1w = src2w; + break; + } + } + if (GET_OPCODE(op) == SLJIT_ADD) { + src2_r = get_imm(-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 <= 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_imm(src2w); + if (src2_r) + break; + if (inp_flags & ALLOW_INV_IMM) { + src2_r = get_imm(~src2w); + if (src2_r) { + flags |= INV_IMM; + break; + } + } + if (GET_OPCODE(op) == SLJIT_ADD) { + src2_r = get_imm(-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_imm(-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 int numerator, unsigned int denominator); +extern int __aeabi_idivmod(int numerator, int denominator); +#else +#error "Software divmod functions are needed" +#endif + +#ifdef __cplusplus +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si 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_SCRATCH_REG2] << 16) + | (reg_map[SLJIT_SCRATCH_REG1] << 12) + | (reg_map[SLJIT_SCRATCH_REG1] << 8) + | reg_map[SLJIT_SCRATCH_REG2]); +#else + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) + | (reg_map[SLJIT_SCRATCH_REG2] << 16) + | (reg_map[SLJIT_SCRATCH_REG1] << 12) + | (reg_map[SLJIT_SCRATCH_REG1] << 8) + | reg_map[TMP_REG1]); +#endif + case SLJIT_UDIV: + case SLJIT_SDIV: + if (compiler->scratches >= 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->scratches >= 3) + return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */); + return SLJIT_SUCCESS; + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw 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: + case SLJIT_MOV_P: + 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) ? (sljit_ub)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) ? (sljit_sb)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) ? (sljit_uh)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) ? (sljit_sh)srcw : srcw); + + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + case SLJIT_MOVU_P: + 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) ? (sljit_ub)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) ? (sljit_sb)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) ? (sljit_uh)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) ? (sljit_sh)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 sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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 sljit_si sljit_get_register_index(sljit_si reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si 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 sljit_si arm_fpu_type = -1; + +static void init_compiler(void) +{ + 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 sljit_si 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 sljit_si sljit_is_fpu_available(void) +{ + /* Always available. */ + return 1; +} + +#endif + +#define FPU_LOAD (1 << 20) +#define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \ + ((inst) | ((add) << 23) | (reg_map[base] << 16) | (freg << 12) | (offs)) +#define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \ + ((opcode) | (mode) | ((dst) << 12) | (src1) | ((src2) << 16)) + +static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_sw tmp; + sljit_uw imm; + sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (SLJIT_UNLIKELY(arg & 0xf0)) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7))); + arg = SLJIT_MEM | TMP_REG1; + argw = 0; + } + + /* Fast loads and stores. */ + if ((arg & 0xf)) { + if (!(argw & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & 0xf, reg, argw >> 2)); + if (!(-argw & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & 0xf, reg, (-argw) >> 2)); + } + + if (compiler->cache_arg == arg) { + tmp = argw - compiler->cache_argw; + if (!(tmp & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, tmp >> 2)); + if (!(-tmp & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG3, 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_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); + } + } + + if (arg & 0xf) { + if (emit_set_delta(compiler, TMP_REG1, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, 0)); + } + imm = get_imm(argw & ~0x3fc); + if (imm) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, imm)); + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2)); + } + imm = get_imm(-argw & ~0x3fc); + if (imm) { + argw = -argw; + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & 0xf, imm)); + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2)); + } + } + + 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)); + + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + op ^= SLJIT_SINGLE_OP; + + if (GET_OPCODE(op) == SLJIT_CMPD) { + if (dst > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, dst, dstw)); + dst = TMP_FREG1; + } + if (src > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src, srcw)); + src = TMP_FREG2; + } + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_SINGLE_OP, dst, src, 0)); + EMIT_INSTRUCTION(VMRS); + return SLJIT_SUCCESS; + } + + dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + + if (src > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_fr, src, srcw)); + src = dst_fr; + } + + switch (GET_OPCODE(op)) { + case SLJIT_MOVD: + if (src != dst_fr && dst_fr != TMP_FREG1) + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0)); + break; + case SLJIT_NEGD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0)); + break; + case SLJIT_ABSD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0)); + break; + } + + if (dst_fr == TMP_FREG1) { + if (GET_OPCODE(op) == SLJIT_MOVD) + dst_fr = src; + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_fr, dst, dstw)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + op ^= SLJIT_SINGLE_OP; + + dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + + if (src2 > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); + src2 = TMP_FREG2; + } + + if (src1 > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); + src1 = TMP_FREG1; + } + + switch (GET_OPCODE(op)) { + case SLJIT_ADDD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + break; + + case SLJIT_SUBD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + break; + + case SLJIT_MULD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + break; + + case SLJIT_DIVD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + break; + } + + if (dst_fr == TMP_FREG1) + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw)); + + return SLJIT_SUCCESS; +} + +#undef FPU_LOAD +#undef EMIT_FPU_DATA_TRANSFER +#undef EMIT_FPU_OPERATION + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + 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) + return SLJIT_SUCCESS; + + if (dst <= TMP_REG3) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3))); + + /* Memory. */ + if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw)) + return compiler->error; + /* TMP_REG3 is used for caching. */ + 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); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src <= TMP_REG3) + 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(sljit_si 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_UNORDERED: + return 0x60000000; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_FLOAT_ORDERED: + 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, sljit_si 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 sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw 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 <= TMP_REG3) + return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src)); + + SLJIT_ASSERT(src & SLJIT_MEM); + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw)); + return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_uw cc, ins; + + CHECK_ERROR(); + check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + cc = get_cc(type); + dst_r = (dst <= TMP_REG3) ? dst : TMP_REG2; + + if (op < SLJIT_ADD) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 0)); + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); + return (dst_r == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; + } + + ins = (op == SLJIT_AND ? AND_DP : (op == SLJIT_OR ? ORR_DP : EOR_DP)); + if ((op == SLJIT_OR || op == SLJIT_XOR) && dst <= TMP_REG3 && dst == src) { + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc); + /* The condition must always be set, even if the ORR/EOR is not executed above. */ + return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))) : SLJIT_SUCCESS; + } + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } else if (src & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + srcw = 0; + } + + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 1) & ~COND_MASK) | cc); + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000)); + if (dst_r == TMP_REG2) + FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0)); + + return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst_r))) : SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si 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 <= TMP_REG3) ? 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) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, 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_sw new_constant) +{ + inline_set_const(addr, new_constant, 1); +} diff --git a/tools/pcre/sljit/sljitNativeMIPS_32.c b/tools/pcre/sljit/sljitNativeMIPS_32.c new file mode 100644 index 00000000..f8c21486 --- /dev/null +++ b/tools/pcre/sljit/sljitNativeMIPS_32.c @@ -0,0 +1,404 @@ +/* + * 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 sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw 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 sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_sw src2) +{ + sljit_si overflow_ra = 0; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + 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 && !(flags & SRC2_IMM)); + 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 && !(flags & SRC2_IMM)); + 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(5), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ADDIU_W | SA(0) | T(dst) | IMM(-1), DR(dst))); + /* Loop for searching the highest bit. */ + FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), DR(dst))); + FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_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; + + 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; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +{ + FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst))); + return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); +} + +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_sw 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 --git a/tools/pcre/sljit/sljitNativeMIPS_common.c b/tools/pcre/sljit/sljitNativeMIPS_common.c new file mode 100644 index 00000000..9559ec32 --- /dev/null +++ b/tools/pcre/sljit/sljitNativeMIPS_common.c @@ -0,0 +1,1881 @@ +/* + * 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. + */ + +/* Latest MIPS architecture. */ +/* Automatically detect SLJIT_MIPS_32_64 */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +{ +#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) + return "MIPS" SLJIT_CPUINFO; +#else + return "MIPS III" SLJIT_CPUINFO; +#endif +} + +/* 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 (0) +#define TMP_FREG2 ((SLJIT_FLOAT_REG6 + 1) << 1) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { + 0, 2, 5, 6, 3, 8, 16, 17, 18, 19, 20, 29, 4, 25, 9 +}; + +/* --------------------------------------------------------------------- */ +/* 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) +#define FS(s) ((s) << 11) +#define FD(d) ((d) << 6) +#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) +/* S = (16 << 21) D = (17 << 21) */ +#define FMT_SD (16 << 21) + +#define ABS_fmt (HI(17) | FMT_SD | LO(5)) +#define ADD_fmt (HI(17) | FMT_SD | 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 CFC1 (HI(17) | (2 << 21)) +#define C_UN_fmt (HI(17) | FMT_SD | LO(49)) +#define C_UEQ_fmt (HI(17) | FMT_SD | LO(51)) +#define C_ULE_fmt (HI(17) | FMT_SD | LO(55)) +#define C_ULT_fmt (HI(17) | FMT_SD | LO(53)) +#define DIV (HI(0) | LO(26)) +#define DIVU (HI(0) | LO(27)) +#define DIV_fmt (HI(17) | FMT_SD | 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 LUI (HI(15)) +#define LW (HI(35)) +#define MFHI (HI(0) | LO(16)) +#define MFLO (HI(0) | LO(18)) +#define MOV_fmt (HI(17) | FMT_SD | LO(6)) +#define MOVN (HI(0) | LO(11)) +#define MOVZ (HI(0) | LO(10)) +#define MUL_fmt (HI(17) | FMT_SD | LO(2)) +#define MULT (HI(0) | LO(24)) +#define MULTU (HI(0) | LO(25)) +#define NEG_fmt (HI(17) | FMT_SD | LO(7)) +#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 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_fmt (HI(17) | FMT_SD | 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) + +/* dest_reg is the absolute name of the register + Useful for reordering instructions in the delay slot. */ +static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) +{ + SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS + || delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f)); + 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(sljit_si 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_sw 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_sw)target_addr - (sljit_sw)(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_sw)target_addr - (sljit_sw)(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 +#error "Implementation required" +#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 <= (sljit_sw)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_sw)(addr - (jump->addr + sizeof(sljit_ins))) >> 2; + SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)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 +#error "Implementation required" +#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; +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +/* Creates an index in data_transfer_insts array. */ +#define LOAD_DATA 0x01 +#define WORD_DATA 0x00 +#define BYTE_DATA 0x02 +#define HALF_DATA 0x04 +#define INT_DATA 0x06 +#define SIGNED_DATA 0x08 +/* Separates integer and floating point registers */ +#define GPR_REG 0x0f +#define DOUBLE_DATA 0x10 + +#define MEM_MASK 0x1f + +#define WRITE_BACK 0x00020 +#define ARG_TEST 0x00040 +#define ALT_KEEP_CACHE 0x00080 +#define CUMULATIVE_OP 0x00100 +#define LOGICAL_OP 0x00200 +#define IMM_OP 0x00400 +#define SRC2_IMM 0x00800 + +#define UNUSED_DEST 0x01000 +#define REG_DEST 0x02000 +#define REG1_SOURCE 0x04000 +#define REG2_SOURCE 0x08000 +#define SLOW_SRC1 0x10000 +#define SLOW_SRC2 0x20000 +#define SLOW_DEST 0x40000 + +/* 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) +#define STACK_STORE SW +#define STACK_LOAD LW +#else +#define STACK_STORE SD +#define STACK_LOAD LD +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#include "sljitNativeMIPS_32.c" +#else +#include "sljitNativeMIPS_64.c" +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_ins base; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + local_size += (saveds + 1 + 4) * sizeof(sljit_sw); + 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 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + if (saveds >= 1) + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + if (saveds >= 2) + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + if (saveds >= 3) + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + if (saveds >= 4) + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + if (saveds >= 5) + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (sljit_si)sizeof(sljit_sw)), 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, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + local_size += (saveds + 1 + 4) * sizeof(sljit_sw); + compiler->local_size = (local_size + 15) & ~0xf; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si local_size; + sljit_ins base; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, 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 * (sljit_si)sizeof(sljit_sw)), RETURN_ADDR_REG)); + if (compiler->saveds >= 5) + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (sljit_si)sizeof(sljit_sw)), DR(SLJIT_SAVED_EREG2))); + if (compiler->saveds >= 4) + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (sljit_si)sizeof(sljit_sw)), DR(SLJIT_SAVED_EREG1))); + if (compiler->saveds >= 3) + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (sljit_si)sizeof(sljit_sw)), DR(SLJIT_SAVED_REG3))); + if (compiler->saveds >= 2) + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (sljit_si)sizeof(sljit_sw)), DR(SLJIT_SAVED_REG2))); + if (compiler->saveds >= 1) + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (sljit_si)sizeof(sljit_sw)), 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_32_64(a, b) a +#else +#define ARCH_32_64(a, b) b +#endif + +static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { +/* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), +/* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), +/* u b s */ HI(40) /* sb */, +/* u b l */ HI(36) /* lbu */, +/* u h s */ HI(41) /* sh */, +/* u h l */ HI(37) /* lhu */, +/* u i s */ HI(43) /* sw */, +/* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */), + +/* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), +/* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), +/* s b s */ HI(40) /* sb */, +/* s b l */ HI(32) /* lb */, +/* s h s */ HI(41) /* sh */, +/* s h l */ HI(33) /* lh */, +/* s i s */ HI(43) /* sw */, +/* s i l */ HI(35) /* lw */, + +/* d s */ HI(61) /* sdc1 */, +/* d l */ HI(53) /* ldc1 */, +/* s s */ HI(57) /* swc1 */, +/* s l */ HI(49) /* lwc1 */, +}; + +#undef ARCH_32_64 + +/* reg_ar is an absoulute register! */ + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +{ + SLJIT_ASSERT(arg & SLJIT_MEM); + + if ((!(flags & WRITE_BACK) || !(arg & 0xf)) && !(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 & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS)); + return -1; + } + return 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); + + /* 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 (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)) + return 1; + return 0; + } + + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_ar, base, delay_slot; + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(next_arg & SLJIT_MEM)) { + next_arg = 0; + next_argw = 0; + } + + if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) { + tmp_ar = reg_ar; + delay_slot = reg_ar; + } else { + tmp_ar = DR(TMP_REG1); + delay_slot = MOVABLE_INS; + } + 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), delay_slot); + 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), delay_slot); + } + 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), delay_slot); + } + } + 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), delay_slot); + } + } + } + + 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), delay_slot); + } + 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), delay_slot); + } + + 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), delay_slot); + } + + 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), delay_slot); + } + + 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), delay_slot); + + 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), delay_slot); + } + + 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), delay_slot); +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw 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 SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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. */ + sljit_si dst_r = TMP_REG2; + sljit_si src1_r; + sljit_sw src2_r = 0; + sljit_si sugg_src2_r = TMP_REG2; + + if (!(flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } + + if (SLJIT_UNLIKELY(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 <= 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_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 (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { + 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 <= 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 <= TMP_REG3) { + 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 (!(flags & SRC2_IMM)) { + if (src2w) { + FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w)); + src2_r = sugg_src2_r; + } + else { + src2_r = 0; + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + dst_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 sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si 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_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_SCRATCH_REG1), DR(SLJIT_SCRATCH_REG1))); + return push_inst(compiler, MFHI | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_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_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_SCRATCH_REG1), DR(SLJIT_SCRATCH_REG1))); + return push_inst(compiler, MFHI | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# define 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); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: + return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UI: + return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_SI: + return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UB: + return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + + case SLJIT_MOV_SB: + return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + + case SLJIT_MOV_UH: + return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + + case SLJIT_MOV_SH: + return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + + case SLJIT_MOVU: + case SLJIT_MOVU_P: + return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UI: + return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_SI: + return emit_op(compiler, SLJIT_MOV_SI, 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, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + + case SLJIT_MOVU_SB: + return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + + case SLJIT_MOVU_UH: + return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + + case SLJIT_MOVU_SH: + return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + + case SLJIT_NOT: + return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: + return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); + + case SLJIT_CLZ: + return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + } + + return SLJIT_SUCCESS; +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# undef flags +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# define 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, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUB: + case SLJIT_SUBC: + return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_MUL: + return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + return emit_op(compiler, op, 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 + SLJIT_ASSERT_STOP(); +#endif + return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# undef flags +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si 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 sljit_si sljit_is_fpu_available(void) +{ +#if (defined SLJIT_QEMU && SLJIT_QEMU) + /* Qemu says fir is 0 by default. */ + return 1; +#elif defined(__GNUC__) + sljit_sw fir; + asm ("cfc1 %0, $0" : "=r"(fir)); + return (fir >> 22) & 0x1; +#else +#error "FIR check is not implemented for this architecture" +#endif +} + +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) +#define FMT(op) (((op & SLJIT_SINGLE_OP) ^ SLJIT_SINGLE_OP) << (21 - 8)) + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (GET_OPCODE(op) == SLJIT_CMPD) { + if (dst > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw)); + dst = TMP_FREG1; + } + else + dst <<= 1; + + if (src > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0)); + src = TMP_FREG2; + } + else + src <<= 1; + + /* src and dst are swapped. */ + if (op & SLJIT_SET_E) { + FAIL_IF(push_inst(compiler, C_UEQ_fmt | FMT(op) | 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_fmt | FMT(op) | 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_fmt | FMT(op) | 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_fmt | FMT(op) | FT(src) | FS(dst), FCSR_FCC); + } + + dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : (dst << 1); + + if (src > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw)); + src = dst_fr; + } + else + src <<= 1; + + switch (GET_OPCODE(op)) { + case SLJIT_MOVD: + if (src != dst_fr && dst_fr != TMP_FREG1) + FAIL_IF(push_inst(compiler, MOV_fmt | FMT(op) | FS(src) | FD(dst_fr), MOVABLE_INS)); + break; + case SLJIT_NEGD: + FAIL_IF(push_inst(compiler, NEG_fmt | FMT(op) | FS(src) | FD(dst_fr), MOVABLE_INS)); + break; + case SLJIT_ABSD: + FAIL_IF(push_inst(compiler, ABS_fmt | FMT(op) | FS(src) | FD(dst_fr), MOVABLE_INS)); + break; + } + + if (dst_fr == TMP_FREG1) { + if (GET_OPCODE(op) == SLJIT_MOVD) + dst_fr = src; + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_fr, dst, dstw, 0, 0)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_fr, flags = 0; + + 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_REG6) ? TMP_FREG2 : (dst << 1); + + if (src1 > SLJIT_FLOAT_REG6) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1 = TMP_FREG1; + } else + flags |= SLOW_SRC1; + } + else + src1 <<= 1; + + if (src2 > SLJIT_FLOAT_REG6) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { + FAIL_IF(compiler->error); + src2 = TMP_FREG2; + } else + flags |= SLOW_SRC2; + } + else + src2 <<= 1; + + 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, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + + if (flags & SLOW_SRC1) + src1 = TMP_FREG1; + if (flags & SLOW_SRC2) + src2 = TMP_FREG2; + + switch (GET_OPCODE(op)) { + case SLJIT_ADDD: + FAIL_IF(push_inst(compiler, ADD_fmt | FMT(op) | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + break; + + case SLJIT_SUBD: + FAIL_IF(push_inst(compiler, SUB_fmt | FMT(op) | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + break; + + case SLJIT_MULD: + FAIL_IF(push_inst(compiler, MUL_fmt | FMT(op) | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + break; + + case SLJIT_DIVD: + FAIL_IF(push_inst(compiler, DIV_fmt | FMT(op) | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + break; + } + + if (dst_fr == TMP_FREG2) + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); + + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + 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) + return SLJIT_SUCCESS; + + if (dst <= TMP_REG3) + return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); + + /* Memory. */ + return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src <= TMP_REG3) + 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 +#error "Implementation required" +#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, sljit_si type) +{ + struct sljit_jump *jump; + sljit_ins inst; + sljit_si flags = 0; + sljit_si 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_UNORDERED: + BR_F(); + break; + case SLJIT_C_FLOAT_ORDERED: + 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_SCRATCH_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, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + struct sljit_jump *jump; + sljit_si 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) { + PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w)); + src1 = TMP_REG1; + } + if (src2 & SLJIT_MEM) { + PTR_FAIL_IF(emit_op_mem2(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, sljit_si type, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + struct sljit_jump *jump; + sljit_ins inst; + sljit_si 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_REG6) { + PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + src1 = TMP_FREG1; + } + else + src1 <<= 1; + + if (src2 > SLJIT_FLOAT_REG6) { + PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); + src2 = TMP_FREG2; + } + else + src2 <<= 1; + + 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; + + switch (type & 0xff) { + case SLJIT_C_FLOAT_EQUAL: + inst = C_UEQ_fmt; + if_true = 1; + break; + case SLJIT_C_FLOAT_NOT_EQUAL: + inst = C_UEQ_fmt; + if_true = 0; + break; + case SLJIT_C_FLOAT_LESS: + inst = C_ULT_fmt; + if_true = 1; + break; + case SLJIT_C_FLOAT_GREATER_EQUAL: + inst = C_ULT_fmt; + if_true = 0; + break; + case SLJIT_C_FLOAT_GREATER: + inst = C_ULE_fmt; + if_true = 0; + break; + case SLJIT_C_FLOAT_LESS_EQUAL: + inst = C_ULE_fmt; + if_true = 1; + break; + case SLJIT_C_FLOAT_UNORDERED: + inst = C_UN_fmt; + if_true = 1; + break; + case SLJIT_C_FLOAT_ORDERED: + default: /* Make compilers happy. */ + inst = C_UN_fmt; + if_true = 0; + break; + } + + PTR_FAIL_IF(push_inst(compiler, inst | FMT(type) | 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 + +#undef FLOAT_DATA +#undef FMT + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + sljit_si 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 <= TMP_REG3) { + 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_SCRATCH_REG1) | TA(0) | DA(4), UNMOVABLE_INS); + } + + /* Register input. */ + if (type >= SLJIT_CALL1) + FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SCRATCH_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 sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si sugg_dst_ar, dst_ar; + sljit_si flags = GET_ALL_FLAGS(op); + + CHECK_ERROR(); + check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + sugg_dst_ar = DR((op < SLJIT_ADD && dst <= TMP_REG3) ? dst : TMP_REG2); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } + + 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_UNORDERED: + case SLJIT_C_FLOAT_ORDERED: + 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 (op >= SLJIT_ADD) { + 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 | flags, CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, 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, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si 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 <= TMP_REG3) ? 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 --git a/tools/pcre/sljit/sljitNativePPC_32.c b/tools/pcre/sljit/sljitNativePPC_32.c new file mode 100644 index 00000000..0bd35a6e --- /dev/null +++ b/tools/pcre/sljit/sljitNativePPC_32.c @@ -0,0 +1,269 @@ +/* + * 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 sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw 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 sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_si src2) +{ + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + 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 { + SLJIT_ASSERT(dst == src2); + } + 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 { + SLJIT_ASSERT(dst == src2); + } + 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)); + + 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 | D(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 | D(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_FORM3) + FAIL_IF(push_inst(compiler, MFXER | D(0))); + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + compiler->imm &= 0x1f; + FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11))); + } + else + FAIL_IF(push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2))); + return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw 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_sw 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 --git a/tools/pcre/sljit/sljitNativePPC_64.c b/tools/pcre/sljit/sljitNativePPC_64.c new file mode 100644 index 00000000..8eaeb41f --- /dev/null +++ b/tools/pcre/sljit/sljitNativePPC_64.c @@ -0,0 +1,421 @@ +/* + * 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. */ + +#if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM) +#define ASM_SLJIT_CLZ(src, dst) \ + __asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) ) +#elif defined(__xlc__) +#error "Please enable GCC syntax for inline assembly statements" +#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 sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw 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 sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_si src2) +{ + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: + 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 { + SLJIT_ASSERT(dst == 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 { + SLJIT_ASSERT(dst == src2); + } + 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 { + SLJIT_ASSERT(dst == src2); + } + 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)); + + 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 | D(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 | D(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)); + } + } + return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : 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)); + } + } + return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_ASHR: + if (flags & ALT_FORM3) + FAIL_IF(push_inst(compiler, MFXER | D(0))); + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) { + compiler->imm &= 0x1f; + FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11))); + } + else { + compiler->imm &= 0x3f; + FAIL_IF(push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4))); + } + } + else + FAIL_IF(push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2))); + return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw 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_sw 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); +} diff --git a/tools/pcre/sljit/sljitNativePPC_common.c b/tools/pcre/sljit/sljitNativePPC_common.c new file mode 100644 index 00000000..f7c75a79 --- /dev/null +++ b/tools/pcre/sljit/sljitNativePPC_common.c @@ -0,0 +1,2014 @@ +/* + * 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(void) +{ + return "PowerPC" SLJIT_CPUINFO; +} + +/* Length of an instruction word. + Both for ppc-32 and ppc-64. */ +typedef sljit_ui sljit_ins; + +#ifdef _AIX +#include +#endif + +static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) +{ +#ifdef _AIX + _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from)); +#elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM) +# if defined(_ARCH_PWR) || defined(_ARCH_PWR2) + /* Cache flush for POWER architecture. */ + while (from < to) { + __asm__ volatile ( + "clf 0, %0\n" + "dcs\n" + : : "r"(from) + ); + from++; + } + __asm__ volatile ( "ics" ); +# elif defined(_ARCH_COM) && !defined(_ARCH_PPC) +# error "Cache flush is not implemented for PowerPC/POWER common mode." +# else + /* Cache flush for PowerPC architecture. */ + while (from < to) { + __asm__ volatile ( + "dcbf 0, %0\n" + "sync\n" + "icbi 0, %0\n" + : : "r"(from) + ); + from++; + } + __asm__ volatile ( "isync" ); +# endif +# ifdef __xlc__ +# warning "This file may fail to compile if -qfuncsect is used" +# endif +#elif defined(__xlc__) +#error "Please enable GCC syntax for inline assembly statements with -qasm=gcc" +#else +#error "This platform requires a cache flush implementation." +#endif /* _AIX */ +} + +#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 (0) +#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { + 0, 3, 4, 5, 6, 7, 30, 29, 28, 27, 26, 1, 8, 9, 10, 31 +}; + +/* --------------------------------------------------------------------- */ +/* 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 FADDS (HI(59) | LO(21)) +#define FCMPU (HI(63) | LO(0)) +#define FDIV (HI(63) | LO(18)) +#define FDIVS (HI(59) | LO(18)) +#define FMR (HI(63) | LO(72)) +#define FMUL (HI(63) | LO(25)) +#define FMULS (HI(59) | LO(25)) +#define FNEG (HI(63) | LO(40)) +#define FSUB (HI(63) | LO(20)) +#define FSUBS (HI(59) | LO(20)) +#define LD (HI(58) | 0) +#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 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) + +#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func) +{ + sljit_sw* ptrs; + if (func_ptr) + *func_ptr = (void*)context; + ptrs = (sljit_sw*)func; + context->addr = addr ? addr : ptrs[0]; + context->r2 = ptrs[1]; + context->r11 = ptrs[2]; +} +#endif + +static sljit_si 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 sljit_si optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_sw 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_sw)target_addr - (sljit_sw)(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_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); +#else + compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); +#endif +#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_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins))); +#else + SLJIT_ASSERT(code_ptr - code <= (sljit_sw)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_sw)addr <= 0x01ffffff && (sljit_sw)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_sw)addr <= 0x7fff && (sljit_sw)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_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (((sljit_sw)code_ptr) & 0x4) + code_ptr++; + sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); + return code_ptr; +#else + sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); + return code_ptr; +#endif +#else + return code; +#endif +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +/* inp_flags: */ + +/* Creates an index in data_transfer_insts array. */ +#define LOAD_DATA 0x01 +#define INDEXED 0x02 +#define WRITE_BACK 0x04 +#define WORD_DATA 0x00 +#define BYTE_DATA 0x08 +#define HALF_DATA 0x10 +#define INT_DATA 0x18 +#define SIGNED_DATA 0x20 +/* Separates integer and floating point registers */ +#define GPR_REG 0x3f +#define DOUBLE_DATA 0x40 + +#define MEM_MASK 0x7f + +/* 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_KEEP_CACHE 0x000800 +#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 + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + 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(-(sljit_si)(sizeof(sljit_sw))) )); + if (saveds >= 1) + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (sljit_si)(sizeof(sljit_sw))) )); + if (saveds >= 2) + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (sljit_si)(sizeof(sljit_sw))) )); + if (saveds >= 3) + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (sljit_si)(sizeof(sljit_sw))) )); + if (saveds >= 4) + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (sljit_si)(sizeof(sljit_sw))) )); + if (saveds >= 5) + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_sw)) )); + + FAIL_IF(push_inst(compiler, ADDI | D(ZERO_REG) | A(0) | 0)); + if (args >= 1) + FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_SCRATCH_REG1))); + if (args >= 2) + FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_SCRATCH_REG2))); + if (args >= 3) + FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_SCRATCH_REG3))); + +#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size; +#else + compiler->local_size = (1 + saveds + 2) * sizeof(sljit_sw) + 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, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + +#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size; +#else + compiler->local_size = (1 + saveds + 2) * sizeof(sljit_sw) + local_size; +#endif + compiler->local_size = (compiler->local_size + 15) & ~0xf; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, 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_sw)))); + if (compiler->saveds >= 5) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (sljit_si)(sizeof(sljit_sw))) )); + if (compiler->saveds >= 4) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (sljit_si)(sizeof(sljit_sw))) )); + if (compiler->saveds >= 3) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (sljit_si)(sizeof(sljit_sw))) )); + if (compiler->saveds >= 2) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (sljit_si)(sizeof(sljit_sw))) )); + if (compiler->saveds >= 1) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_LOAD | D(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) )); + + 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_32_64(a, b) a +#define INST_CODE_AND_DST(inst, flags, reg) \ + ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) +#else +#define ARCH_32_64(a, b) b +#define INST_CODE_AND_DST(inst, flags, reg) \ + (((inst) & ~(ADDR_MODE2 | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) +#endif + +static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { + +/* -------- Unsigned -------- */ + +/* Word. */ + +/* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), +/* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), +/* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), +/* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), + +/* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), +/* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), +/* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), +/* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), + +/* Byte. */ + +/* u b n i s */ HI(38) /* stb */, +/* u b n i l */ HI(34) /* lbz */, +/* u b n x s */ HI(31) | LO(215) /* stbx */, +/* u b n x l */ HI(31) | LO(87) /* lbzx */, + +/* u b w i s */ HI(39) /* stbu */, +/* u b w i l */ HI(35) /* lbzu */, +/* u b w x s */ HI(31) | LO(247) /* stbux */, +/* u b w x l */ HI(31) | LO(119) /* lbzux */, + +/* Half. */ + +/* u h n i s */ HI(44) /* sth */, +/* u h n i l */ HI(40) /* lhz */, +/* u h n x s */ HI(31) | LO(407) /* sthx */, +/* u h n x l */ HI(31) | LO(279) /* lhzx */, + +/* u h w i s */ HI(45) /* sthu */, +/* u h w i l */ HI(41) /* lhzu */, +/* u h w x s */ HI(31) | LO(439) /* sthux */, +/* u h w x l */ HI(31) | LO(311) /* lhzux */, + +/* Int. */ + +/* u i n i s */ HI(36) /* stw */, +/* u i n i l */ HI(32) /* lwz */, +/* u i n x s */ HI(31) | LO(151) /* stwx */, +/* u i n x l */ HI(31) | LO(23) /* lwzx */, + +/* u i w i s */ HI(37) /* stwu */, +/* u i w i l */ HI(33) /* lwzu */, +/* u i w x s */ HI(31) | LO(183) /* stwux */, +/* u i w x l */ HI(31) | LO(55) /* lwzux */, + +/* -------- Signed -------- */ + +/* Word. */ + +/* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), +/* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), +/* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), +/* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), + +/* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), +/* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), +/* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), +/* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), + +/* Byte. */ + +/* s b n i s */ HI(38) /* stb */, +/* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */, +/* s b n x s */ HI(31) | LO(215) /* stbx */, +/* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */, + +/* s b w i s */ HI(39) /* stbu */, +/* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */, +/* s b w x s */ HI(31) | LO(247) /* stbux */, +/* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */, + +/* Half. */ + +/* s h n i s */ HI(44) /* sth */, +/* s h n i l */ HI(42) /* lha */, +/* s h n x s */ HI(31) | LO(407) /* sthx */, +/* s h n x l */ HI(31) | LO(343) /* lhax */, + +/* s h w i s */ HI(45) /* sthu */, +/* s h w i l */ HI(43) /* lhau */, +/* s h w x s */ HI(31) | LO(439) /* sthux */, +/* s h w x l */ HI(31) | LO(375) /* lhaux */, + +/* Int. */ + +/* s i n i s */ HI(36) /* stw */, +/* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x2 /* lwa */), +/* s i n x s */ HI(31) | LO(151) /* stwx */, +/* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */), + +/* s i w i s */ HI(37) /* stwu */, +/* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | UPDATE_REQ | 0x2 /* lwa */), +/* s i w x s */ HI(31) | LO(183) /* stwux */, +/* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */), + +/* -------- Double -------- */ + +/* d n i s */ HI(54) /* stfd */, +/* d n i l */ HI(50) /* lfd */, +/* d n x s */ HI(31) | LO(727) /* stfdx */, +/* d n x l */ HI(31) | LO(599) /* lfdx */, + +/* s n i s */ HI(52) /* stfs */, +/* s n i l */ HI(48) /* lfs */, +/* s n x s */ HI(31) | LO(663) /* stfsx */, +/* s n x l */ HI(31) | LO(535) /* lfsx */, + +}; + +#undef ARCH_32_64 + +/* Simple cases, (no caching is required). */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_ins inst; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_si 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, reg) | IMM(argw)); + return -1; + } +#endif + return 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B((arg >> 4) & 0xf)); + return -1; + } + return 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those operator always + uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); + + if (!(arg & 0xf)) + return (next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX); + + if (arg & 0xf0) + return ((arg & 0xf0) == (next_arg & 0xf0) && (argw & 0x3) == (next_argw & 0x3)); + + 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 sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_r; + sljit_ins inst; + + SLJIT_ASSERT(arg & SLJIT_MEM); + + tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1; + /* Special case for "mov reg, [reg, ... ]". */ + if ((arg & 0xf) == tmp_r) + tmp_r = TMP_REG1; + + 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r)); + } + + if (SLJIT_UNLIKELY(arg & 0xf0)) { + argw &= 0x3; + /* Otherwise getput_arg_fast would capture it. */ + SLJIT_ASSERT(argw); + + if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg && argw == compiler->cache_argw) + tmp_r = TMP_REG3; + else { + if ((arg & 0xf0) == (next_arg & 0xf0) && argw == (next_argw & 0x3)) { + compiler->cache_arg = SLJIT_MEM | (arg & 0xf0); + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } +#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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(tmp_r)); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si input_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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. */ + sljit_si dst_r; + sljit_si src1_r; + sljit_si src2_r; + sljit_si sugg_src2_r = TMP_REG2; + sljit_si flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); + + if (!(input_flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } + + /* Destination check. */ + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } + else if (dst <= ZERO_REG) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } + else { + SLJIT_ASSERT(dst & SLJIT_MEM); + if (getput_arg_fast(compiler, input_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 <= ZERO_REG) { + src1_r = src1; + flags |= REG1_SOURCE; + } + else if (src1 & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); + src1_r = TMP_REG1; + } + else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1_r = TMP_REG1; + } + else + src1_r = 0; + + /* Source 2. */ + if (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) { + FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); + src2_r = sugg_src2_r; + } + else if (getput_arg_fast(compiler, input_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, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, input_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, input_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, input_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, input_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, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); + src1_r = TMP_REG1; + } + + if (src2_r == 0) { + FAIL_IF(getput_arg(compiler, input_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, input_flags, dst_r, dst, dstw)); + else + FAIL_IF(getput_arg(compiler, input_flags, dst_r, dst, dstw, 0, 0)); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si 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_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG1))); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)); +#else + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)); +#endif + case SLJIT_UDIV: + case SLJIT_SDIV: + FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_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_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); + } + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); +#else + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); +#endif + } + + return SLJIT_SUCCESS; +} + +#define EMIT_MOV(type, type_flags, type_cast) \ + emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw) + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; + sljit_si op_flags = GET_ALL_FLAGS(op); + + CHECK_ERROR(); + check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + op = GET_OPCODE(op); + if ((src & SLJIT_IMM) && srcw == 0) + src = ZERO_REG; + + if (op_flags & SLJIT_SET_O) + FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); + + if (op_flags & SLJIT_INT_OP) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { + if (src <= ZERO_REG && src == dst) { + if (!TYPE_CAST_NEEDED(op)) + return SLJIT_SUCCESS; + } +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) + op = SLJIT_MOV_UI; + if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) + op = SLJIT_MOVU_UI; + if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) + op = SLJIT_MOV_SI; + if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) + op = SLJIT_MOVU_SI; +#endif + } +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + else { + /* Most operations expect sign extended arguments. */ + flags |= INT_DATA | SIGNED_DATA; + if (src & SLJIT_IMM) + srcw = (sljit_si)srcw; + } +#endif + } + + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: +#endif + return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + case SLJIT_MOV_UI: + return EMIT_MOV(SLJIT_MOV_UI, INT_DATA, (sljit_ui)); + + case SLJIT_MOV_SI: + return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, (sljit_si)); +#endif + + case SLJIT_MOV_UB: + return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA, (sljit_ub)); + + case SLJIT_MOV_SB: + return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, (sljit_sb)); + + case SLJIT_MOV_UH: + return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA, (sljit_uh)); + + case SLJIT_MOV_SH: + return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, (sljit_sh)); + + case SLJIT_MOVU: + case SLJIT_MOVU_P: +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: +#endif + return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + case SLJIT_MOVU_UI: + return EMIT_MOV(SLJIT_MOV_UI, INT_DATA | WRITE_BACK, (sljit_ui)); + + case SLJIT_MOVU_SI: + return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_si)); +#endif + + case SLJIT_MOVU_UB: + return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, (sljit_ub)); + + case SLJIT_MOVU_SB: + return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sb)); + + case SLJIT_MOVU_UH: + return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, (sljit_uh)); + + case SLJIT_MOVU_SH: + return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sh)); + + case SLJIT_NOT: + return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: + return emit_op(compiler, SLJIT_NEG, 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, flags | (!(op_flags & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw); +#endif + } + + return SLJIT_SUCCESS; +} + +#undef EMIT_MOV + +#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 sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si 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) { + /* Most operations expect sign extended arguments. */ + flags |= INT_DATA | SIGNED_DATA; + if (src1 & SLJIT_IMM) + src1w = (sljit_si)(src1w); + if (src2 & SLJIT_IMM) + src2w = (sljit_si)(src2w); + if (GET_FLAGS(op)) + flags |= ALT_SIGN_EXT; + } +#endif + if (op & SLJIT_SET_O) + FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); + if (src2 == TMP_REG2) + flags |= ALT_KEEP_CACHE; + + 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, 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, 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, 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, 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, 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, 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, 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, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + return emit_op(compiler, SLJIT_ADD, flags, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_ADDC: + return emit_op(compiler, SLJIT_ADDC, 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, 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, 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, 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, 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, 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, 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, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + return emit_op(compiler, SLJIT_SUB, 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, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + return emit_op(compiler, SLJIT_SUB, 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, 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, flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUBC: + return emit_op(compiler, SLJIT_SUBC, 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) + flags |= ALT_FORM2; +#endif + if (!GET_FLAGS(op)) { + if (TEST_SL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_MUL, 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, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + return emit_op(compiler, SLJIT_MUL, 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), 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), 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), 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), 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), 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), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_ASHR: + if (op & SLJIT_KEEP_FLAGS) + flags |= ALT_FORM3; + /* Fall through. */ + case SLJIT_SHL: + case SLJIT_LSHR: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op & SLJIT_INT_OP) + flags |= ALT_FORM2; +#endif + if (src2 & SLJIT_IMM) { + compiler->imm = src2w; + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si 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 sljit_si sljit_is_fpu_available(void) +{ + /* Always available. */ + return 1; +} + +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6)) +#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (GET_OPCODE(op) == SLJIT_CMPD) { + if (dst > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw)); + dst = TMP_FREG1; + } + + if (src > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0)); + src = TMP_FREG2; + } + + return push_inst(compiler, FCMPU | CRD(4) | FA(dst) | FB(src)); + } + + dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + + if (src > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw)); + src = dst_fr; + } + + switch (GET_OPCODE(op)) { + case SLJIT_MOVD: + if (src != dst_fr && dst_fr != TMP_FREG1) + FAIL_IF(push_inst(compiler, FMR | FD(dst_fr) | FB(src))); + break; + case SLJIT_NEGD: + FAIL_IF(push_inst(compiler, FNEG | FD(dst_fr) | FB(src))); + break; + case SLJIT_ABSD: + FAIL_IF(push_inst(compiler, FABS | FD(dst_fr) | FB(src))); + break; + } + + if (dst_fr == TMP_FREG1) { + if (GET_OPCODE(op) == SLJIT_MOVD) + dst_fr = src; + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_fr, dst, dstw, 0, 0)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_fr, flags = 0; + + 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_REG6) ? TMP_FREG2 : dst; + + if (src1 > SLJIT_FLOAT_REG6) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1 = TMP_FREG1; + } else + flags |= ALT_FORM1; + } + + if (src2 > SLJIT_FLOAT_REG6) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { + FAIL_IF(compiler->error); + src2 = TMP_FREG2; + } else + flags |= ALT_FORM2; + } + + if ((flags & (ALT_FORM1 | ALT_FORM2)) == (ALT_FORM1 | ALT_FORM2)) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + } + } + else if (flags & ALT_FORM1) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + else if (flags & ALT_FORM2) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + + if (flags & ALT_FORM1) + src1 = TMP_FREG1; + if (flags & ALT_FORM2) + src2 = TMP_FREG2; + + switch (GET_OPCODE(op)) { + case SLJIT_ADDD: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_fr) | FA(src1) | FB(src2))); + break; + + case SLJIT_SUBD: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_fr) | FA(src1) | FB(src2))); + break; + + case SLJIT_MULD: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_fr) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); + break; + + case SLJIT_DIVD: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_fr) | FA(src1) | FB(src2))); + break; + } + + if (dst_fr == TMP_FREG2) + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); + + return SLJIT_SUCCESS; +} + +#undef FLOAT_DATA +#undef SELECT_FOP + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + 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) + return SLJIT_SUCCESS; + + if (dst <= ZERO_REG) + return push_inst(compiler, MFLR | D(dst)); + + /* Memory. */ + 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); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src <= ZERO_REG) + 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(sljit_si 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_UNORDERED: + return (12 << 21) | ((4 + 3) << 16); + + case SLJIT_C_FLOAT_ORDERED: + 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, sljit_si 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(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 sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + struct sljit_jump *jump = NULL; + sljit_si src_r; + + CHECK_ERROR(); + check_sljit_emit_ijump(compiler, type, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src <= ZERO_REG) + 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 | (20 << 21) | (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 sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si reg, input_flags; + sljit_si flags = GET_ALL_FLAGS(op); + + CHECK_ERROR(); + check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + reg = (op < SLJIT_ADD && dst <= ZERO_REG) ? dst : TMP_REG2; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + input_flags = (flags & SLJIT_INT_OP) ? INT_DATA : WORD_DATA; +#else + input_flags = WORD_DATA; +#endif + FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } + + 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_UNORDERED: + GET_CR_BIT(4 + 3, reg); + break; + + case SLJIT_C_FLOAT_ORDERED: + GET_CR_BIT(4 + 3, reg); + INVERT_BIT(reg); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + + if (op < SLJIT_ADD) { +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op == SLJIT_MOV) + input_flags = WORD_DATA; + else { + op = SLJIT_MOV_UI; + input_flags = INT_DATA; + } +#else + op = SLJIT_MOV; + input_flags = WORD_DATA; +#endif + return (reg == TMP_REG2) ? emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0) : SLJIT_SUCCESS; + } + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, op | flags, dst, dstw, src, srcw, TMP_REG2, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si 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 <= ZERO_REG) ? 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 --git a/tools/pcre/sljit/sljitNativeSPARC_32.c b/tools/pcre/sljit/sljitNativeSPARC_32.c new file mode 100644 index 00000000..80479bfe --- /dev/null +++ b/tools/pcre/sljit/sljitNativeSPARC_32.c @@ -0,0 +1,164 @@ +/* + * 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. + */ + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw imm) +{ + if (imm <= SIMM_MAX && imm >= SIMM_MIN) + return push_inst(compiler, OR | D(dst) | S1(0) | IMM(imm), DR(dst)); + + FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((imm >> 10) & 0x3fffff), DR(dst))); + return (imm & 0x3ff) ? push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (imm & 0x3ff), DR(dst)) : SLJIT_SUCCESS; +} + +#define ARG2(flags, src2) ((flags & SRC2_IMM) ? IMM(src2) : S2(src2)) + +static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_sw src2) +{ + SLJIT_COMPILE_ASSERT(ICC_IS_SET == SET_FLAGS, icc_is_set_and_set_flags_must_be_the_same); + + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (dst != src2) + return push_inst(compiler, OR | D(dst) | S1(0) | S2(src2), DR(dst)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_UB) + return push_inst(compiler, AND | D(dst) | S1(src2) | IMM(0xff), DR(dst)); + FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(24), DR(dst))); + return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), 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 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(16), DR(dst))); + return push_inst(compiler, (op == SLJIT_MOV_SH ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + return push_inst(compiler, XNOR | (flags & SET_FLAGS) | D(dst) | S1(0) | S2(src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + /* sparc 32 does not support SLJIT_KEEP_FLAGS. Not sure I can fix this. */ + FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(src2) | S2(0), SET_FLAGS)); + FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2(src2), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, BICC | DA(0x1) | (7 & DISP_MASK), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(0) | IMM(32), UNMOVABLE_INS | (flags & SET_FLAGS))); + FAIL_IF(push_inst(compiler, OR | D(dst) | S1(0) | IMM(-1), DR(dst))); + + /* Loop. */ + FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(0), SET_FLAGS)); + FAIL_IF(push_inst(compiler, SLL | D(TMP_REG1) | S1(TMP_REG1) | IMM(1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, BICC | DA(0xe) | (-2 & DISP_MASK), UNMOVABLE_INS)); + return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(dst) | IMM(1), UNMOVABLE_INS | (flags & SET_FLAGS)); + + case SLJIT_ADD: + return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_ADDC: + return push_inst(compiler, ADDC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_SUB: + return push_inst(compiler, SUB | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_SUBC: + return push_inst(compiler, SUBC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_MUL: + FAIL_IF(push_inst(compiler, SMUL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); + if (!(flags & SET_FLAGS)) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(dst) | IMM(31), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, RDY | D(TMP_REG4), DR(TMP_REG4))); + return push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(TMP_REG4), MOVABLE_INS | SET_FLAGS); + + case SLJIT_AND: + return push_inst(compiler, AND | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_OR: + return push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_XOR: + return push_inst(compiler, XOR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS)); + + case SLJIT_SHL: + FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); + return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS); + + case SLJIT_LSHR: + FAIL_IF(push_inst(compiler, SRL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); + return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS); + + case SLJIT_ASHR: + FAIL_IF(push_inst(compiler, SRA | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst))); + return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS); + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +{ + FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((init_value >> 10) & 0x3fffff), DR(dst))); + return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst)); +} + +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] & 0xffc00000) | ((new_addr >> 10) & 0x3fffff); + inst[1] = (inst[1] & 0xfffffc00) | (new_addr & 0x3ff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff); + inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} diff --git a/tools/pcre/sljit/sljitNativeSPARC_common.c b/tools/pcre/sljit/sljitNativeSPARC_common.c new file mode 100644 index 00000000..c6522be2 --- /dev/null +++ b/tools/pcre/sljit/sljitNativeSPARC_common.c @@ -0,0 +1,1348 @@ +/* + * 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(void) +{ + return "SPARC" SLJIT_CPUINFO; +} + +/* Length of an instruction word + Both for sparc-32 and sparc-64 */ +typedef sljit_ui sljit_ins; + +static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) +{ + if (SLJIT_UNLIKELY(from == to)) + return; + + do { + __asm__ volatile ( + "flush %0\n" + : : "r"(from) + ); + /* Operates at least on doubleword. */ + from += 2; + } while (from < to); + + if (from == to) { + /* Flush the last word. */ + to --; + __asm__ volatile ( + "flush %0\n" + : : "r"(to) + ); + } +} + +/* TMP_REG2 is not used by getput_arg */ +#define TMP_REG1 (SLJIT_NO_REGISTERS + 1) +#define TMP_REG2 (SLJIT_NO_REGISTERS + 2) +#define TMP_REG3 (SLJIT_NO_REGISTERS + 3) +#define TMP_REG4 (SLJIT_NO_REGISTERS + 4) +#define LINK_REG (SLJIT_NO_REGISTERS + 5) + +#define TMP_FREG1 (0) +#define TMP_FREG2 ((SLJIT_FLOAT_REG6 + 1) << 1) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 7] = { + 0, 8, 9, 10, 11, 12, 16, 17, 18, 19, 20, 14, 1, 24, 25, 26, 15 +}; + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +#define D(d) (reg_map[d] << 25) +#define DA(d) ((d) << 25) +#define S1(s1) (reg_map[s1] << 14) +#define S2(s2) (reg_map[s2]) +#define S1A(s1) ((s1) << 14) +#define S2A(s2) (s2) +#define IMM_ARG 0x2000 +#define DOP(op) ((op) << 5) +#define IMM(imm) (((imm) & 0x1fff) | IMM_ARG) + +#define DR(dr) (reg_map[dr]) +#define OPC1(opcode) ((opcode) << 30) +#define OPC2(opcode) ((opcode) << 22) +#define OPC3(opcode) ((opcode) << 19) +#define SET_FLAGS OPC3(0x10) + +#define ADD (OPC1(0x2) | OPC3(0x00)) +#define ADDC (OPC1(0x2) | OPC3(0x08)) +#define AND (OPC1(0x2) | OPC3(0x01)) +#define ANDN (OPC1(0x2) | OPC3(0x05)) +#define CALL (OPC1(0x1)) +#define FABSS (OPC1(0x2) | OPC3(0x34) | DOP(0x09)) +#define FADDD (OPC1(0x2) | OPC3(0x34) | DOP(0x42)) +#define FADDS (OPC1(0x2) | OPC3(0x34) | DOP(0x41)) +#define FCMPD (OPC1(0x2) | OPC3(0x35) | DOP(0x52)) +#define FCMPS (OPC1(0x2) | OPC3(0x35) | DOP(0x51)) +#define FDIVD (OPC1(0x2) | OPC3(0x34) | DOP(0x4e)) +#define FDIVS (OPC1(0x2) | OPC3(0x34) | DOP(0x4d)) +#define FMOVS (OPC1(0x2) | OPC3(0x34) | DOP(0x01)) +#define FMULD (OPC1(0x2) | OPC3(0x34) | DOP(0x4a)) +#define FMULS (OPC1(0x2) | OPC3(0x34) | DOP(0x49)) +#define FNEGS (OPC1(0x2) | OPC3(0x34) | DOP(0x05)) +#define FSUBD (OPC1(0x2) | OPC3(0x34) | DOP(0x46)) +#define FSUBS (OPC1(0x2) | OPC3(0x34) | DOP(0x45)) +#define JMPL (OPC1(0x2) | OPC3(0x38)) +#define NOP (OPC1(0x0) | OPC2(0x04)) +#define OR (OPC1(0x2) | OPC3(0x02)) +#define ORN (OPC1(0x2) | OPC3(0x06)) +#define RDY (OPC1(0x2) | OPC3(0x28) | S1A(0)) +#define RESTORE (OPC1(0x2) | OPC3(0x3d)) +#define SAVE (OPC1(0x2) | OPC3(0x3c)) +#define SETHI (OPC1(0x0) | OPC2(0x04)) +#define SLL (OPC1(0x2) | OPC3(0x25)) +#define SLLX (OPC1(0x2) | OPC3(0x25) | (1 << 12)) +#define SRA (OPC1(0x2) | OPC3(0x27)) +#define SRAX (OPC1(0x2) | OPC3(0x27) | (1 << 12)) +#define SRL (OPC1(0x2) | OPC3(0x26)) +#define SRLX (OPC1(0x2) | OPC3(0x26) | (1 << 12)) +#define SUB (OPC1(0x2) | OPC3(0x04)) +#define SUBC (OPC1(0x2) | OPC3(0x0c)) +#define TA (OPC1(0x2) | OPC3(0x3a) | (8 << 25)) +#define WRY (OPC1(0x2) | OPC3(0x30) | DA(0)) +#define XOR (OPC1(0x2) | OPC3(0x03)) +#define XNOR (OPC1(0x2) | OPC3(0x07)) + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#define MAX_DISP (0x1fffff) +#define MIN_DISP (-0x200000) +#define DISP_MASK (0x3fffff) + +#define BICC (OPC1(0x0) | OPC2(0x2)) +#define FBFCC (OPC1(0x0) | OPC2(0x6)) +#define SLL_W SLL +#define SDIV (OPC1(0x2) | OPC3(0x0f)) +#define SMUL (OPC1(0x2) | OPC3(0x0b)) +#define UDIV (OPC1(0x2) | OPC3(0x0e)) +#define UMUL (OPC1(0x2) | OPC3(0x0a)) +#else +#define SLL_W SLLX +#endif + +#define SIMM_MAX (0x0fff) +#define SIMM_MIN (-0x1000) + +/* dest_reg is the absolute name of the register + Useful for reordering instructions in the delay slot. */ +static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) +{ + sljit_ins *ptr; + SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS + || (delay_slot & DST_INS_MASK) == MOVABLE_INS + || (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f)); + 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* optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_sw 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 (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + if (jump->flags & IS_CALL) { + /* Call is always patchable on sparc 32. */ + jump->flags |= PATCH_CALL; + if (jump->flags & IS_MOVABLE) { + inst[0] = inst[-1]; + inst[-1] = CALL; + jump->addr -= sizeof(sljit_ins); + return inst; + } + inst[0] = CALL; + inst[1] = NOP; + return inst + 1; + } +#else + /* Both calls and BPr instructions shall not pass this point. */ +#error "Implementation required" +#endif + + if (jump->flags & IS_COND) + inst--; + + if (jump->flags & IS_MOVABLE) { + diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1)) >> 2; + if (diff <= MAX_DISP && diff >= MIN_DISP) { + jump->flags |= PATCH_B; + inst--; + if (jump->flags & IS_COND) { + saved_inst = inst[0]; + inst[0] = inst[1] ^ (1 << 28); + inst[1] = saved_inst; + } else { + inst[1] = inst[0]; + inst[0] = BICC | DA(0x8); + } + jump->addr = (sljit_uw)inst; + return inst + 1; + } + } + + diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2; + if (diff <= MAX_DISP && diff >= MIN_DISP) { + jump->flags |= PATCH_B; + if (jump->flags & IS_COND) + inst[0] ^= (1 << 28); + else + inst[0] = BICC | DA(0x8); + inst[1] = NOP; + jump->addr = (sljit_uw)inst; + return inst + 1; + } + + return code_ptr; +} + +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_SPARC_32 && SLJIT_CONFIG_SPARC_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 <= (sljit_si)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_CALL) { + addr = (sljit_sw)(addr - jump->addr) >> 2; + SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000); + buf_ptr[0] = CALL | (addr & 0x3fffffff); + break; + } + if (jump->flags & PATCH_B) { + addr = (sljit_sw)(addr - jump->addr) >> 2; + SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP); + buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK); + break; + } + + /* Set the fields of immediate loads. */ +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff); + buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff); +#else +#error "Implementation required" +#endif + } while (0); + jump = jump->next; + } + + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = compiler->size * sizeof(sljit_ins); + SLJIT_CACHE_FLUSH(code, code_ptr); + return code; +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +/* Creates an index in data_transfer_insts array. */ +#define LOAD_DATA 0x01 +#define WORD_DATA 0x00 +#define BYTE_DATA 0x02 +#define HALF_DATA 0x04 +#define INT_DATA 0x06 +#define SIGNED_DATA 0x08 +/* Separates integer and floating point registers */ +#define GPR_REG 0x0f +#define DOUBLE_DATA 0x10 + +#define MEM_MASK 0x1f + +#define WRITE_BACK 0x00020 +#define ARG_TEST 0x00040 +#define ALT_KEEP_CACHE 0x00080 +#define CUMULATIVE_OP 0x00100 +#define IMM_OP 0x00200 +#define SRC2_IMM 0x00400 + +#define REG_DEST 0x00800 +#define REG2_SOURCE 0x01000 +#define SLOW_SRC1 0x02000 +#define SLOW_SRC2 0x04000 +#define SLOW_DEST 0x08000 + +/* SET_FLAGS (0x10 << 19) also belong here! */ + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#include "sljitNativeSPARC_32.c" +#else +#include "sljitNativeSPARC_64.c" +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + local_size += 23 * sizeof(sljit_sw); + local_size = (local_size + 7) & ~0x7; + compiler->local_size = local_size; + + if (local_size <= SIMM_MAX) { + FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_LOCALS_REG) | S1(SLJIT_LOCALS_REG) | IMM(-local_size), UNMOVABLE_INS)); + } + else { + FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size)); + FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_LOCALS_REG) | S1(SLJIT_LOCALS_REG) | S2(TMP_REG1), UNMOVABLE_INS)); + } + + if (args >= 1) + FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG1) | S1(0) | S2A(24), DR(SLJIT_SAVED_REG1))); + if (args >= 2) + FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG2) | S1(0) | S2A(25), DR(SLJIT_SAVED_REG2))); + if (args >= 3) + FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG3) | S1(0) | S2A(26), DR(SLJIT_SAVED_REG3))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + local_size += 23 * sizeof(sljit_sw); + compiler->local_size = (local_size + 7) & ~0x7; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + + if (op != SLJIT_MOV || !(src <= TMP_REG3)) { + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + src = SLJIT_SCRATCH_REG1; + } + + FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS)); + return push_inst(compiler, RESTORE | D(SLJIT_SCRATCH_REG1) | S1(src) | S2(0), UNMOVABLE_INS); +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#define ARCH_32_64(a, b) a +#else +#define ARCH_32_64(a, b) b +#endif + +static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { +/* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */), +/* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */), +/* u b s */ OPC1(3) | OPC3(0x05) /* stb */, +/* u b l */ OPC1(3) | OPC3(0x01) /* ldub */, +/* u h s */ OPC1(3) | OPC3(0x06) /* sth */, +/* u h l */ OPC1(3) | OPC3(0x02) /* lduh */, +/* u i s */ OPC1(3) | OPC3(0x04) /* stw */, +/* u i l */ OPC1(3) | OPC3(0x00) /* lduw */, + +/* s w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */), +/* s w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */), +/* s b s */ OPC1(3) | OPC3(0x05) /* stb */, +/* s b l */ OPC1(3) | OPC3(0x09) /* ldsb */, +/* s h s */ OPC1(3) | OPC3(0x06) /* sth */, +/* s h l */ OPC1(3) | OPC3(0x0a) /* ldsh */, +/* s i s */ OPC1(3) | OPC3(0x04) /* stw */, +/* s i l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x08) /* ldsw */), + +/* d s */ OPC1(3) | OPC3(0x27), +/* d l */ OPC1(3) | OPC3(0x23), +/* s s */ OPC1(3) | OPC3(0x24), +/* s l */ OPC1(3) | OPC3(0x20), +}; + +#undef ARCH_32_64 + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (!(flags & WRITE_BACK) || !(arg & 0xf)) { + if ((!(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) + || ((arg & 0xf0) && (argw & 0x3) == 0)) { + /* Works for both absoulte and relative addresses (immediate case). */ + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] + | ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg)) + | S1(arg & 0xf) | ((arg & 0xf0) ? S2((arg >> 4) & 0xf) : IMM(argw)), + ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS)); + return -1; + } + } + return 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); + + /* Simple operation except for updates. */ + if (arg & 0xf0) { + argw &= 0x3; + SLJIT_ASSERT(argw); + next_argw &= 0x3; + if ((arg & 0xf0) == (next_arg & 0xf0) && argw == next_argw) + return 1; + return 0; + } + + if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)) + return 1; + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si base, arg2, delay_slot; + sljit_ins dest; + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(next_arg & SLJIT_MEM)) { + next_arg = 0; + next_argw = 0; + } + + base = arg & 0xf; + if (SLJIT_UNLIKELY(arg & 0xf0)) { + argw &= 0x3; + SLJIT_ASSERT(argw != 0); + + /* Using the cache. */ + if (((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) && (argw == compiler->cache_argw)) + arg2 = TMP_REG3; + else { + if ((arg & 0xf0) == (next_arg & 0xf0) && argw == (next_argw & 0x3)) { + compiler->cache_arg = SLJIT_MEM | (arg & 0xf0); + compiler->cache_argw = argw; + arg2 = TMP_REG3; + } + else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && (reg << 4) != (arg & 0xf0)) + arg2 = reg; + else /* It must be a mov operation, so tmp1 must be free to use. */ + arg2 = TMP_REG1; + FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1((arg >> 4) & 0xf) | IMM_ARG | argw, DR(arg2))); + } + } + else { + /* Using the cache. */ + 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, ADD | D(TMP_REG3) | S1(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); + compiler->cache_argw = argw; + } + arg2 = TMP_REG3; + } else { + if ((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN) { + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + arg2 = TMP_REG3; + } + else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base) + arg2 = reg; + else /* It must be a mov operation, so tmp1 must be free to use. */ + arg2 = TMP_REG1; + FAIL_IF(load_immediate(compiler, arg2, argw)); + } + } + + dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg)); + delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS; + if (!base) + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot); + if (!(flags & WRITE_BACK)) + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot); + FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot)); + return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base)); +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw 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); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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. */ + sljit_si dst_r = TMP_REG2; + sljit_si src1_r; + sljit_sw src2_r = 0; + sljit_si sugg_src2_r = TMP_REG2; + + if (!(flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } + + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + } + else if (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_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw)) + flags |= SLOW_DEST; + + if (flags & IMM_OP) { + if ((src2 & SLJIT_IMM) && src2w) { + if (src2w <= SIMM_MAX && src2w >= SIMM_MIN) { + flags |= SRC2_IMM; + src2_r = src2w; + } + } + if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { + if (src1w <= SIMM_MAX && src1w >= SIMM_MIN) { + flags |= SRC2_IMM; + src2_r = src1w; + + /* And swap arguments. */ + src1 = src2; + src1w = src2w; + src2 = SLJIT_IMM; + /* src2w = src2_r unneeded. */ + } + } + } + + /* Source 1. */ + if (src1 <= TMP_REG3) + src1_r = src1; + else if (src1 & SLJIT_IMM) { + if (src1w) { + FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); + src1_r = TMP_REG1; + } + else + src1_r = 0; + } + else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC1; + src1_r = TMP_REG1; + } + + /* Source 2. */ + if (src2 <= TMP_REG3) { + 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 (!(flags & SRC2_IMM)) { + if (src2w) { + FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); + src2_r = sugg_src2_r; + } + else { + src2_r = 0; + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + dst_r = 0; + } + } + } + else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, 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, TMP_REG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, 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, dst_r, dst, dstw); + return compiler->error; + } + return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + CHECK_ERROR(); + check_sljit_emit_op0(compiler, op); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + return push_inst(compiler, TA, UNMOVABLE_INS); + case SLJIT_NOP: + return push_inst(compiler, NOP, UNMOVABLE_INS); + case SLJIT_UMUL: + case SLJIT_SMUL: +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? UMUL : SMUL) | D(SLJIT_SCRATCH_REG1) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG1))); + return push_inst(compiler, RDY | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)); +#else +#error "Implementation required" +#endif + case SLJIT_UDIV: + case SLJIT_SDIV: +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + if (op == SLJIT_UDIV) + FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS)); + else { + FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_SCRATCH_REG1) | IMM(31), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS)); + } + FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_SCRATCH_REG1), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? UDIV : SDIV) | D(SLJIT_SCRATCH_REG1) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG1))); + FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_SCRATCH_REG2) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, SUB | D(SLJIT_SCRATCH_REG2) | S1(TMP_REG2) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2))); + return SLJIT_SUCCESS; +#else +#error "Implementation required" +#endif + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si flags = GET_FLAGS(op) ? 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); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: + return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UI: + return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_SI: + return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UB: + return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + + case SLJIT_MOV_SB: + return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + + case SLJIT_MOV_UH: + return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + + case SLJIT_MOV_SH: + return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + + case SLJIT_MOVU: + case SLJIT_MOVU_P: + return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UI: + return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_SI: + return emit_op(compiler, SLJIT_MOV_SI, 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, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + + case SLJIT_MOVU_SB: + return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + + case SLJIT_MOVU_UH: + return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + + case SLJIT_MOVU_SH: + return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + + case SLJIT_NOT: + case SLJIT_CLZ: + return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: + return emit_op(compiler, SLJIT_SUB, flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si flags = GET_FLAGS(op) ? 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); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_ADD: + case SLJIT_ADDC: + case SLJIT_MUL: + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUB: + case SLJIT_SUBC: + return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SHL: + case SLJIT_LSHR: + case SLJIT_ASHR: +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + if (src2 & SLJIT_IMM) + src2w &= 0x1f; +#else + SLJIT_ASSERT_STOP(); +#endif + return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si 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 sljit_si sljit_is_fpu_available(void) +{ + return 1; +} + +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) +#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (GET_OPCODE(op) == SLJIT_CMPD) { + if (dst > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw)); + dst = TMP_FREG1; + } + else + dst <<= 1; + + if (src > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0)); + src = TMP_FREG2; + } + else + src <<= 1; + + return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(dst) | S2A(src), FCC_IS_SET | MOVABLE_INS); + } + + dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : (dst << 1); + + if (src > SLJIT_FLOAT_REG6) { + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw)); + src = dst_fr; + } + else + src <<= 1; + + switch (GET_OPCODE(op)) { + case SLJIT_MOVD: + if (src != dst_fr && dst_fr != TMP_FREG1) { + FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr) | S2A(src), MOVABLE_INS)); + if (!(op & SLJIT_SINGLE_OP)) + FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS)); + } + break; + case SLJIT_NEGD: + FAIL_IF(push_inst(compiler, FNEGS | DA(dst_fr) | S2A(src), MOVABLE_INS)); + if (dst_fr != src && !(op & SLJIT_SINGLE_OP)) + FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS)); + break; + case SLJIT_ABSD: + FAIL_IF(push_inst(compiler, FABSS | DA(dst_fr) | S2A(src), MOVABLE_INS)); + if (dst_fr != src && !(op & SLJIT_SINGLE_OP)) + FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS)); + break; + } + + if (dst_fr == TMP_FREG1) { + if (GET_OPCODE(op) == SLJIT_MOVD) + dst_fr = src; + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_fr, dst, dstw, 0, 0)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_fr, flags = 0; + + 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_REG6) ? TMP_FREG2 : (dst << 1); + + if (src1 > SLJIT_FLOAT_REG6) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1 = TMP_FREG1; + } else + flags |= SLOW_SRC1; + } + else + src1 <<= 1; + + if (src2 > SLJIT_FLOAT_REG6) { + if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { + FAIL_IF(compiler->error); + src2 = TMP_FREG2; + } else + flags |= SLOW_SRC2; + } + else + src2 <<= 1; + + 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, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); + + if (flags & SLOW_SRC1) + src1 = TMP_FREG1; + if (flags & SLOW_SRC2) + src2 = TMP_FREG2; + + switch (GET_OPCODE(op)) { + case SLJIT_ADDD: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS)); + break; + + case SLJIT_SUBD: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS)); + break; + + case SLJIT_MULD: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS)); + break; + + case SLJIT_DIVD: + FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS)); + break; + } + + if (dst_fr == TMP_FREG2) + FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); + + return SLJIT_SUCCESS; +} + +#undef FLOAT_DATA +#undef SELECT_FOP + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + 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) + return SLJIT_SUCCESS; + + if (dst <= TMP_REG3) + return push_inst(compiler, OR | D(dst) | S1(0) | S2(LINK_REG), DR(dst)); + + /* Memory. */ + return emit_op_mem(compiler, WORD_DATA, LINK_REG, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src <= TMP_REG3) + FAIL_IF(push_inst(compiler, OR | D(LINK_REG) | S1(0) | S2(src), DR(LINK_REG))); + else if (src & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, LINK_REG, src, srcw)); + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, LINK_REG, srcw)); + + FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(LINK_REG) | IMM(8), 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; +} + +static sljit_ins get_cc(sljit_si type) +{ + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_MUL_NOT_OVERFLOW: + return DA(0x1); + + case SLJIT_C_NOT_EQUAL: + case SLJIT_C_MUL_OVERFLOW: + return DA(0x9); + + case SLJIT_C_LESS: + return DA(0x5); + + case SLJIT_C_GREATER_EQUAL: + return DA(0xd); + + case SLJIT_C_GREATER: + return DA(0xc); + + case SLJIT_C_LESS_EQUAL: + return DA(0x4); + + case SLJIT_C_SIG_LESS: + return DA(0x3); + + case SLJIT_C_SIG_GREATER_EQUAL: + return DA(0xb); + + case SLJIT_C_SIG_GREATER: + return DA(0xa); + + case SLJIT_C_SIG_LESS_EQUAL: + return DA(0x2); + + case SLJIT_C_OVERFLOW: + return DA(0x7); + + case SLJIT_C_NOT_OVERFLOW: + return DA(0xf); + + case SLJIT_C_FLOAT_EQUAL: + return DA(0x9); + + case SLJIT_C_FLOAT_NOT_EQUAL: /* Unordered. */ + return DA(0x1); + + case SLJIT_C_FLOAT_LESS: + return DA(0x4); + + case SLJIT_C_FLOAT_GREATER_EQUAL: /* Unordered. */ + return DA(0xc); + + case SLJIT_C_FLOAT_LESS_EQUAL: + return DA(0xd); + + case SLJIT_C_FLOAT_GREATER: /* Unordered. */ + return DA(0x5); + + case SLJIT_C_FLOAT_UNORDERED: + return DA(0x7); + + case SLJIT_C_FLOAT_ORDERED: + return DA(0xf); + + default: + SLJIT_ASSERT_STOP(); + return DA(0x8); + } +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si 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; + + if (type < SLJIT_C_FLOAT_EQUAL) { + jump->flags |= IS_COND; + if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET)) + jump->flags |= IS_MOVABLE; +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + PTR_FAIL_IF(push_inst(compiler, BICC | get_cc(type ^ 1) | 5, UNMOVABLE_INS)); +#else +#error "Implementation required" +#endif + } + else if (type < SLJIT_JUMP) { + jump->flags |= IS_COND; + if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & FCC_IS_SET)) + jump->flags |= IS_MOVABLE; +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + PTR_FAIL_IF(push_inst(compiler, FBFCC | get_cc(type ^ 1) | 5, UNMOVABLE_INS)); +#else +#error "Implementation required" +#endif + } else { + if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) + jump->flags |= IS_MOVABLE; + if (type >= SLJIT_FAST_CALL) + jump->flags |= IS_CALL; + } + + PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? LINK_REG : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + struct sljit_jump *jump = NULL; + sljit_si src_r; + + CHECK_ERROR(); + check_sljit_emit_ijump(compiler, type, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src <= TMP_REG3) + 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); + jump->u.target = srcw; + if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) + jump->flags |= IS_MOVABLE; + if (type >= SLJIT_FAST_CALL) + jump->flags |= IS_CALL; + + FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + src_r = TMP_REG2; + } + else { + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw)); + src_r = TMP_REG2; + } + + FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? LINK_REG : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS)); + if (jump) + jump->addr = compiler->size; + return push_inst(compiler, NOP, UNMOVABLE_INS); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0); + + CHECK_ERROR(); + check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + op = GET_OPCODE(op); + reg = (op < SLJIT_ADD && dst <= TMP_REG3) ? dst : TMP_REG2; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } + + if (type < SLJIT_C_FLOAT_EQUAL) + FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS)); + else + FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS)); + + FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS)); + + if (op >= SLJIT_ADD) + return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); + + return (reg == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; +#else +#error "Implementation required" +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + sljit_si reg; + struct sljit_const *const_; + + 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 <= TMP_REG3) ? dst : TMP_REG2; + + PTR_FAIL_IF(emit_const(compiler, reg, init_value)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); + + return const_; +} diff --git a/tools/pcre/sljit/sljitNativeX86_32.c b/tools/pcre/sljit/sljitNativeX86_32.c new file mode 100644 index 00000000..03a595bd --- /dev/null +++ b/tools/pcre/sljit/sljitNativeX86_32.c @@ -0,0 +1,547 @@ +/* + * 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 sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm) +{ + sljit_ub *inst; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw)); + FAIL_IF(!inst); + INC_SIZE(1 + sizeof(sljit_sw)); + *inst++ = opcode; + *(sljit_sw*)inst = imm; + return SLJIT_SUCCESS; +} + +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) +{ + if (type == SLJIT_JUMP) { + *code_ptr++ = JMP_i32; + jump->addr++; + } + else if (type >= SLJIT_FAST_CALL) { + *code_ptr++ = CALL_i32; + jump->addr++; + } + else { + *code_ptr++ = GROUP_0F; + *code_ptr++ = get_jump_code(type); + jump->addr += 2; + } + + if (jump->flags & JUMP_LABEL) + jump->flags |= PATCH_MW; + else + *(sljit_sw*)code_ptr = jump->u.target - (jump->addr + 4); + code_ptr += 4; + + return code_ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si size; + sljit_si locals_offset; + sljit_ub *inst; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + 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 + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + + INC_SIZE(size); + PUSH_REG(reg_map[TMP_REGISTER]); +#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (args > 0) { + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[TMP_REGISTER] << 3) | 0x4 /* esp */; + } +#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) { + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_SCRATCH_REG3]; + } + if (args > 1) { + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_SCRATCH_REG2]; + } + if (args > 2) { + *inst++ = MOV_r_rm; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x4 /* esp */; + *inst++ = 0x24; + *inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */ + } +#else + if (args > 0) { + *inst++ = MOV_r_rm; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER]; + *inst++ = sizeof(sljit_sw) * 2; + } + if (args > 1) { + *inst++ = MOV_r_rm; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER]; + *inst++ = sizeof(sljit_sw) * 3; + } + if (args > 2) { + *inst++ = MOV_r_rm; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER]; + *inst++ = sizeof(sljit_sw) * 4; + } +#endif + +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + locals_offset = 2 * sizeof(sljit_uw); +#else + SLJIT_COMPILE_ASSERT(FIXED_LOCALS_OFFSET >= 2 * sizeof(sljit_uw), require_at_least_two_words); + locals_offset = FIXED_LOCALS_OFFSET; +#endif + compiler->scratches_start = locals_offset; + if (scratches > 3) + locals_offset += (scratches - 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)); + + compiler->local_size = local_size; +#ifdef _WIN32 + if (local_size > 1024) { +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size)); +#else + local_size -= FIXED_LOCALS_OFFSET; + FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size)); + FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, + SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, FIXED_LOCALS_OFFSET)); +#endif + FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); + } +#endif + + SLJIT_ASSERT(local_size > 0); + return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, + SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si locals_offset; + + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; + compiler->args = args; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + locals_offset = 2 * sizeof(sljit_uw); +#else + locals_offset = FIXED_LOCALS_OFFSET; +#endif + compiler->scratches_start = locals_offset; + if (scratches > 3) + locals_offset += (scratches - 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 sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si size; + sljit_ub *inst; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + SLJIT_ASSERT(compiler->args >= 0); + + 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, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32, + 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 + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + + 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) + RET_I16(sizeof(sljit_sw)); + else + RET(); +#else + RET(); +#endif + + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +/* Size contains the flags as well. */ +static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, + /* The register or immediate operand. */ + sljit_si a, sljit_sw imma, + /* The general operand (not immediate). */ + sljit_si b, sljit_sw immb) +{ + sljit_ub *inst; + sljit_ub *buf_ptr; + sljit_si flags = size & ~0xf; + sljit_si 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)); + SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) + && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) + && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); +#endif + + size &= 0xf; + inst_size = size; + +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) + 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_sw); + else if (immb != 0 && !(b & 0xf0)) { + /* Immediate operand. */ + if (immb <= 127 && immb >= -128) + inst_size += sizeof(sljit_sb); + else + inst_size += sizeof(sljit_sw); + } + + 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_sw); + } + else + SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + PTR_FAIL_IF(!inst); + + /* Encoding the byte. */ + INC_SIZE(inst_size); +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + if (flags & EX86_PREF_F2) + *inst++ = 0xf2; + if (flags & EX86_PREF_F3) + *inst++ = 0xf3; +#endif + if (flags & EX86_PREF_66) + *inst++ = 0x66; + + buf_ptr = inst + size; + + /* Encode mod/rm byte. */ + if (!(flags & EX86_SHIFT_INS)) { + if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) + *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; + + 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) + *inst = GROUP_SHIFT_1; + else + *inst = GROUP_SHIFT_N; + } else + *inst = GROUP_SHIFT_CL; + *buf_ptr = 0; + } + + if (!(b & SLJIT_MEM)) +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_map[b] : b); +#else + *buf_ptr++ |= MOD_REG + 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_sw*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_sw); + } + } + } + else { + *buf_ptr++ |= 0x04; + *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3) | (immb << 6); + } + } + else { + *buf_ptr++ |= 0x05; + *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_sw); + } + + 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_sw*)buf_ptr = imma; + } + + return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); +} + +/* --------------------------------------------------------------------- */ +/* Call / return instructions */ +/* --------------------------------------------------------------------- */ + +static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) +{ + sljit_ub *inst; + +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); + FAIL_IF(!inst); + INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2); + + if (type >= SLJIT_CALL3) + PUSH_REG(reg_map[SLJIT_SCRATCH_REG3]); + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_SCRATCH_REG3] << 3) | reg_map[SLJIT_SCRATCH_REG1]; +#else + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0)); + FAIL_IF(!inst); + INC_SIZE(4 * (type - SLJIT_CALL0)); + + *inst++ = MOV_rm_r; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG1] << 3) | 0x4 /* SIB */; + *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG]; + *inst++ = 0; + if (type >= SLJIT_CALL2) { + *inst++ = MOV_rm_r; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG2] << 3) | 0x4 /* SIB */; + *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG]; + *inst++ = sizeof(sljit_sw); + } + if (type >= SLJIT_CALL3) { + *inst++ = MOV_rm_r; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG3] << 3) | 0x4 /* SIB */; + *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG]; + *inst++ = 2 * sizeof(sljit_sw); + } +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + sljit_ub *inst; + + CHECK_ERROR(); + check_sljit_emit_fast_enter(compiler, dst, dstw); + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + dst = TMP_REGISTER; + + if (dst <= TMP_REGISTER) { + /* Unused dest is possible here. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + + INC_SIZE(1); + POP_REG(reg_map[dst]); + return SLJIT_SUCCESS; + } + + /* Memory. */ + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = POP_rm; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + sljit_ub *inst; + + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + CHECK_EXTRA_REGS(src, srcw, (void)0); + + if (src <= TMP_REGISTER) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + FAIL_IF(!inst); + + INC_SIZE(1 + 1); + PUSH_REG(reg_map[src]); + } + else if (src & SLJIT_MEM) { + inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_FF; + *inst |= PUSH_rm; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + } + else { + /* SLJIT_IMM. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + FAIL_IF(!inst); + + INC_SIZE(5 + 1); + *inst++ = PUSH_i32; + *(sljit_sw*)inst = srcw; + inst += sizeof(sljit_sw); + } + + RET(); + return SLJIT_SUCCESS; +} diff --git a/tools/pcre/sljit/sljitNativeX86_64.c b/tools/pcre/sljit/sljitNativeX86_64.c new file mode 100644 index 00000000..28f04fdd --- /dev/null +++ b/tools/pcre/sljit/sljitNativeX86_64.c @@ -0,0 +1,810 @@ +/* + * 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 sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +{ + sljit_ub *inst; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw)); + FAIL_IF(!inst); + INC_SIZE(2 + sizeof(sljit_sw)); + *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); + *inst++ = MOV_r_i32 + (reg_map[reg] & 0x7); + *(sljit_sw*)inst = imm; + return SLJIT_SUCCESS; +} + +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) +{ + if (type < SLJIT_JUMP) { + /* Invert type. */ + *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++ = MOV_r_i32 + 1; + jump->addr = (sljit_uw)code_ptr; + + if (jump->flags & JUMP_LABEL) + jump->flags |= PATCH_MD; + else + *(sljit_sw*)code_ptr = jump->u.target; + + code_ptr += sizeof(sljit_sw); + *code_ptr++ = REX_B; + *code_ptr++ = GROUP_FF; + *code_ptr++ = (type >= SLJIT_FAST_CALL) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1); + + return code_ptr; +} + +static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type) +{ + sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si)); + + if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) { + *code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32; + *(sljit_sw*)code_ptr = delta; + } + else { + SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second); + *code_ptr++ = REX_W | REX_B; + *code_ptr++ = MOV_r_i32 + 1; + *(sljit_sw*)code_ptr = addr; + code_ptr += sizeof(sljit_sw); + *code_ptr++ = REX_B; + *code_ptr++ = GROUP_FF; + *code_ptr++ = (type == 2) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1); + } + + return code_ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si size, pushed_size; + sljit_ub *inst; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + 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_sw); +#ifndef _WIN64 + if (saveds >= 2) + size += saveds - 1; +#else + if (saveds >= 4) + size += saveds - 3; + if (scratches >= 5) { + size += (5 - 4) * 2; + pushed_size += sizeof(sljit_sw); + } +#endif + size += args * 3; + if (size > 0) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + + INC_SIZE(size); + if (saveds >= 5) { + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg); + *inst++ = 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); + *inst++ = 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); + *inst++ = 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); + *inst++ = 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 (scratches >= 5) { + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg); + *inst++ = REX_B; + PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]); + } +#endif + +#ifndef _WIN64 + if (args > 0) { + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7 /* rdi */; + } + if (args > 1) { + *inst++ = REX_W | REX_R; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6 /* rsi */; + } + if (args > 2) { + *inst++ = REX_W | REX_R; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2 /* rdx */; + } +#else + if (args > 0) { + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1 /* rcx */; + } + if (args > 1) { + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2 /* rdx */; + } + if (args > 2) { + *inst++ = REX_W | REX_B; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0 /* r8 */; + } +#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. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_si))); + FAIL_IF(!inst); + INC_SIZE(4 + (3 + sizeof(sljit_si))); + *inst++ = REX_W; + *inst++ = GROUP_BINARY_83; + *inst++ = MOD_REG | SUB | 4; + /* Pushed size must be divisible by 8. */ + SLJIT_ASSERT(!(pushed_size & 0x7)); + if (pushed_size & 0x8) { + *inst++ = 5 * sizeof(sljit_sw); + local_size -= 5 * sizeof(sljit_sw); + } else { + *inst++ = 4 * sizeof(sljit_sw); + local_size -= 4 * sizeof(sljit_sw); + } + /* Second instruction */ + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG1] < 8, temporary_reg1_is_loreg); + *inst++ = REX_W; + *inst++ = MOV_rm_i32; + *inst++ = MOD_REG | reg_lmap[SLJIT_SCRATCH_REG1]; + *(sljit_si*)inst = local_size; +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + 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) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *inst++ = REX_W; + *inst++ = GROUP_BINARY_83; + *inst++ = MOD_REG | SUB | 4; + *inst++ = local_size; + } + else { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); + FAIL_IF(!inst); + INC_SIZE(7); + *inst++ = REX_W; + *inst++ = GROUP_BINARY_81; + *inst++ = MOD_REG | SUB | 4; + *(sljit_si*)inst = local_size; + inst += sizeof(sljit_si); + } +#ifdef _WIN64 + /* Save xmm6 with MOVAPS instruction. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); + *inst++ = GROUP_0F; + *(sljit_si*)inst = 0x20247429; +#endif + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si pushed_size; + + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + 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_sw); +#ifdef _WIN64 + if (scratches >= 5) + pushed_size += sizeof(sljit_sw); +#endif + compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si size; + sljit_ub *inst; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + + compiler->flags_saved = 0; + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + +#ifdef _WIN64 + /* Restore xmm6 with MOVAPS instruction. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); + *inst++ = GROUP_0F; + *(sljit_si*)inst = 0x20247428; +#endif + SLJIT_ASSERT(compiler->local_size > 0); + if (compiler->local_size <= 127) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *inst++ = REX_W; + *inst++ = GROUP_BINARY_83; + *inst++ = MOD_REG | ADD | 4; + *inst = compiler->local_size; + } + else { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); + FAIL_IF(!inst); + INC_SIZE(7); + *inst++ = REX_W; + *inst++ = GROUP_BINARY_81; + *inst++ = MOD_REG | ADD | 4; + *(sljit_si*)inst = 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->scratches >= 5) + size += (5 - 4) * 2; +#endif + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + + INC_SIZE(size); + +#ifdef _WIN64 + if (compiler->scratches >= 5) { + *inst++ = 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 + *inst++ = REX_B; +#endif + POP_REG(reg_lmap[SLJIT_SAVED_REG2]); + } + if (compiler->saveds >= 3) { +#ifndef _WIN64 + *inst++ = REX_B; +#endif + POP_REG(reg_lmap[SLJIT_SAVED_REG3]); + } + if (compiler->saveds >= 4) { + *inst++ = REX_B; + POP_REG(reg_lmap[SLJIT_SAVED_EREG1]); + } + if (compiler->saveds >= 5) { + *inst++ = REX_B; + POP_REG(reg_lmap[SLJIT_SAVED_EREG2]); + } + + RET(); + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm) +{ + sljit_ub *inst; + sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + length); + FAIL_IF(!inst); + INC_SIZE(length); + if (rex) + *inst++ = rex; + *inst++ = opcode; + *(sljit_si*)inst = imm; + return SLJIT_SUCCESS; +} + +static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, + /* The register or immediate operand. */ + sljit_si a, sljit_sw imma, + /* The general operand (not immediate). */ + sljit_si b, sljit_sw immb) +{ + sljit_ub *inst; + sljit_ub *buf_ptr; + sljit_ub rex = 0; + sljit_si flags = size & ~0xf; + sljit_si 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)); + SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) + && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) + && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); +#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 | EX86_PREF_F3)) + 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_si); /* 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_sb); + else + inst_size += sizeof(sljit_si); + } + } + + 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_si); + } + 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++; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + PTR_FAIL_IF(!inst); + + /* Encoding the byte. */ + INC_SIZE(inst_size); +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + if (flags & EX86_PREF_F2) + *inst++ = 0xf2; + if (flags & EX86_PREF_F3) + *inst++ = 0xf3; +#endif + if (flags & EX86_PREF_66) + *inst++ = 0x66; + if (rex) + *inst++ = rex; + buf_ptr = inst + size; + + /* Encode mod/rm byte. */ + if (!(flags & EX86_SHIFT_INS)) { + if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) + *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; + + 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) + *inst = GROUP_SHIFT_1; + else + *inst = GROUP_SHIFT_N; + } else + *inst = GROUP_SHIFT_CL; + *buf_ptr = 0; + } + + if (!(b & SLJIT_MEM)) +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b); +#else + *buf_ptr++ |= MOD_REG + 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_si*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_si); + } + } + } + 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_si*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_si); + } + + 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_si*)buf_ptr = imma; + } + + return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); +} + +/* --------------------------------------------------------------------- */ +/* Call / return instructions */ +/* --------------------------------------------------------------------- */ + +static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) +{ + sljit_ub *inst; + +#ifndef _WIN64 + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 6 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + FAIL_IF(!inst); + INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); + if (type >= SLJIT_CALL3) { + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3]; + } + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1]; +#else + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 2 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + FAIL_IF(!inst); + INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); + if (type >= SLJIT_CALL3) { + *inst++ = REX_W | REX_R; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3]; + } + *inst++ = REX_W; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1]; +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + sljit_ub *inst; + + 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 <= TMP_REGISTER) { + if (reg_map[dst] < 8) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + POP_REG(reg_lmap[dst]); + return SLJIT_SUCCESS; + } + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + *inst++ = REX_B; + POP_REG(reg_lmap[dst]); + return SLJIT_SUCCESS; + } + + /* REX_W is not necessary (src is not immediate). */ + compiler->mode32 = 1; + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = POP_rm; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + sljit_ub *inst; + + 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 <= TMP_REGISTER) { + if (reg_map[src] < 8) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + FAIL_IF(!inst); + + INC_SIZE(1 + 1); + PUSH_REG(reg_lmap[src]); + } + else { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1); + FAIL_IF(!inst); + + INC_SIZE(2 + 1); + *inst++ = REX_B; + PUSH_REG(reg_lmap[src]); + } + } + else if (src & SLJIT_MEM) { + /* REX_W is not necessary (src is not immediate). */ + compiler->mode32 = 1; + inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_FF; + *inst |= PUSH_rm; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + } + else { + SLJIT_ASSERT(IS_HALFWORD(srcw)); + /* SLJIT_IMM. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + FAIL_IF(!inst); + + INC_SIZE(5 + 1); + *inst++ = PUSH_i32; + *(sljit_si*)inst = srcw; + inst += sizeof(sljit_si); + } + + RET(); + return SLJIT_SUCCESS; +} + + +/* --------------------------------------------------------------------- */ +/* Extend input */ +/* --------------------------------------------------------------------- */ + +static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + sljit_si dst_r; + + compiler->mode32 = 0; + + if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) + return SLJIT_SUCCESS; /* Empty instruction. */ + + if (src & SLJIT_IMM) { + if (dst <= TMP_REGISTER) { + if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; + } + return emit_load_imm64(compiler, dst, srcw); + } + compiler->mode32 = 1; + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + compiler->mode32 = 0; + return SLJIT_SUCCESS; + } + + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + + if ((dst & SLJIT_MEM) && (src <= TMP_REGISTER)) + dst_r = src; + else { + if (sign) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = MOVSXD_r_rm; + } else { + compiler->mode32 = 1; + FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw)); + compiler->mode32 = 0; + } + } + + if (dst & SLJIT_MEM) { + compiler->mode32 = 1; + inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_r; + compiler->mode32 = 0; + } + + return SLJIT_SUCCESS; +} diff --git a/tools/pcre/sljit/sljitNativeX86_common.c b/tools/pcre/sljit/sljitNativeX86_common.c new file mode 100644 index 00000000..ab98a03d --- /dev/null +++ b/tools/pcre/sljit/sljitNativeX86_common.c @@ -0,0 +1,2836 @@ +/* + * 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(void) +{ + 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->scratches_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_sw); \ + 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_sw); \ + 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 + +#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 (0) +#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_SSE2 0x0800 +#define EX86_PREF_F2 0x1000 +#define EX86_PREF_F3 0x2000 +#endif + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +#define ADD (/* BINARY */ 0 << 3) +#define ADD_EAX_i32 0x05 +#define ADD_r_rm 0x03 +#define ADD_rm_r 0x01 +#define ADDSD_x_xm 0x58 +#define ADC (/* BINARY */ 2 << 3) +#define ADC_EAX_i32 0x15 +#define ADC_r_rm 0x13 +#define ADC_rm_r 0x11 +#define AND (/* BINARY */ 4 << 3) +#define AND_EAX_i32 0x25 +#define AND_r_rm 0x23 +#define AND_rm_r 0x21 +#define ANDPD_x_xm 0x54 +#define BSR_r_rm (/* GROUP_0F */ 0xbd) +#define CALL_i32 0xe8 +#define CALL_rm (/* GROUP_FF */ 2 << 3) +#define CDQ 0x99 +#define CMOVNE_r_rm (/* GROUP_0F */ 0x45) +#define CMP (/* BINARY */ 7 << 3) +#define CMP_EAX_i32 0x3d +#define CMP_r_rm 0x3b +#define CMP_rm_r 0x39 +#define DIV (/* GROUP_F7 */ 6 << 3) +#define DIVSD_x_xm 0x5e +#define INT3 0xcc +#define IDIV (/* GROUP_F7 */ 7 << 3) +#define IMUL (/* GROUP_F7 */ 5 << 3) +#define IMUL_r_rm (/* GROUP_0F */ 0xaf) +#define IMUL_r_rm_i8 0x6b +#define IMUL_r_rm_i32 0x69 +#define JE_i8 0x74 +#define JMP_i8 0xeb +#define JMP_i32 0xe9 +#define JMP_rm (/* GROUP_FF */ 4 << 3) +#define LEA_r_m 0x8d +#define MOV_r_rm 0x8b +#define MOV_r_i32 0xb8 +#define MOV_rm_r 0x89 +#define MOV_rm_i32 0xc7 +#define MOV_rm8_i8 0xc6 +#define MOV_rm8_r8 0x88 +#define MOVSD_x_xm 0x10 +#define MOVSD_xm_x 0x11 +#define MOVSXD_r_rm 0x63 +#define MOVSX_r_rm8 (/* GROUP_0F */ 0xbe) +#define MOVSX_r_rm16 (/* GROUP_0F */ 0xbf) +#define MOVZX_r_rm8 (/* GROUP_0F */ 0xb6) +#define MOVZX_r_rm16 (/* GROUP_0F */ 0xb7) +#define MUL (/* GROUP_F7 */ 4 << 3) +#define MULSD_x_xm 0x59 +#define NEG_rm (/* GROUP_F7 */ 3 << 3) +#define NOP 0x90 +#define NOT_rm (/* GROUP_F7 */ 2 << 3) +#define OR (/* BINARY */ 1 << 3) +#define OR_r_rm 0x0b +#define OR_EAX_i32 0x0d +#define OR_rm_r 0x09 +#define POP_r 0x58 +#define POP_rm 0x8f +#define POPF 0x9d +#define PUSH_i32 0x68 +#define PUSH_r 0x50 +#define PUSH_rm (/* GROUP_FF */ 6 << 3) +#define PUSHF 0x9c +#define RET_near 0xc3 +#define RET_i16 0xc2 +#define SBB (/* BINARY */ 3 << 3) +#define SBB_EAX_i32 0x1d +#define SBB_r_rm 0x1b +#define SBB_rm_r 0x19 +#define SAR (/* SHIFT */ 7 << 3) +#define SHL (/* SHIFT */ 4 << 3) +#define SHR (/* SHIFT */ 5 << 3) +#define SUB (/* BINARY */ 5 << 3) +#define SUB_EAX_i32 0x2d +#define SUB_r_rm 0x2b +#define SUB_rm_r 0x29 +#define SUBSD_x_xm 0x5c +#define TEST_EAX_i32 0xa9 +#define TEST_rm_r 0x85 +#define UCOMISD_x_xm 0x2e +#define XCHG_EAX_r 0x90 +#define XCHG_r_rm 0x87 +#define XOR (/* BINARY */ 6 << 3) +#define XOR_EAX_i32 0x35 +#define XOR_r_rm 0x33 +#define XOR_rm_r 0x31 +#define XORPD_x_xm 0x57 + +#define GROUP_0F 0x0f +#define GROUP_F7 0xf7 +#define GROUP_FF 0xff +#define GROUP_BINARY_81 0x81 +#define GROUP_BINARY_83 0x83 +#define GROUP_SHIFT_1 0xd1 +#define GROUP_SHIFT_N 0xc1 +#define GROUP_SHIFT_CL 0xd3 + +#define MOD_REG 0xc0 +#define MOD_DISP8 0x40 + +#define INC_SIZE(s) (*inst++ = (s), compiler->size += (s)) + +#define PUSH_REG(r) (*inst++ = (PUSH_r + (r))) +#define POP_REG(r) (*inst++ = (POP_r + (r))) +#define RET() (*inst++ = (RET_near)) +#define RET_I16(n) (*inst++ = (RET_i16), *inst++ = n, *inst++ = 0) +/* r32, r/m32 */ +#define MOV_RM(mod, reg, rm) (*inst++ = (MOV_r_rm), *inst++ = (mod) << 6 | (reg) << 3 | (rm)) + +/* Multithreading does not affect these static variables, since they store + built-in CPU features. Therefore they can be overwritten by different threads + if they detect the CPU features in the same time. */ +#if (defined SLJIT_SSE2 && SLJIT_SSE2) && (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) +static sljit_si cpu_has_sse2 = -1; +#endif +static sljit_si cpu_has_cmov = -1; + +#if defined(_MSC_VER) && (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +#if _MSC_VER >= 1400 +#include +#else +#error "MSVC does not support inline assembly in 64 bit mode" +#endif +#endif /* _MSC_VER && SLJIT_CONFIG_X86_64 */ + +static void get_cpu_features(void) +{ + sljit_ui features; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) + /* 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 + +#else /* SLJIT_CONFIG_X86_32 */ + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) + /* AT&T syntax. */ + __asm__ ( + "pushq %%rbx\n" + "movl $0x1, %%eax\n" + "cpuid\n" + "popq %%rbx\n" + "movl %%edx, %0\n" + : "=g" (features) + : + : "%rax", "%rcx", "%rdx" + ); +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + int CPUInfo[4]; + + __cpuid(CPUInfo, 1); + features = (sljit_ui)CPUInfo[3]; +#else + __asm { + mov eax, 1 + push rbx + cpuid + pop rbx + mov features, edx + } +#endif + +#endif /* SLJIT_CONFIG_X86_32 */ + +#if (defined SLJIT_SSE2 && SLJIT_SSE2) && (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) + cpu_has_sse2 = (features >> 26) & 0x1; +#endif + cpu_has_cmov = (features >> 15) & 0x1; +} + +static sljit_ub get_jump_code(sljit_si type) +{ + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_FLOAT_EQUAL: + return 0x84 /* je */; + + case SLJIT_C_NOT_EQUAL: + case SLJIT_C_FLOAT_NOT_EQUAL: + return 0x85 /* jne */; + + case SLJIT_C_LESS: + case SLJIT_C_FLOAT_LESS: + return 0x82 /* jc */; + + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_GREATER_EQUAL: + return 0x83 /* jae */; + + case SLJIT_C_GREATER: + case SLJIT_C_FLOAT_GREATER: + return 0x87 /* jnbe */; + + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_LESS_EQUAL: + return 0x86 /* jbe */; + + case SLJIT_C_SIG_LESS: + return 0x8c /* jl */; + + case SLJIT_C_SIG_GREATER_EQUAL: + return 0x8d /* jnl */; + + case SLJIT_C_SIG_GREATER: + return 0x8f /* jnle */; + + case SLJIT_C_SIG_LESS_EQUAL: + return 0x8e /* jle */; + + case SLJIT_C_OVERFLOW: + case SLJIT_C_MUL_OVERFLOW: + return 0x80 /* jo */; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_MUL_NOT_OVERFLOW: + return 0x81 /* jno */; + + case SLJIT_C_FLOAT_UNORDERED: + return 0x8a /* jp */; + + case SLJIT_C_FLOAT_ORDERED: + return 0x8b /* jpo */; + } + return 0; +} + +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type); +#endif + +static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, sljit_si type) +{ + sljit_si 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_sw)(label_addr - (jump->addr + 2)) >= -128 && (sljit_sw)(label_addr - (jump->addr + 2)) <= 127; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((sljit_sw)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_sw)(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++ = JMP_i8; + else + *code_ptr++ = JMP_i32; + jump->addr++; + } + else if (type >= SLJIT_FAST_CALL) { + short_jump = 0; + *code_ptr++ = CALL_i32; + jump->addr++; + } + else if (short_jump) { + *code_ptr++ = get_jump_code(type) - 0x10; + jump->addr++; + } + else { + *code_ptr++ = GROUP_0F; + *code_ptr++ = get_jump_code(type); + jump->addr += 2; + } + + if (short_jump) { + jump->flags |= PATCH_MB; + code_ptr += sizeof(sljit_sb); + } else { + jump->flags |= PATCH_MW; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + code_ptr += sizeof(sljit_sw); +#else + code_ptr += sizeof(sljit_si); +#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_sw); + const_ = const_->next; + } + else { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *code_ptr++ = (*buf_ptr == 2) ? CALL_i32 : JMP_i32; + buf_ptr++; + *(sljit_sw*)code_ptr = *(sljit_sw*)buf_ptr - ((sljit_sw)code_ptr + sizeof(sljit_sw)); + code_ptr += sizeof(sljit_sw); + buf_ptr += sizeof(sljit_sw) - 1; +#else + code_ptr = generate_fixed_jump(code_ptr, *(sljit_sw*)(buf_ptr + 1), *buf_ptr); + buf_ptr += sizeof(sljit_sw); +#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_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) <= 127); + *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))); + } else if (jump->flags & PATCH_MW) { + if (jump->flags & JUMP_LABEL) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sw))); +#else + SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) >= -0x80000000ll && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) <= 0x7fffffffll); + *(sljit_si*)jump->addr = (sljit_si)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))); +#endif + } + else { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_sw))); +#else + SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) >= -0x80000000ll && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) <= 0x7fffffffll); + *(sljit_si*)jump->addr = (sljit_si)(jump->u.target - (jump->addr + sizeof(sljit_si))); +#endif + } + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + else if (jump->flags & PATCH_MD) + *(sljit_sw*)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 sljit_si emit_cum_binary(struct sljit_compiler *compiler, + sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w); + +static sljit_si 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, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w); + +static sljit_si emit_mov(struct sljit_compiler *compiler, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw); + +static SLJIT_INLINE sljit_si emit_save_flags(struct sljit_compiler *compiler) +{ + sljit_ub *inst; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); +#else + inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); + FAIL_IF(!inst); + INC_SIZE(6); + *inst++ = REX_W; +#endif + *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp + sizeof(sljit_sw)] */ + *inst++ = 0x64; + *inst++ = 0x24; + *inst++ = (sljit_ub)sizeof(sljit_sw); + *inst++ = PUSHF; + compiler->flags_saved = 1; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_restore_flags(struct sljit_compiler *compiler, sljit_si keep_flags) +{ + sljit_ub *inst; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); + *inst++ = POPF; +#else + inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); + FAIL_IF(!inst); + INC_SIZE(6); + *inst++ = POPF; + *inst++ = REX_W; +#endif + *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp - sizeof(sljit_sw)] */ + *inst++ = 0x64; + *inst++ = 0x24; + *inst++ = (sljit_ub)-(sljit_sb)sizeof(sljit_sw); + compiler->flags_saved = keep_flags; + return SLJIT_SUCCESS; +} + +#ifdef _WIN32 +#include + +static void SLJIT_CALL sljit_grow_stack(sljit_sw 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 sljit_si emit_mov(struct sljit_compiler *compiler, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + + if (dst == SLJIT_UNUSED) { + /* No destination, doesn't need to setup flags. */ + if (src & SLJIT_MEM) { + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); + FAIL_IF(!inst); + *inst = MOV_r_rm; + } + return SLJIT_SUCCESS; + } + if (src <= TMP_REGISTER) { + inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_r; + return SLJIT_SUCCESS; + } + if (src & SLJIT_IMM) { + if (dst <= TMP_REGISTER) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + return emit_do_imm(compiler, MOV_r_i32 + 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, MOV_r_i32 + 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)); + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_r; + return SLJIT_SUCCESS; + } +#endif + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; + } + if (dst <= TMP_REGISTER) { + inst = emit_x86_instruction(compiler, 1, dst, 0, src, srcw); + FAIL_IF(!inst); + *inst = MOV_r_rm; + return SLJIT_SUCCESS; + } + + /* Memory to memory move. Requires two instruction. */ + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); + FAIL_IF(!inst); + *inst = MOV_r_rm; + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_r; + return SLJIT_SUCCESS; +} + +#define EMIT_MOV(compiler, dst, dstw, src, srcw) \ + FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + sljit_ub *inst; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_si size; +#endif + + CHECK_ERROR(); + check_sljit_emit_op0(compiler, op); + + switch (GET_OPCODE(op)) { + case SLJIT_BREAKPOINT: + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = INT3; + break; + case SLJIT_NOP: + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = NOP; + 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_SCRATCH_REG1] == 0 + && reg_map[SLJIT_SCRATCH_REG2] == 2 + && reg_map[TMP_REGISTER] > 7, + invalid_register_assignment_for_div_mul); +#else + SLJIT_COMPILE_ASSERT( + reg_map[SLJIT_SCRATCH_REG1] == 0 + && reg_map[SLJIT_SCRATCH_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_SCRATCH_REG2, 0); + inst = emit_x86_instruction(compiler, 1, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0); +#else + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); +#endif + FAIL_IF(!inst); + *inst = XOR_r_rm; + } + + if (op == SLJIT_SDIV) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_SCRATCH_REG2, 0); +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = CDQ; +#else + if (compiler->mode32) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = CDQ; + } else { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + *inst++ = REX_W; + *inst = CDQ; + } +#endif + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + *inst++ = GROUP_F7; + *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_SCRATCH_REG2]); +#else +#ifdef _WIN64 + size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2; +#else + size = (!compiler->mode32) ? 3 : 2; +#endif + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); +#ifdef _WIN64 + if (!compiler->mode32) + *inst++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0); + else if (op >= SLJIT_UDIV) + *inst++ = REX_B; + *inst++ = GROUP_F7; + *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_SCRATCH_REG2]); +#else + if (!compiler->mode32) + *inst++ = REX_W; + *inst++ = GROUP_F7; + *inst = MOD_REG | reg_map[SLJIT_SCRATCH_REG2]; +#endif +#endif + switch (op) { + case SLJIT_UMUL: + *inst |= MUL; + break; + case SLJIT_SMUL: + *inst |= IMUL; + break; + case SLJIT_UDIV: + *inst |= DIV; + break; + case SLJIT_SDIV: + *inst |= IDIV; + break; + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) + EMIT_MOV(compiler, SLJIT_SCRATCH_REG2, 0, TMP_REGISTER, 0); +#endif + break; + } + + return SLJIT_SUCCESS; +} + +#define ENCODE_PREFIX(prefix) \ + do { \ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); \ + FAIL_IF(!inst); \ + INC_SIZE(1); \ + *inst = (prefix); \ + } while (0) + +static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + sljit_si dst_r; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_si 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 <= TMP_REGISTER) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); +#else + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; +#endif + } + inst = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm8_i8; + return SLJIT_SUCCESS; + } + + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + + if ((dst & SLJIT_MEM) && src <= TMP_REGISTER) { +#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 <= TMP_REGISTER && reg_map[src] >= 4) { + /* src, dst are registers. */ + SLJIT_ASSERT(dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REGISTER); + if (reg_map[dst] < 4) { + if (dst != src) + EMIT_MOV(compiler, dst, 0, src, 0); + inst = emit_x86_instruction(compiler, 2, dst, 0, dst, 0); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; + } + else { + if (dst != src) + EMIT_MOV(compiler, dst, 0, src, 0); + if (sign) { + /* shl reg, 24 */ + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); + FAIL_IF(!inst); + *inst |= SHL; + /* sar reg, 24 */ + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); + FAIL_IF(!inst); + *inst |= SAR; + } + else { + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0xff, dst, 0); + FAIL_IF(!inst); + *(inst + 1) |= AND; + } + } + return SLJIT_SUCCESS; + } +#endif + else { + /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */ + inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; + } + + 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_SCRATCH_REG1) { + if ((dst & 0xf0) == (SLJIT_SCRATCH_REG2 << 4)) + work_r = SLJIT_SCRATCH_REG3; + else + work_r = SLJIT_SCRATCH_REG2; + } + else { + if ((dst & 0xf0) != (SLJIT_SCRATCH_REG1 << 4)) + work_r = SLJIT_SCRATCH_REG1; + else if ((dst & 0xf) == SLJIT_SCRATCH_REG2) + work_r = SLJIT_SCRATCH_REG3; + else + work_r = SLJIT_SCRATCH_REG2; + } + + if (work_r == SLJIT_SCRATCH_REG1) { + ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REGISTER]); + } + else { + inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); + FAIL_IF(!inst); + *inst = XCHG_r_rm; + } + + inst = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm8_r8; + + if (work_r == SLJIT_SCRATCH_REG1) { + ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REGISTER]); + } + else { + inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); + FAIL_IF(!inst); + *inst = XCHG_r_rm; + } + } + else { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm8_r8; + } +#else + inst = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm8_r8; +#endif + } + + return SLJIT_SUCCESS; +} + +static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + sljit_si 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 <= TMP_REGISTER) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); +#else + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; +#endif + } + inst = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; + } + + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + + if ((dst & SLJIT_MEM) && src <= TMP_REGISTER) + dst_r = src; + else { + inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = sign ? MOVSX_r_rm16 : MOVZX_r_rm16; + } + + if (dst & SLJIT_MEM) { + inst = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_r; + } + + return SLJIT_SUCCESS; +} + +static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= opcode; + return SLJIT_SUCCESS; + } + if (dst == src && dstw == srcw) { + /* Same input and output */ + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= opcode; + return SLJIT_SUCCESS; + } + if (dst <= TMP_REGISTER) { + EMIT_MOV(compiler, dst, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= opcode; + return SLJIT_SUCCESS; + } + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= opcode; + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + return SLJIT_SUCCESS; +} + +static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= NOT_rm; + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst = OR_r_rm; + return SLJIT_SUCCESS; + } + if (dst <= TMP_REGISTER) { + EMIT_MOV(compiler, dst, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= NOT_rm; + inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); + FAIL_IF(!inst); + *inst = OR_r_rm; + return SLJIT_SUCCESS; + } + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= NOT_rm; + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst = OR_r_rm; + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + return SLJIT_SUCCESS; +} + +static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + sljit_si dst_r; + + SLJIT_UNUSED_ARG(op_flags); + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + /* Just set the zero flag. */ + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst++ = GROUP_F7; + *inst |= NOT_rm; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0); +#else + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0); +#endif + FAIL_IF(!inst); + *inst |= SHR; + return SLJIT_SUCCESS; + } + + if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_IMM, srcw); + src = TMP_REGISTER; + srcw = 0; + } + + inst = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = BSR_r_rm; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst <= TMP_REGISTER) + dst_r = dst; + else { + /* Find an unused temporary register. */ + if ((dst & 0xf) != SLJIT_SCRATCH_REG1 && (dst & 0xf0) != (SLJIT_SCRATCH_REG1 << 4)) + dst_r = SLJIT_SCRATCH_REG1; + else if ((dst & 0xf) != SLJIT_SCRATCH_REG2 && (dst & 0xf0) != (SLJIT_SCRATCH_REG2 << 4)) + dst_r = SLJIT_SCRATCH_REG2; + else + dst_r = SLJIT_SCRATCH_REG3; + EMIT_MOV(compiler, dst, dstw, dst_r, 0); + } + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31); +#else + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REG2; + compiler->mode32 = 0; + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); + compiler->mode32 = op_flags & SLJIT_INT_OP; +#endif + + if (cpu_has_cmov == -1) + get_cpu_features(); + + if (cpu_has_cmov) { + inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = CMOVNE_r_rm; + } else { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + + *inst++ = JE_i8; + *inst++ = 2; + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_map[dst_r] << 3) | reg_map[TMP_REGISTER]; +#else + inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); + + *inst++ = JE_i8; + *inst++ = 3; + *inst++ = REX_W | (reg_map[dst_r] >= 8 ? REX_R : 0) | (reg_map[TMP_REGISTER] >= 8 ? REX_B : 0); + *inst++ = MOV_r_rm; + *inst++ = MOD_REG | (reg_lmap[dst_r] << 3) | reg_lmap[TMP_REGISTER]; +#endif + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); +#else + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, dst_r, 0); +#endif + FAIL_IF(!inst); + *(inst + 1) |= XOR; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst & SLJIT_MEM) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!inst); + *inst = XCHG_r_rm; + } +#else + if (dst & SLJIT_MEM) + EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0); +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + sljit_si update = 0; + sljit_si op_flags = GET_ALL_FLAGS(op); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_si dst_is_ereg = 0; + sljit_si 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_flags & SLJIT_INT_OP; +#endif + + op = GET_OPCODE(op); + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; +#endif + + if (op_flags & SLJIT_INT_OP) { + if (src <= TMP_REGISTER && src == dst) { + if (!TYPE_CAST_NEEDED(op)) + return SLJIT_SUCCESS; + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) + op = SLJIT_MOV_UI; + if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) + op = SLJIT_MOVU_UI; + if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) + op = SLJIT_MOV_SI; + if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) + op = SLJIT_MOVU_SI; +#endif + } + + SLJIT_COMPILE_ASSERT(SLJIT_MOV + 8 == SLJIT_MOVU, movu_offset); + if (op >= SLJIT_MOVU) { + update = 1; + op -= 8; + } + + if (src & SLJIT_IMM) { + switch (op) { + case SLJIT_MOV_UB: + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOV_SB: + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOV_UH: + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOV_SH: + srcw = (sljit_sh)srcw; + break; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case SLJIT_MOV_UI: + srcw = (sljit_ui)srcw; + break; + case SLJIT_MOV_SI: + srcw = (sljit_si)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)) { + inst = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw); + FAIL_IF(!inst); + *inst = LEA_r_m; + 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 || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) { + SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG)); + dst = TMP_REGISTER; + } +#endif + + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: +#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, srcw)); + break; + case SLJIT_MOV_SB: + FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, srcw)); + break; + case SLJIT_MOV_UH: + FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, srcw)); + break; + case SLJIT_MOV_SH: + FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, 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, srcw)); + break; + case SLJIT_MOV_SI: + FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, 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)) { + inst = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw); + FAIL_IF(!inst); + *inst = LEA_r_m; + } + return SLJIT_SUCCESS; + } + + if (SLJIT_UNLIKELY(GET_FLAGS(op_flags))) + compiler->flags_saved = 0; + + switch (op) { + case SLJIT_NOT: + if (SLJIT_UNLIKELY(op_flags & SLJIT_SET_E)) + return emit_not_with_flags(compiler, dst, dstw, src, srcw); + return emit_unary(compiler, NOT_rm, dst, dstw, src, srcw); + + case SLJIT_NEG: + if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + return emit_unary(compiler, NEG_rm, dst, dstw, src, srcw); + + case SLJIT_CLZ: + if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + return emit_clz(compiler, op_flags, 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) { \ + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ + FAIL_IF(!inst); \ + *(inst + 1) |= (op_imm); \ + } \ + else { \ + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \ + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \ + FAIL_IF(!inst); \ + *inst = (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) \ + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ + FAIL_IF(!inst); \ + *(inst + 1) |= (op_imm); + +#define BINARY_EAX_IMM(op_eax_imm, immw) \ + FAIL_IF(emit_do_imm(compiler, (op_eax_imm), immw)) + +#endif + +static sljit_si emit_cum_binary(struct sljit_compiler *compiler, + sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + + 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 { + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!inst); + *inst = 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_SCRATCH_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if ((dst == SLJIT_SCRATCH_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 <= TMP_REGISTER) { + inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + else if (src2 <= TMP_REGISTER) { + /* Special exception for sljit_emit_op_flags. */ + inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!inst); + *inst = 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_SCRATCH_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { +#else + if ((dst == SLJIT_SCRATCH_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 <= TMP_REGISTER) { + inst = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w); + FAIL_IF(!inst); + *inst = op_rm; + } + else if (src1 <= TMP_REGISTER) { + inst = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + return SLJIT_SUCCESS; + } + + /* General version. */ + if (dst <= TMP_REGISTER) { + EMIT_MOV(compiler, dst, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, dst, 0); + } + else { + inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); + FAIL_IF(!inst); + *inst = 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 { + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + } + + return SLJIT_SUCCESS; +} + +static sljit_si 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, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + + 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 { + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!inst); + *inst = 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_SCRATCH_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if ((dst == SLJIT_SCRATCH_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 <= TMP_REGISTER) { + inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + else if (src2 <= TMP_REGISTER) { + inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!inst); + *inst = op_mr; + } + return SLJIT_SUCCESS; + } + + /* General version. */ + if (dst <= TMP_REGISTER && dst != src2) { + EMIT_MOV(compiler, dst, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, dst, 0); + } + else { + inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); + FAIL_IF(!inst); + *inst = 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 { + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!inst); + *inst = op_rm; + } + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + } + + return SLJIT_SUCCESS; +} + +static sljit_si emit_mul(struct sljit_compiler *compiler, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + sljit_si dst_r; + + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + + /* Register destination. */ + if (dst_r == src1 && !(src2 & SLJIT_IMM)) { + inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = IMUL_r_rm; + } + else if (dst_r == src2 && !(src1 & SLJIT_IMM)) { + inst = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = IMUL_r_rm; + } + 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) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i8; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = (sljit_sb)src1w; + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + else { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i32; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *(sljit_sw*)inst = src1w; + } +#else + else if (IS_HALFWORD(src1w)) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i32; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *(sljit_si*)inst = (sljit_si)src1w; + } + else { + EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); + if (dst_r != src2) + EMIT_MOV(compiler, dst_r, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = IMUL_r_rm; + } +#endif + } + else if (src2 & SLJIT_IMM) { + /* Note: src1 is NOT immediate. */ + + if (src2w <= 127 && src2w >= -128) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i8; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = (sljit_sb)src2w; + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + else { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i32; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *(sljit_sw*)inst = src2w; + } +#else + else if (IS_HALFWORD(src2w)) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!inst); + *inst = IMUL_r_rm_i32; + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + *(sljit_si*)inst = (sljit_si)src2w; + } + else { + EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); + if (dst_r != src1) + EMIT_MOV(compiler, dst_r, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = IMUL_r_rm; + } +#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); + inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = IMUL_r_rm; + } + + if (dst_r == TMP_REGISTER) + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + + return SLJIT_SUCCESS; +} + +static sljit_si emit_lea_binary(struct sljit_compiler *compiler, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + sljit_si 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 <= TMP_REGISTER) ? dst : TMP_REGISTER; + + if (src1 <= TMP_REGISTER) { + if (src2 <= TMP_REGISTER || src2 == TMP_REGISTER) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0); + FAIL_IF(!inst); + *inst = LEA_r_m; + done = 1; + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_si)src2w); +#else + if (src2 & SLJIT_IMM) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); +#endif + FAIL_IF(!inst); + *inst = LEA_r_m; + done = 1; + } + } + else if (src2 <= TMP_REGISTER) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_si)src1w); +#else + if (src1 & SLJIT_IMM) { + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); +#endif + FAIL_IF(!inst); + *inst = LEA_r_m; + 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 sljit_si emit_cmp_binary(struct sljit_compiler *compiler, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { +#endif + BINARY_EAX_IMM(CMP_EAX_i32, src2w); + return SLJIT_SUCCESS; + } + + if (src1 <= TMP_REGISTER) { + if (src2 & SLJIT_IMM) { + BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0); + } + else { + inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); + FAIL_IF(!inst); + *inst = CMP_r_rm; + } + return SLJIT_SUCCESS; + } + + if (src2 <= TMP_REGISTER && !(src1 & SLJIT_IMM)) { + inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); + FAIL_IF(!inst); + *inst = CMP_rm_r; + 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(CMP, CMP_rm_r, src2w, src1, src1w); + } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!inst); + *inst = CMP_r_rm; + } + return SLJIT_SUCCESS; +} + +static sljit_si emit_test_binary(struct sljit_compiler *compiler, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { +#endif + BINARY_EAX_IMM(TEST_EAX_i32, src2w); + return SLJIT_SUCCESS; + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (src2 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { +#else + if (src2 == SLJIT_SCRATCH_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { +#endif + BINARY_EAX_IMM(TEST_EAX_i32, src1w); + return SLJIT_SUCCESS; + } + + if (src1 <= TMP_REGISTER) { + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (IS_HALFWORD(src2w) || compiler->mode32) { + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); + FAIL_IF(!inst); + *inst = GROUP_F7; + } + else { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0); + FAIL_IF(!inst); + *inst = TEST_rm_r; + } +#else + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); + FAIL_IF(!inst); + *inst = GROUP_F7; +#endif + } + else { + inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); + FAIL_IF(!inst); + *inst = TEST_rm_r; + } + return SLJIT_SUCCESS; + } + + if (src2 <= TMP_REGISTER) { + if (src1 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (IS_HALFWORD(src1w) || compiler->mode32) { + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0); + FAIL_IF(!inst); + *inst = GROUP_F7; + } + else { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w)); + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0); + FAIL_IF(!inst); + *inst = TEST_rm_r; + } +#else + inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0); + FAIL_IF(!inst); + *inst = GROUP_F7; +#endif + } + else { + inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); + FAIL_IF(!inst); + *inst = TEST_rm_r; + } + 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) { + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst = GROUP_F7; + } + else { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst = TEST_rm_r; + } +#else + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst = GROUP_F7; +#endif + } + else { + inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!inst); + *inst = TEST_rm_r; + } + return SLJIT_SUCCESS; +} + +static sljit_si emit_shift(struct sljit_compiler *compiler, + sljit_ub mode, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_ub* inst; + + if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) { + if (dst == src1 && dstw == src1w) { + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw); + FAIL_IF(!inst); + *inst |= mode; + return SLJIT_SUCCESS; + } + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst |= mode; + return SLJIT_SUCCESS; + } + if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst |= mode; + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + return SLJIT_SUCCESS; + } + if (dst <= TMP_REGISTER) { + EMIT_MOV(compiler, dst, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); + FAIL_IF(!inst); + *inst |= mode; + return SLJIT_SUCCESS; + } + + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst |= 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); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst |= mode; + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + } + else if (dst <= TMP_REGISTER && 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); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0); + FAIL_IF(!inst); + *inst |= 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_sw), SLJIT_PREF_SHIFT_REG, 0); +#endif + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + FAIL_IF(!inst); + *inst |= 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_sw)); +#endif + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + } + + return SLJIT_SUCCESS; +} + +static sljit_si emit_shift_with_flags(struct sljit_compiler *compiler, + sljit_ub mode, sljit_si set_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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, OR_r_rm, OR_rm_r, OR, OR_EAX_i32, + dst, dstw, src1, src1w, SLJIT_IMM, 0); + } + + if (!set_flags) + return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); + + if (!(dst <= TMP_REGISTER)) + 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 <= TMP_REGISTER) + return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32, + 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, ADC_r_rm, ADC_rm_r, ADC, ADC_EAX_i32, + 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, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, + 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, SBB_r_rm, SBB_rm_r, SBB, SBB_EAX_i32, + 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, AND_r_rm, AND_rm_r, AND, AND_EAX_i32, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_OR: + return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_XOR: + return emit_cum_binary(compiler, XOR_r_rm, XOR_rm_r, XOR, XOR_EAX_i32, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_SHL: + return emit_shift_with_flags(compiler, SHL, GET_FLAGS(op), + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_LSHR: + return emit_shift_with_flags(compiler, SHR, GET_FLAGS(op), + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_ASHR: + return emit_shift_with_flags(compiler, SAR, GET_FLAGS(op), + dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si 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 sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size) +{ + sljit_ub *inst; + + CHECK_ERROR(); + check_sljit_emit_op_custom(compiler, instruction, size); + SLJIT_ASSERT(size > 0 && size < 16); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + SLJIT_MEMMOVE(inst, instruction, size); + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + +/* Alignment + 2 * 16 bytes. */ +static sljit_si sse2_data[3 + (4 + 4) * 2]; +static sljit_si *sse2_buffer; + +static void init_compiler(void) +{ + sse2_buffer = (sljit_si*)(((sljit_uw)sse2_data + 15) & ~0xf); + /* Single precision constants. */ + sse2_buffer[0] = 0x80000000; + sse2_buffer[4] = 0x7fffffff; + /* Double precision constants. */ + sse2_buffer[8] = 0; + sse2_buffer[9] = 0x80000000; + sse2_buffer[12] = 0xffffffff; + sse2_buffer[13] = 0x7fffffff; +} + +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ +#if (defined SLJIT_SSE2 && SLJIT_SSE2) +#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) + if (cpu_has_sse2 == -1) + get_cpu_features(); + return cpu_has_sse2; +#else /* SLJIT_DETECT_SSE2 */ + return 1; +#endif /* SLJIT_DETECT_SSE2 */ +#else /* SLJIT_SSE2 */ + return 0; +#endif +} + +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + +static sljit_si emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, + sljit_si single, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) +{ + sljit_ub *inst; + + inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = opcode; + return SLJIT_SUCCESS; +} + +static sljit_si emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode, + sljit_si pref66, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) +{ + sljit_ub *inst; + + inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = opcode; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_sse2_load(struct sljit_compiler *compiler, + sljit_si single, sljit_si dst, sljit_si src, sljit_sw srcw) +{ + return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw); +} + +static SLJIT_INLINE sljit_si emit_sse2_store(struct sljit_compiler *compiler, + sljit_si single, sljit_si dst, sljit_sw dstw, sljit_si src) +{ + return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si 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_CMPD) { + compiler->flags_saved = 0; + if (dst <= SLJIT_FLOAT_REG6) + dst_r = dst; + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, dst, dstw)); + } + return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_SINGLE_OP), dst_r, src, srcw); + } + + if (op == SLJIT_MOVD) { + if (dst <= SLJIT_FLOAT_REG6) + return emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst, src, srcw); + if (src <= SLJIT_FLOAT_REG6) + return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, src); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src, srcw)); + return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + } + + if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG6) { + dst_r = dst; + if (dst != src) + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); + } + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); + } + + switch (GET_OPCODE(op)) { + case SLJIT_NEGD: + FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer : sse2_buffer + 8))); + break; + + case SLJIT_ABSD: + FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer + 4 : sse2_buffer + 12))); + break; + } + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si 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_REG6) { + dst_r = dst; + if (dst == src1) + ; /* Do nothing here. */ + else if (dst == src2 && (op == SLJIT_ADDD || op == SLJIT_MULD)) { + /* Swap arguments. */ + src2 = src1; + src2w = src1w; + } + else if (dst != src2) + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src1, src1w)); + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + } + } + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + } + + switch (GET_OPCODE(op)) { + case SLJIT_ADDD: + FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + break; + + case SLJIT_SUBD: + FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + break; + + case SLJIT_MULD: + FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + break; + + case SLJIT_DIVD: + FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + break; + } + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +#else + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw 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 sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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 *inst; + 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); + + inst = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF(!inst); + + *inst++ = 0; + *inst++ = 0; + + return label; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + sljit_ub *inst; + 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 + + inst = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF_NULL(inst); + + *inst++ = 0; + *inst++ = type + 4; + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + sljit_ub *inst; + 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_SCRATCH_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_sw); +#endif +#endif +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64) + if (src == SLJIT_SCRATCH_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 + + inst = (sljit_ub*)ensure_buf(compiler, 2); + FAIL_IF_NULL(inst); + + *inst++ = 0; + *inst++ = 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 + inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_FF; + *inst |= (type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm; + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_ub *inst; + sljit_ub cond_set = 0; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_si reg; +#else + /* CHECK_EXTRA_REGS migh overwrite these values. */ + sljit_si dst_save = dst; + sljit_sw dstw_save = dstw; +#endif + + CHECK_ERROR(); + check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, 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)); + + /* setcc = jcc + 0x10. */ + cond_set = get_jump_code(type) + 0x10; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + reg = (op == SLJIT_MOV && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); + FAIL_IF(!inst); + INC_SIZE(4 + 4); + /* Set low register to conditional flag. */ + *inst++ = (reg_map[reg] <= 7) ? REX : REX_B; + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | reg_lmap[reg]; + *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); + *inst++ = GROUP_0F; + *inst++ = MOVZX_r_rm8; + *inst = MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]; + + if (reg != TMP_REGISTER) + return SLJIT_SUCCESS; + + if (GET_OPCODE(op) < SLJIT_ADD) { + compiler->mode32 = GET_OPCODE(op) != SLJIT_MOV; + return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0); + } +#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_REGISTER, 0); +#else /* SLJIT_CONFIG_X86_64 */ + if (GET_OPCODE(op) < SLJIT_ADD && dst <= TMP_REGISTER) { + if (reg_map[dst] <= 4) { + /* Low byte is accessible. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); + FAIL_IF(!inst); + INC_SIZE(3 + 3); + /* Set low byte to conditional flag. */ + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | reg_map[dst]; + + *inst++ = GROUP_0F; + *inst++ = MOVZX_r_rm8; + *inst = MOD_REG | (reg_map[dst] << 3) | reg_map[dst]; + return SLJIT_SUCCESS; + } + + /* Low byte is not accessible. */ + if (cpu_has_cmov == -1) + get_cpu_features(); + + if (cpu_has_cmov) { + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_IMM, 1); + /* a xor reg, reg operation would overwrite the flags. */ + EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0); + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!inst); + INC_SIZE(3); + + *inst++ = GROUP_0F; + /* cmovcc = setcc - 0x50. */ + *inst++ = cond_set - 0x50; + *inst++ = MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REGISTER]; + return SLJIT_SUCCESS; + } + + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + FAIL_IF(!inst); + INC_SIZE(1 + 3 + 3 + 1); + *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; + /* Set al to conditional flag. */ + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | 0 /* eax */; + + *inst++ = GROUP_0F; + *inst++ = MOVZX_r_rm8; + *inst++ = MOD_REG | (reg_map[dst] << 3) | 0 /* eax */; + *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; + return SLJIT_SUCCESS; + } + + /* Set TMP_REGISTER to the bit. */ + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + FAIL_IF(!inst); + INC_SIZE(1 + 3 + 3 + 1); + *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; + /* Set al to conditional flag. */ + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | 0 /* eax */; + + *inst++ = GROUP_0F; + *inst++ = MOVZX_r_rm8; + *inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */; + + *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; + + if (GET_OPCODE(op) < SLJIT_ADD) + return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0); + +#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 /* SLJIT_CONFIG_X86_64 */ +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw 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, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + sljit_ub *inst; + struct sljit_const *const_; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_si 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 <= TMP_REGISTER) ? 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 + + inst = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF(!inst); + + *inst++ = 0; + *inst++ = 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_sw*)addr = new_addr - (addr + 4); +#else + *(sljit_uw*)addr = new_addr; +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + *(sljit_sw*)addr = new_constant; +} diff --git a/tools/pcre/sljit/sljitUtils.c b/tools/pcre/sljit/sljitUtils.c new file mode 100644 index 00000000..1f023fa6 --- /dev/null +++ b/tools/pcre/sljit/sljitUtils.c @@ -0,0 +1,332 @@ +/* + * 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 */ + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) + +#include + +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) + +#include + +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) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) + +#ifdef _WIN32 +#include "windows.h" +#else +/* Provides mmap function. */ +#include +/* For detecting the page size. */ +#include + +#ifndef MAP_ANON + +#include + +/* Some old systems does not have MAP_ANON. */ +static sljit_si dev_zero = -1; + +#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) + +static SLJIT_INLINE sljit_si open_dev_zero(void) +{ + dev_zero = open("/dev/zero", O_RDWR); + return dev_zero < 0; +} + +#else /* SLJIT_SINGLE_THREADED */ + +#include + +static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER; + +static SLJIT_INLINE sljit_si open_dev_zero(void) +{ + pthread_mutex_lock(&dev_zero_mutex); + dev_zero = open("/dev/zero", O_RDWR); + pthread_mutex_unlock(&dev_zero_mutex); + return dev_zero < 0; +} + +#endif /* SLJIT_SINGLE_THREADED */ + +#endif + +#endif + +#endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */ + +#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) + +/* Planning to make it even more clever in the future. */ +static sljit_sw 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(NULL, 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 +#ifdef MAP_ANON + base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); +#else + if (dev_zero < 0) { + if (open_dev_zero()) { + SLJIT_FREE(stack); + return NULL; + } + } + base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0); +#endif + 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_sw 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 madvise is available, we release the unnecessary space. */ +#if defined(POSIX_MADV_DONTNEED) + if (aligned_new_limit < aligned_old_limit) + posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED); +#elif defined(MADV_DONTNEED) + if (aligned_new_limit < aligned_old_limit) + madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED); +#endif + stack->limit = new_limit; + return 0; +#endif +} + +#endif /* SLJIT_UTIL_STACK */ + +#endif diff --git a/tools/pcre/testdata/grepbinary b/tools/pcre/testdata/grepbinary new file mode 100644 index 0000000000000000000000000000000000000000..5efa1302049e4541d1acf53b63d6caaf5f9c439c GIT binary patch literal 45 zcmWH^NL45-%}mZ#NGi%N&r?Was8Gl%%`GTa$S+GRQYZmR=Ok8DDx~D6>u~`9Z_*E= literal 0 HcmV?d00001 diff --git a/tools/pcre/testdata/grepfilelist b/tools/pcre/testdata/grepfilelist new file mode 100644 index 00000000..dd73ec7f --- /dev/null +++ b/tools/pcre/testdata/grepfilelist @@ -0,0 +1,3 @@ +testdata/grepinputv + +testdata/grepinputx diff --git a/tools/pcre/testdata/grepinput b/tools/pcre/testdata/grepinput new file mode 100644 index 00000000..0f00edd9 --- /dev/null +++ b/tools/pcre/testdata/grepinput @@ -0,0 +1,611 @@ +This is a file of miscellaneous text that is used as test data for checking +that the pcregrep command is working correctly. The file must be more than 24K +long so that it needs more than a single read() call to process it. New +features should be added at the end, because some of the tests involve the +output of line numbers, and we don't want these to change. + +PATTERN at the start of a line. +In the middle of a line, PATTERN appears. + +This pattern is in lower case. + +Here follows a whole lot of stuff that makes the file over 24K long. + +------------------------------------------------------------------------------- +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. + +The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the +lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox +jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick +brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. +------------------------------------------------------------------------------- + +aaaaa0 +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bbbbbb +cccccccccccccccccccccccccccccccccccccccccc +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +eeeee +aaaaa2 +ffffffffff + +This is a line before the binary zero. +This line contains a binary zero here >< for testing. +This is a line after the binary zero. + +ABOVE the elephant +ABOVE +ABOVE theatre +AB.VE +AB.VE the turtle + +010203040506 + +PUT NEW DATA ABOVE THIS LINE. +============================= + +Check up on PATTERN near the end. +This is the last line of this file. diff --git a/tools/pcre/testdata/grepinput3 b/tools/pcre/testdata/grepinput3 new file mode 100644 index 00000000..7409cfc0 --- /dev/null +++ b/tools/pcre/testdata/grepinput3 @@ -0,0 +1,15 @@ +triple: t1_txt s1_tag s_txt p_tag p_txt o_tag o_txt + +triple: t2_txt s1_tag s_txt p_tag p_txt o_tag +Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + +triple: t3_txt s2_tag s_txt p_tag p_txt o_tag o_txt + +triple: t4_txt s1_tag s_txt p_tag p_txt o_tag o_txt + +triple: t5_txt s1_tag s_txt p_tag p_txt o_tag +o_txt + +triple: t6_txt s2_tag s_txt p_tag p_txt o_tag o_txt + +triple: t7_txt s1_tag s_txt p_tag p_txt o_tag o_txt diff --git a/tools/pcre/testdata/grepinput8 b/tools/pcre/testdata/grepinput8 new file mode 100644 index 00000000..c4b8c440 --- /dev/null +++ b/tools/pcre/testdata/grepinput8 @@ -0,0 +1,11 @@ +X one +X two X three X four X five +X six +X seven…X eight
X nine
X ten + +Before 111 +Before 222
Before 333…Match +After 111 +After 222
After 333 +And so on and so on +And so on and so on diff --git a/tools/pcre/testdata/grepinputv b/tools/pcre/testdata/grepinputv new file mode 100644 index 00000000..d33d326b --- /dev/null +++ b/tools/pcre/testdata/grepinputv @@ -0,0 +1,4 @@ +The quick brown +fox jumps +over the lazy dog. +This time it jumps and jumps and jumps. diff --git a/tools/pcre/testdata/grepinputx b/tools/pcre/testdata/grepinputx new file mode 100644 index 00000000..730cc8a0 --- /dev/null +++ b/tools/pcre/testdata/grepinputx @@ -0,0 +1,43 @@ +This is a second file of input for the pcregrep tests. + +Here is the pattern again. + +Pattern +That time it was on a line by itself. + +To pat or not to pat, that is the question. + +complete pair +of lines + +That was a complete pair +of lines all by themselves. + +complete pair +of lines + +And there they were again, to check line numbers. + +one +two +three +four +five +six +seven +eight +nine +ten +eleven +twelve +thirteen +fourteen +fifteen +sixteen +seventeen +eighteen +nineteen +twenty + +This line contains pattern not on a line by itself. +This is the last line of this file. diff --git a/tools/pcre/testdata/greplist b/tools/pcre/testdata/greplist new file mode 100644 index 00000000..1434ae96 --- /dev/null +++ b/tools/pcre/testdata/greplist @@ -0,0 +1,7 @@ +This is a file of patterns for testing the -f option. Don't include any blank +lines because they will match everything! This is no longer true, so have one. + +pattern +line by itself + +End of the list of patterns. diff --git a/tools/pcre/testdata/grepoutput b/tools/pcre/testdata/grepoutput new file mode 100644 index 00000000..733b9d6a --- /dev/null +++ b/tools/pcre/testdata/grepoutput @@ -0,0 +1,707 @@ +---------------------------- Test 1 ------------------------------ +PATTERN at the start of a line. +In the middle of a line, PATTERN appears. +Check up on PATTERN near the end. +RC=0 +---------------------------- Test 2 ------------------------------ +PATTERN at the start of a line. +RC=0 +---------------------------- Test 3 ------------------------------ +7:PATTERN at the start of a line. +8:In the middle of a line, PATTERN appears. +10:This pattern is in lower case. +610:Check up on PATTERN near the end. +RC=0 +---------------------------- Test 4 ------------------------------ +4 +RC=0 +---------------------------- Test 5 ------------------------------ +./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: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. +RC=0 +---------------------------- Test 6 ------------------------------ +7:PATTERN at the start of a line. +8:In the middle of a line, PATTERN appears. +10:This pattern is in lower case. +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. +RC=0 +---------------------------- Test 7 ------------------------------ +./testdata/grepinput +./testdata/grepinputx +RC=0 +---------------------------- Test 8 ------------------------------ +./testdata/grepinput +RC=0 +---------------------------- Test 9 ------------------------------ +RC=0 +---------------------------- Test 10 ----------------------------- +RC=1 +---------------------------- Test 11 ----------------------------- +1:This is a second file of input for the pcregrep tests. +2: +4: +5:Pattern +6:That time it was on a line by itself. +7: +8:To pat or not to pat, that is the question. +9: +10:complete pair +11:of lines +12: +13:That was a complete pair +14:of lines all by themselves. +15: +16:complete pair +17:of lines +18: +19:And there they were again, to check line numbers. +20: +21:one +22:two +23:three +24:four +25:five +26:six +27:seven +28:eight +29:nine +30:ten +31:eleven +32:twelve +33:thirteen +34:fourteen +35:fifteen +36:sixteen +37:seventeen +38:eighteen +39:nineteen +40:twenty +41: +43:This is the last line of this file. +RC=0 +---------------------------- Test 12 ----------------------------- +Pattern +RC=0 +---------------------------- Test 13 ----------------------------- +Here is the pattern again. +That time it was on a line by itself. +seventeen +This line contains pattern not on a line by itself. +RC=0 +---------------------------- Test 14 ----------------------------- +./testdata/grepinputx:To pat or not to pat, that is the question. +RC=0 +---------------------------- Test 15 ----------------------------- +pcregrep: Error in command-line regex at offset 4: nothing to repeat +RC=2 +---------------------------- Test 16 ----------------------------- +pcregrep: Failed to open ./testdata/nonexistfile: No such file or directory +RC=2 +---------------------------- Test 17 ----------------------------- +features should be added at the end, because some of the tests involve the +output of line numbers, and we don't want these to change. +RC=0 +---------------------------- Test 18 ----------------------------- +4:features should be added at the end, because some of the tests involve the +output of line numbers, and we don't want these to change. +583:brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. +------------------------------------------------------------------------------- +RC=0 +---------------------------- Test 19 ----------------------------- +Pattern +RC=0 +---------------------------- Test 20 ----------------------------- +10:complete pair +of lines +16:complete pair +of lines +RC=0 +---------------------------- Test 21 ----------------------------- +24:four +25-five +26-six +27-seven +-- +34:fourteen +35-fifteen +36-sixteen +37-seventeen +RC=0 +---------------------------- Test 22 ----------------------------- +21-one +22-two +23-three +24:four +-- +31-eleven +32-twelve +33-thirteen +34:fourteen +RC=0 +---------------------------- Test 23 ----------------------------- +one +two +three +four +five +six +seven +-- +eleven +twelve +thirteen +fourteen +fifteen +sixteen +seventeen +RC=0 +---------------------------- Test 24 ----------------------------- +four +five +six +seven +eight +nine +ten +eleven +twelve +thirteen +fourteen +fifteen +sixteen +seventeen +eighteen +nineteen +twenty + +This line contains pattern not on a line by itself. +This is the last line of this file. +RC=0 +---------------------------- Test 25 ----------------------------- +15- +16-complete pair +17-of lines +18- +19-And there they were again, to check line numbers. +20- +21-one +22-two +23-three +24:four +25-five +26-six +27-seven +28-eight +29-nine +30-ten +31-eleven +32-twelve +33-thirteen +34:fourteen +RC=0 +---------------------------- Test 26 ----------------------------- + +complete pair +of lines + +And there they were again, to check line numbers. + +one +two +three +four +five +six +seven +eight +nine +ten +eleven +twelve +thirteen +fourteen +fifteen +sixteen +seventeen +eighteen +nineteen +twenty + +This line contains pattern not on a line by itself. +This is the last line of this file. +RC=0 +---------------------------- Test 27 ----------------------------- +four +five +six +seven +eight +nine +ten +eleven +twelve +thirteen +fourteen +fifteen +sixteen +seventeen +eighteen +nineteen +twenty + +This line contains pattern not on a line by itself. +This is the last line of this file. +RC=0 +---------------------------- Test 28 ----------------------------- +14-of lines all by themselves. +15- +16-complete pair +17-of lines +18- +19-And there they were again, to check line numbers. +20- +21-one +22-two +23-three +24:four +25-five +26-six +27-seven +28-eight +29-nine +30-ten +31-eleven +32-twelve +33-thirteen +34:fourteen +RC=0 +---------------------------- Test 29 ----------------------------- +of lines all by themselves. + +complete pair +of lines + +And there they were again, to check line numbers. + +one +two +three +four +five +six +seven +eight +nine +ten +eleven +twelve +thirteen +fourteen +fifteen +sixteen +seventeen +eighteen +nineteen +twenty + +This line contains pattern not on a line by itself. +This is the last line of this file. +RC=0 +---------------------------- Test 30 ----------------------------- +./testdata/grepinput-4-features should be added at the end, because some of the tests involve the +./testdata/grepinput-5-output of line numbers, and we don't want these to change. +./testdata/grepinput-6- +./testdata/grepinput:7:PATTERN at the start of a line. +./testdata/grepinput:8:In the middle of a line, PATTERN appears. +./testdata/grepinput-9- +./testdata/grepinput:10:This pattern is in lower case. +-- +./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- +./testdata/grepinputx:3:Here is the pattern again. +./testdata/grepinputx-4- +./testdata/grepinputx:5:Pattern +-- +./testdata/grepinputx-39-nineteen +./testdata/grepinputx-40-twenty +./testdata/grepinputx-41- +./testdata/grepinputx:42:This line contains pattern not on a line by itself. +RC=0 +---------------------------- Test 31 ----------------------------- +./testdata/grepinput:7:PATTERN at the start of a line. +./testdata/grepinput:8:In the middle of a line, PATTERN appears. +./testdata/grepinput-9- +./testdata/grepinput:10:This pattern is in lower case. +./testdata/grepinput-11- +./testdata/grepinput-12-Here follows a whole lot of stuff that makes the file over 24K long. +./testdata/grepinput-13- +-- +./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- +./testdata/grepinputx:5:Pattern +./testdata/grepinputx-6-That time it was on a line by itself. +./testdata/grepinputx-7- +./testdata/grepinputx-8-To pat or not to pat, that is the question. +-- +./testdata/grepinputx:42:This line contains pattern not on a line by itself. +./testdata/grepinputx-43-This is the last line of this file. +RC=0 +---------------------------- Test 32 ----------------------------- +./testdata/grepinputx +RC=0 +---------------------------- Test 33 ----------------------------- +pcregrep: Failed to open ./testdata/grepnonexist: No such file or directory +RC=2 +---------------------------- Test 34 ----------------------------- +RC=2 +---------------------------- Test 35 ----------------------------- +./testdata/grepinput8 +./testdata/grepinputx +RC=0 +---------------------------- Test 36 ----------------------------- +./testdata/grepinput3 +./testdata/grepinputx +RC=0 +---------------------------- Test 37 ----------------------------- +aaaaa0 +aaaaa2 +010203040506 +RC=0 +======== STDERR ======== +pcregrep: pcre_exec() gave error -8 while matching this text: + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +pcregrep: pcre_exec() gave error -8 while matching this text: + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +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. +RC=0 +---------------------------- Test 39 ------------------------------ +This is a line before the binary zero. +This line contains a binary zero here >< for testing. +RC=0 +---------------------------- Test 40 ------------------------------ +This line contains a binary zero here >< for testing. +This is a line after the binary zero. +RC=0 +---------------------------- Test 41 ------------------------------ +before the binary zero +after the binary zero +RC=0 +---------------------------- Test 42 ------------------------------ +./testdata/grepinput:595:before the binary zero +./testdata/grepinput:597:after the binary zero +RC=0 +---------------------------- Test 43 ------------------------------ +595:before +595:zero +596:zero +597:after +597:zero +RC=0 +---------------------------- Test 44 ------------------------------ +595:before +595:zero +596:zero +597:zero +RC=0 +---------------------------- Test 45 ------------------------------ +10:pattern +595:binary +596:binary +597:binary +RC=0 +---------------------------- Test 46 ------------------------------ +pcregrep: Error in 2nd command-line regex at offset 9: missing ) +RC=2 +---------------------------- Test 47 ------------------------------ +AB.VE +RC=0 +---------------------------- Test 48 ------------------------------ +ABOVE the elephant +AB.VE +AB.VE the turtle +RC=0 +---------------------------- Test 49 ------------------------------ +ABOVE the elephant +AB.VE +AB.VE the turtle +PUT NEW DATA ABOVE THIS LINE. +RC=0 +---------------------------- Test 50 ------------------------------ +RC=1 +---------------------------- Test 51 ------------------------------ +over the lazy dog. +This time it jumps and jumps and jumps. +RC=0 +---------------------------- Test 52 ------------------------------ +fox jumps +This time it jumps and jumps and jumps. +RC=0 +---------------------------- Test 53 ------------------------------ +36972,6 +36990,4 +37024,4 +37066,5 +37083,4 +RC=0 +---------------------------- Test 54 ------------------------------ +595:15,6 +595:33,4 +596:28,4 +597:15,5 +597:32,4 +RC=0 +---------------------------- Test 55 ----------------------------- +Here is the pattern again. +That time it was on a line by itself. +This line contains pattern not on a line by itself. +RC=0 +---------------------------- Test 56 ----------------------------- +./testdata/grepinput:456 +./testdata/grepinput3:0 +./testdata/grepinput8:0 +./testdata/grepinputv:1 +./testdata/grepinputx:0 +RC=0 +---------------------------- Test 57 ----------------------------- +./testdata/grepinput:456 +./testdata/grepinputv:1 +RC=0 +---------------------------- Test 58 ----------------------------- +PATTERN at the start of a line. +In the middle of a line, PATTERN appears. +Check up on PATTERN near the end. +RC=0 +---------------------------- Test 59 ----------------------------- +PATTERN at the start of a line. +In the middle of a line, PATTERN appears. +Check up on PATTERN near the end. +RC=0 +---------------------------- Test 60 ----------------------------- +PATTERN at the start of a line. +In the middle of a line, PATTERN appears. +Check up on PATTERN near the end. +RC=0 +---------------------------- Test 61 ----------------------------- +PATTERN at the start of a line. +In the middle of a line, PATTERN appears. +Check up on PATTERN near the end. +RC=0 +---------------------------- Test 62 ----------------------------- +pcregrep: pcre_exec() gave error -8 while matching text that starts: + +This is a file of miscellaneous text that is used as test data for checking +that the pcregrep command is working correctly. The file must be more than 24K +long so that it needs more than a single read + +pcregrep: Error -8, -21 or -27 means that a resource limit was exceeded. +pcregrep: Check your regex for nested unlimited loops. +RC=1 +---------------------------- Test 63 ----------------------------- +pcregrep: pcre_exec() gave error -21 while matching text that starts: + +This is a file of miscellaneous text that is used as test data for checking +that the pcregrep command is working correctly. The file must be more than 24K +long so that it needs more than a single read + +pcregrep: Error -8, -21 or -27 means that a resource limit was exceeded. +pcregrep: Check your regex for nested unlimited loops. +RC=1 +---------------------------- Test 64 ------------------------------ +appears +RC=0 +---------------------------- Test 65 ------------------------------ +pear +RC=0 +---------------------------- Test 66 ------------------------------ +RC=0 +---------------------------- Test 67 ------------------------------ +RC=0 +---------------------------- Test 68 ------------------------------ +pear +RC=0 +---------------------------- Test 69 ----------------------------- +1:This is a second file of input for the pcregrep tests. +2: +4: +5:Pattern +6:That time it was on a line by itself. +7: +8:To pat or not to pat, that is the question. +9: +10:complete pair +11:of lines +12: +13:That was a complete pair +14:of lines all by themselves. +15: +16:complete pair +17:of lines +18: +19:And there they were again, to check line numbers. +20: +21:one +22:two +23:three +24:four +25:five +26:six +27:seven +28:eight +29:nine +30:ten +31:eleven +32:twelve +33:thirteen +34:fourteen +35:fifteen +36:sixteen +37:seventeen +38:eighteen +39:nineteen +40:twenty +41: +43:This is the last line of this file. +RC=0 +---------------------------- Test 70 ----------------------------- +triple: t1_txt s1_tag s_txt p_tag p_txt o_tag o_txt + +triple: t3_txt s2_tag s_txt p_tag p_txt o_tag o_txt + +triple: t4_txt s1_tag s_txt p_tag p_txt o_tag o_txt + +triple: 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 +testdata/grepinput3:triple: t7_txt s1_tag s_txt p_tag p_txt o_tag o_txt +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 +---------------------------- Test 94 ----------------------------- +./testdata/grepinput8 +./testdata/grepinputx +RC=0 +---------------------------- Test 95 ----------------------------- +testdata/grepinputx:complete pair +testdata/grepinputx:That was a complete pair +testdata/grepinputx:complete pair +RC=0 +---------------------------- Test 96 ----------------------------- +./testdata/grepinput3 +./testdata/grepinput8 +./testdata/grepinputx +RC=0 +---------------------------- Test 97 ----------------------------- +./testdata/grepinput3 +./testdata/grepinputx +RC=0 +---------------------------- Test 98 ----------------------------- +./testdata/grepinputx +RC=0 +---------------------------- Test 99 ----------------------------- +./testdata/grepinput3 +./testdata/grepinputx +RC=0 +---------------------------- Test 100 ------------------------------ +./testdata/grepinput:zerothe. +./testdata/grepinput:zeroa +./testdata/grepinput:zerothe. +RC=0 +---------------------------- Test 101 ------------------------------ +./testdata/grepinput:.|zero|the|. +./testdata/grepinput:zero|a +./testdata/grepinput:.|zero|the|. +RC=0 diff --git a/tools/pcre/testdata/grepoutput8 b/tools/pcre/testdata/grepoutput8 new file mode 100644 index 00000000..91493bdc --- /dev/null +++ b/tools/pcre/testdata/grepoutput8 @@ -0,0 +1,12 @@ +---------------------------- Test U1 ------------------------------ +1:X one +2:X two 3:X three 4:X four 5:X five +6:X six +7:X sevenÂ…8:X eight
9:X nine
10:X ten +RC=0 +---------------------------- Test U2 ------------------------------ +12-Before 111 +13-Before 222
14-Before 333Â…15:Match +16-After 111 +17-After 222
18-After 333 +RC=0 diff --git a/tools/pcre/testdata/grepoutputN b/tools/pcre/testdata/grepoutputN new file mode 100644 index 00000000..1f9f8801 --- /dev/null +++ b/tools/pcre/testdata/grepoutputN @@ -0,0 +1,16 @@ +---------------------------- Test N1 ------------------------------ +1:abc 2:def ---------------------------- Test N2 ------------------------------ +1:abc def +2:ghi +jkl---------------------------- Test N3 ------------------------------ +2:def 3: +ghi +jkl---------------------------- Test N4 ------------------------------ +2:ghi +jkl---------------------------- Test N5 ------------------------------ +1:abc 2:def +3:ghi +4:jkl---------------------------- Test N6 ------------------------------ +1:abc 2:def +3:ghi +4:jkl \ No newline at end of file diff --git a/tools/pcre/testdata/greppatN4 b/tools/pcre/testdata/greppatN4 new file mode 100644 index 00000000..7112d84f --- /dev/null +++ b/tools/pcre/testdata/greppatN4 @@ -0,0 +1,2 @@ +xxx +jkl \ No newline at end of file diff --git a/tools/pcre/testdata/saved16 b/tools/pcre/testdata/saved16 new file mode 100644 index 0000000000000000000000000000000000000000..ff5b11dff9bed96ba61ff959d8d45c2b57e9662f GIT binary patch literal 70 zcmZQzV6bBV0@ont05Ai{4gv`PK_Wvkg9wBPCu3p5JcaM_yYrj4HOSxuzLV=F<(4@AS#GoTr?DoJfoR6QLAThWf2Ri>8`2n zX&T%FNYdeWM4q?tQjCTU^&-!eJUVtv*|G?wXU~zPs!a8n8(mg~z5N|mXqH@vadJmr zuQ#vwgSjS0tY3ylh)+dh3C!e+xzf_s8=9KqUFuU@#YP_JN$nB}6Fh@J%S&(#J>Ge| kq@L)jtD`Ol(*MI%b;Pj#QtqmL%XAAvB7SZfgg>G726CS?bN~PV literal 0 HcmV?d00001 diff --git a/tools/pcre/testdata/saved16BE-2 b/tools/pcre/testdata/saved16BE-2 new file mode 100644 index 0000000000000000000000000000000000000000..dade400e96556e635a2a21998fb03f09c88a650a GIT binary patch literal 336 zcmZusF$w}P5S)aAv$C?VIBaasLb0(E)XGNufr=t{jp@bb_zepmagambU@a0S8}w2* zFq56h?vem11CTE!%Ne9@0Gf%XM;qy{4oOgr4b~XY^hqVoU?uK^EzamMEja((m1lI9n;5Hu-)KS4boJEK z^fb5;&>IZ<@yJ0##6LnCEh;&;{1c8fV^+-aqG!XNL~JL1hbvaYli%V*9@x(6n`dSILv{el)eZUh*5k2W^m%gf= nuUQHQI=a=eTULH)eiI!B3iY2z9q6^4W})#a{!O6hP*&j%f@(B$ literal 0 HcmV?d00001 diff --git a/tools/pcre/testdata/saved16LE-2 b/tools/pcre/testdata/saved16LE-2 new file mode 100644 index 0000000000000000000000000000000000000000..c8be985756cf3442483356e21337ae5f72c76318 GIT binary patch literal 336 zcmZutF$w}P5S)aAv$C?VIBaaSP;Bf3wXzX^prQzOjp@bb_>C)kL?A)mU@a0S33?~E zu-TnuX0iz&G622#YP!q>y9OXxeEMi3{q}JZPl+uy7!nMaA|QozKqu^QMxWDy`j1o4 zB|j)yc}C)ly8{O#oE2yW&+dZ@>9LiVXxNz^-GDug=#Y`sd_9|y#!{UUrGYKY#R^=F iS1T;IS&P~nt`;xno;4U+MV{hI_&LmfdsjEb&U4<+tv{In literal 0 HcmV?d00001 diff --git a/tools/pcre/testdata/saved32 b/tools/pcre/testdata/saved32 new file mode 100644 index 0000000000000000000000000000000000000000..255235d37596ccca66ecc26c97a8643df92cce0a GIT binary patch literal 100 zcmZQzV2EJ=0@ont05Ai{4gm=OK_U<*12GSXg9d7Wd=4O%1!9mo5S;|2L3)aS7$gq@ E06=R6g8%>k literal 0 HcmV?d00001 diff --git a/tools/pcre/testdata/saved32BE-1 b/tools/pcre/testdata/saved32BE-1 new file mode 100644 index 0000000000000000000000000000000000000000..42af7b42b026869ac20fae8a78430470c298a8e3 GIT binary patch literal 544 zcmaiwI|{;35Je}6Uq}(L5(_tw1*8}I-~t3uLHwd@o=c*3AXpT=kmA_7|&`jEe_AZ5> I+5V~V0$e6E<^TWy literal 0 HcmV?d00001 diff --git a/tools/pcre/testdata/saved32BE-2 b/tools/pcre/testdata/saved32BE-2 new file mode 100644 index 0000000000000000000000000000000000000000..68a896d45b06c4208c0f52f803409d020d47b376 GIT binary patch literal 448 zcmZvYO$x#=5Jo4VP{E>6Patl)QQWu|U5htRK?L3CUc7+!@O-XC;+wQ7DLCcjo4-tw zikPQ}l$+&tCBg5AWMnKvD|wJb>f8Tjn#BcH+W(0dxCHH7N`x=?QmY#kLVRfp!){U9N8nl@=98(6-Vsk q#cISg^YooMTi;cH&N}CA$xHa&f*P_h=dDw@dEoEp3hmNzQ46mVv?^j)A>7{ z)-0*aY&2iZmQ_O3Fw1Z$)Yh{6E7!j2TiCz^WaHpWZR*;YcpcR)#0$8>0Hi%a2jV+P zv!9%;w}t_oD}26Z)x0wGY5FMi9o~bVa!cryTG_H^zMr9RX->E-n=vJu3y_{~3yG%qnIF@695 literal 0 HcmV?d00001 diff --git a/tools/pcre/testdata/saved8 b/tools/pcre/testdata/saved8 new file mode 100644 index 0000000000000000000000000000000000000000..9b63b1db7291335c3a3b6a714f34191db163ed76 GIT binary patch literal 61 ucmZQzU@&C>0@ont05Ai{4g?7RK_Wvkg9d~NCu= 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 + The quick brown FOX + What do you know about the quick brown fox? + What do you know about THE QUICK BROWN FOX? + +/The quick brown fox/i + the quick brown fox + The quick brown FOX + What do you know about the quick brown fox? + What do you know about THE QUICK BROWN FOX? + +/abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/ + abcd\t\n\r\f\a\e9;\$\\?caxyz + +/a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ + abxyzpqrrrabbxyyyypqAzz + abxyzpqrrrabbxyyyypqAzz + aabxyzpqrrrabbxyyyypqAzz + aaabxyzpqrrrabbxyyyypqAzz + aaaabxyzpqrrrabbxyyyypqAzz + abcxyzpqrrrabbxyyyypqAzz + aabcxyzpqrrrabbxyyyypqAzz + aaabcxyzpqrrrabbxyyyypAzz + aaabcxyzpqrrrabbxyyyypqAzz + aaabcxyzpqrrrabbxyyyypqqAzz + aaabcxyzpqrrrabbxyyyypqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqqqAzz + aaaabcxyzpqrrrabbxyyyypqAzz + abxyzzpqrrrabbxyyyypqAzz + aabxyzzzpqrrrabbxyyyypqAzz + aaabxyzzzzpqrrrabbxyyyypqAzz + aaaabxyzzzzpqrrrabbxyyyypqAzz + abcxyzzpqrrrabbxyyyypqAzz + aabcxyzzzpqrrrabbxyyyypqAzz + aaabcxyzzzzpqrrrabbxyyyypqAzz + aaaabcxyzzzzpqrrrabbxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyyypqAzz + aaabcxyzpqrrrabbxyyyypABzz + aaabcxyzpqrrrabbxyyyypABBzz + >>>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 + +/\A(abc|def)=(\1){2,3}\Z/ + abc=abcabc + def=defdefdef + *** Failers + abc=defdef + +/^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/ + abcdefghijkcda2 + abcdefghijkkkkcda2 + +/(cat(a(ract|tonic)|erpillar)) \1()2(3)/ + cataract cataract23 + catatonic catatonic23 + caterpillar caterpillar23 + + +/^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 + +/^(a)\1{2,3}(.)/ + aaab + aaaab + aaaaab + aaaaaab + +/(?!^)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 ]{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 + +/(AB)*?\1/ + ABABAB + +/(AB)*\1/ + ABABAB + +/(?.*/)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 + +/((?>[^()]+)|\([^()]*\))+/ + ((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 + +/(?:(a)|b)(?(1)A|B)/ + aA + bB + *** Failers + aB + bA + +/^(a)?(?(1)a|b)+$/ + aa + b + bb + *** Failers + ab + +/^(?(?=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 + +/(?<=(foo))bar\1/ + foobarfoo + foobarfootling + *** Failers + foobar + barfoo + +/(?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 + +/^(a\1?){4}$/ + aaaaaaaaaa + *** Failers + AB + aaaaaaaaa + aaaaaaaaaaa + +/^(a(?(1)\1)){4}$/ + aaaaaaaaaa + *** Failers + aaaaaaaaa + aaaaaaaaaaa + +/(?:(f)(o)(o)|(b)(a)(r))*/ + foobar + +/(?<=a)b/ + ab + *** Failers + cb + b + +/(?a+)ab/ + +/(?>a+)b/ + aaab + +/([[:]+)/ + a:[b]: + +/([[=]+)/ + a=[b]= + +/([[.]+)/ + a.[b]. + +/((?>a+)b)/ + aaab + +/(?>(a+))b/ + aaab + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/a\Z/ + *** Failers + aaab + a\nb\n + +/b\Z/ + a\nb\n + +/b\z/ + +/b\Z/ + a\nb + +/b\z/ + a\nb + *** Failers + +/^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/ + a + abc + a-b + 0-9 + a.b + 5.6.7 + the.quick.brown.fox + a100.b200.300c + 12-ab.1245 + *** Failers + \ + .a + -a + a- + a. + a_b + a.- + a.. + ab..bc + the.quick.brown.fox- + the.quick.brown.fox. + the.quick.brown.fox_ + the.quick.brown.fox+ + +/(?>.*)(?<=(abcd|wxyz))/ + alphabetabcd + endingwxyz + *** Failers + a rather long string that doesn't end with one of them + +/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark + +/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope + +/(?<=\d{3}(?!999))foo/ + 999foo + 123999foo + *** Failers + 123abcfoo + +/(?<=(?!...999)\d{3})foo/ + 999foo + 123999foo + *** Failers + 123abcfoo + +/(?<=\d{3}(?!999)...)foo/ + 123abcfoo + 123456foo + *** Failers + 123999foo + +/(?<=\d{3}...)(?\s*)=(?>\s*) # find Z)+|A)*/ + ZABCDEFG + +/((?>)+|A)*/ + ZABCDEFG + +/a*/g + abbab + +/^[a-\d]/ + abcde + -things + 0digit + *** Failers + bcdef + +/^[\d-a]/ + abcde + -things + 0digit + *** Failers + bcdef + +/[[:space:]]+/ + > \x09\x0a\x0c\x0d\x0b< + +/[[:blank:]]+/ + > \x09\x0a\x0c\x0d\x0b< + +/[\s]+/ + > \x09\x0a\x0c\x0d\x0b< + +/\s+/ + > \x09\x0a\x0c\x0d\x0b< + +/a b/x + ab + +/(?!\A)x/m + a\nxb\n + +/(?!^)x/m + a\nxb\n + +/abc\Qabc\Eabc/ + abcabcabc + +/abc\Q(*+|\Eabc/ + abc(*+|abc + +/ abc\Q abc\Eabc/x + abc abcabc + *** Failers + abcabcabc + +/abc#comment + \Q#not comment + literal\E/x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal/x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal\E #more comment + /x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal\E #more comment/x + abc#not comment\n literal + +/\Qabc\$xyz\E/ + abc\\\$xyz + +/\Qabc\E\$\Qxyz\E/ + abc\$xyz + +/\Gabc/ + abc + *** Failers + xyzabc + +/\Gabc./g + abc1abc2xyzabc3 + +/abc./g + abc1abc2xyzabc3 + +/a(?x: b c )d/ + XabcdY + *** Failers + Xa b c d Y + +/((?x)x y z | a b c)/ + XabcY + AxyzB + +/(?i)AB(?-i)C/ + XabCY + *** Failers + XabcY + +/((?i)AB(?-i)C|D)E/ + abCE + DE + *** Failers + abcE + abCe + dE + De + +/(.*)\d+\1/ + abc123abc + abc123bc + +/(.*)\d+\1/s + abc123abc + abc123bc + +/((.*))\d+\1/ + abc123abc + abc123bc + +/-- This tests for an IPv6 address in the form where it can have up to --/ +/-- eight components, one and only one of which is empty. This must be --/ +/-- an internal component. --/ + +/^(?!:) # colon disallowed at start + (?: # start of item + (?: [0-9a-f]{1,4} | # 1-4 hex digits or + (?(1)0 | () ) ) # if null previously matched, fail; else null + : # followed by colon + ){1,7} # end item; 1-7 of them required + [0-9a-f]{1,4} $ # final hex number at end of string + (?(1)|.) # check that there was an empty component + /xi + a123::a123 + a123:b342::abcd + a123:b342::324e:abcd + a123:ddde:b342::324e:abcd + a123:ddde:b342::324e:dcba:abcd + a123:ddde:9999:b342::324e:dcba:abcd + *** Failers + 1:2:3:4:5:6:7:8 + a123:bce:ddde:9999:b342::324e:dcba:abcd + a123::9999:b342::324e:dcba:abcd + abcde:2:3:4:5:6:7:8 + ::1 + abcd:fee0:123:: + :1 + 1: + +/[z\Qa-d]\E]/ + z + a + - + d + ] + *** Failers + b + +/[\z\C]/ + z + C + +/\M/ + M + +/(a+)*b/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ + REGular + regulaer + Regex + regulär + +/Åæåä[à-ÿÀ-ß]+/ + Åæåäà + Åæåäÿ + ÅæåäÀ + Åæåäß + +/(?<=Z)X./ + \x84XAZXB + +/ab cd (?x) de fg/ + ab cd defg + +/ab cd(?x) de fg/ + ab cddefg + ** Failers + abcddefg + +/(?a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?:a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/\Z/g + abc\n + +/^(?s)(?>.*)(?(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 + +/(?>.*?a)(?<=ba)/ + aba + +/(?:.*?a)(?<=ba)/ + aba + +/.*?a(*PRUNE)b/ + aab + +/.*?a(*PRUNE)b/s + aab + +/^a(*PRUNE)b/s + aab + +/.*?a(*SKIP)b/ + aab + +/(?>.*?a)b/s + aab + +/(?>.*?a)b/ + aab + +/(?>^a)b/s + aab + +/(?>.*?)(?<=(abcd)|(wxyz))/ + alphabetabcd + endingwxyz + +/(?>.*)(?<=(abcd)|(wxyz))/ + alphabetabcd + endingwxyz + +"(?>.*)foo" + abcdfooxyz + +"(?>.*?)foo" + abcdfooxyz + +/-- End of testinput1 --/ diff --git a/tools/pcre/testdata/testinput10 b/tools/pcre/testdata/testinput10 new file mode 100644 index 00000000..f20dcb3d --- /dev/null +++ b/tools/pcre/testdata/testinput10 @@ -0,0 +1,1337 @@ +/-- 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} + +/^>\p{Xsp}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xsp}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xsp}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>[\p{Xsp}]/8 + >\x{2028}\x{0b} + +/^>[\p{Xsp}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}/8 + >\x{1680}\x{2028}\x{0b} + >\x{a0} + ** Failers + \x{0b} + +/^>\p{Xps}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}+?/8 + >\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>[\p{Xps}]/8 + >\x{2028}\x{0b} + +/^>[\p{Xps}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^\p{Xwd}/8 + ABCD + 1234 + \x{6ca} + \x{a6c} + \x{10a7} + _ABC + ** Failers + [] + +/^\p{Xwd}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}{2,9}/8 + A_12\x{6ca}\x{a6c}\x{10a7} + +/^[\p{Xwd}]/8 + ABCD1234_ + 1234abcd_ + \x{6ca} + \x{a6c} + \x{10a7} + _ABC + ** Failers + [] + +/^[\p{Xwd}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/-- Unicode properties for \b abd \B --/ + +/\b...\B/8W + abc_ + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ + +/\b...\B/8 + abc_ + ** Failers + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ + +/\b...\B/W + abc_ + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- Caseless single negated characters > 127 need UCP support --/ + +/[^\x{100}]/8i + \x{100}\x{101}X + +/[^\x{100}]+/8i + \x{100}\x{101}XX + +/^\X/8 + A\P + A\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{301}\P + A\x{301}\P\P + +/^\X{2,3}/8 + A\P + A\P\P + AA\P + AA\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X{2}/8 + AA\P + AA\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X+/8 + AA\P + AA\P\P + +/^\X+?Z/8 + AA\P + AA\P\P + +/-- These are tests for extended grapheme clusters --/ + +/^\X/8+ + G\x{34e}\x{34e}X + \x{34e}\x{34e}X + \x04X + \x{1100}X + \x{1100}\x{34e}X + \x{1b04}\x{1b04}X + *These match up to the roman letters + \x{1111}\x{1111}L,L + \x{1111}\x{1111}\x{1169}L,L,V + \x{1111}\x{ae4c}L, LV + \x{1111}\x{ad89}L, LVT + \x{1111}\x{ae4c}\x{1169}L, LV, V + \x{1111}\x{ae4c}\x{1169}\x{1169}L, LV, V, V + \x{1111}\x{ae4c}\x{1169}\x{11fe}L, LV, V, T + \x{1111}\x{ad89}\x{11fe}L, LVT, T + \x{1111}\x{ad89}\x{11fe}\x{11fe}L, LVT, T, T + \x{ad89}\x{11fe}\x{11fe}LVT, T, T + *These match just the first codepoint (invalid sequence) + \x{1111}\x{11fe}L, T + \x{ae4c}\x{1111}LV, L + \x{ae4c}\x{ae4c}LV, LV + \x{ae4c}\x{ad89}LV, LVT + \x{1169}\x{1111}V, L + \x{1169}\x{ae4c}V, LV + \x{1169}\x{ad89}V, LVT + \x{ad89}\x{1111}LVT, L + \x{ad89}\x{1169}LVT, V + \x{ad89}\x{ae4c}LVT, LV + \x{ad89}\x{ad89}LVT, LVT + \x{11fe}\x{1111}T, L + \x{11fe}\x{1169}T, V + \x{11fe}\x{ae4c}T, LV + \x{11fe}\x{ad89}T, LVT + *Test extend and spacing mark + \x{1111}\x{ae4c}\x{0711}L, LV, extend + \x{1111}\x{ae4c}\x{1b04}L, LV, spacing mark + \x{1111}\x{ae4c}\x{1b04}\x{0711}\x{1b04}L, LV, spacing mark, extend, spacing mark + *Test CR, LF, and control + \x0d\x{0711}CR, extend + \x0d\x{1b04}CR, spacingmark + \x0a\x{0711}LF, extend + \x0a\x{1b04}LF, spacingmark + \x0b\x{0711}Control, extend + \x09\x{1b04}Control, spacingmark + *There are no Prepend characters, so we can't test Prepend, CR + +/^(?>\X{2})X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + +/^\X{2,4}X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + +/^\X{2,4}?X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + +/-- --/ + +/\x{1e9e}+/8i + \x{1e9e}\x{00df} + +/[z\x{1e9e}]+/8i + \x{1e9e}\x{00df} + +/\x{00df}+/8i + \x{1e9e}\x{00df} + +/[z\x{00df}]+/8i + \x{1e9e}\x{00df} + +/\x{1f88}+/8i + \x{1f88}\x{1f80} + +/[z\x{1f88}]+/8i + \x{1f88}\x{1f80} + +/-- Perl matches these --/ + +/\x{00b5}+/8i + \x{00b5}\x{039c}\x{03bc} + +/\x{039c}+/8i + \x{00b5}\x{039c}\x{03bc} + +/\x{03bc}+/8i + \x{00b5}\x{039c}\x{03bc} + + +/\x{00c5}+/8i + \x{00c5}\x{00e5}\x{212b} + +/\x{00e5}+/8i + \x{00c5}\x{00e5}\x{212b} + +/\x{212b}+/8i + \x{00c5}\x{00e5}\x{212b} + + +/\x{01c4}+/8i + \x{01c4}\x{01c5}\x{01c6} + +/\x{01c5}+/8i + \x{01c4}\x{01c5}\x{01c6} + +/\x{01c6}+/8i + \x{01c4}\x{01c5}\x{01c6} + + +/\x{01c7}+/8i + \x{01c7}\x{01c8}\x{01c9} + +/\x{01c8}+/8i + \x{01c7}\x{01c8}\x{01c9} + +/\x{01c9}+/8i + \x{01c7}\x{01c8}\x{01c9} + + +/\x{01ca}+/8i + \x{01ca}\x{01cb}\x{01cc} + +/\x{01cb}+/8i + \x{01ca}\x{01cb}\x{01cc} + +/\x{01cc}+/8i + \x{01ca}\x{01cb}\x{01cc} + + +/\x{01f1}+/8i + \x{01f1}\x{01f2}\x{01f3} + +/\x{01f2}+/8i + \x{01f1}\x{01f2}\x{01f3} + +/\x{01f3}+/8i + \x{01f1}\x{01f2}\x{01f3} + + +/\x{0345}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + +/\x{0399}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + +/\x{03b9}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + +/\x{1fbe}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + + +/\x{0392}+/8i + \x{0392}\x{03b2}\x{03d0} + +/\x{03b2}+/8i + \x{0392}\x{03b2}\x{03d0} + +/\x{03d0}+/8i + \x{0392}\x{03b2}\x{03d0} + + +/\x{0395}+/8i + \x{0395}\x{03b5}\x{03f5} + +/\x{03b5}+/8i + \x{0395}\x{03b5}\x{03f5} + +/\x{03f5}+/8i + \x{0395}\x{03b5}\x{03f5} + + +/\x{0398}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + +/\x{03b8}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + +/\x{03d1}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + +/\x{03f4}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + + +/\x{039a}+/8i + \x{039a}\x{03ba}\x{03f0} + +/\x{03ba}+/8i + \x{039a}\x{03ba}\x{03f0} + +/\x{03f0}+/8i + \x{039a}\x{03ba}\x{03f0} + + +/\x{03a0}+/8i + \x{03a0}\x{03c0}\x{03d6} + +/\x{03c0}+/8i + \x{03a0}\x{03c0}\x{03d6} + +/\x{03d6}+/8i + \x{03a0}\x{03c0}\x{03d6} + + +/\x{03a1}+/8i + \x{03a1}\x{03c1}\x{03f1} + +/\x{03c1}+/8i + \x{03a1}\x{03c1}\x{03f1} + +/\x{03f1}+/8i + \x{03a1}\x{03c1}\x{03f1} + + +/\x{03a3}+/8i + \x{03A3}\x{03C2}\x{03C3} + +/\x{03c2}+/8i + \x{03A3}\x{03C2}\x{03C3} + +/\x{03c3}+/8i + \x{03A3}\x{03C2}\x{03C3} + + +/\x{03a6}+/8i + \x{03a6}\x{03c6}\x{03d5} + +/\x{03c6}+/8i + \x{03a6}\x{03c6}\x{03d5} + +/\x{03d5}+/8i + \x{03a6}\x{03c6}\x{03d5} + + +/\x{03c9}+/8i + \x{03c9}\x{03a9}\x{2126} + +/\x{03a9}+/8i + \x{03c9}\x{03a9}\x{2126} + +/\x{2126}+/8i + \x{03c9}\x{03a9}\x{2126} + + +/\x{1e60}+/8i + \x{1e60}\x{1e61}\x{1e9b} + +/\x{1e61}+/8i + \x{1e60}\x{1e61}\x{1e9b} + +/\x{1e9b}+/8i + \x{1e60}\x{1e61}\x{1e9b} + + +/\x{1e9e}+/8i + \x{1e9e}\x{00df} + +/\x{00df}+/8i + \x{1e9e}\x{00df} + + +/\x{1f88}+/8i + \x{1f88}\x{1f80} + +/\x{1f80}+/8i + \x{1f88}\x{1f80} + +/\x{004b}+/8i + \x{004b}\x{006b}\x{212a} + +/\x{006b}+/8i + \x{004b}\x{006b}\x{212a} + +/\x{212a}+/8i + \x{004b}\x{006b}\x{212a} + + +/\x{0053}+/8i + \x{0053}\x{0073}\x{017f} + +/\x{0073}+/8i + \x{0053}\x{0073}\x{017f} + +/\x{017f}+/8i + \x{0053}\x{0073}\x{017f} + +/ist/8i + ikt + +/is+t/8i + iSs\x{17f}t + ikt + +/is+?t/8i + ikt + +/is?t/8i + ikt + +/is{2}t/8i + iskt + +/-- End of testinput10 --/ diff --git a/tools/pcre/testdata/testinput11 b/tools/pcre/testdata/testinput11 new file mode 100644 index 00000000..391ada7a --- /dev/null +++ b/tools/pcre/testdata/testinput11 @@ -0,0 +1,135 @@ +/-- These are a few representative patterns whose lengths and offsets are to be +shown when the link size is 2. This is just a doublecheck test to ensure the +sizes don't go horribly wrong when something is changed. The pattern contents +are all themselves checked in other tests. Unicode, including property support, +is required for these tests. --/ + +/((?i)b)/BM + +/(?s)(.*X|^B)/BM + +/(?s:.*X|^B)/BM + +/^[[:alnum:]]/BM + +/#/IxMD + +/a#/IxMD + +/x?+/BM + +/x++/BM + +/x{1,3}+/BM + +/(x)*+/BM + +/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM + +|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\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{10ffff}/8BM + +/\x{110000}/8BM + +/[\x{ff}]/8BM + +/[\x{100}]/8BM + +/\x80/8BM + +/\xff/8BM + +/\x{0041}\x{2262}\x{0391}\x{002e}/D8M + +/\x{D55c}\x{ad6d}\x{C5B4}/D8M + +/\x{65e5}\x{672c}\x{8a9e}/D8M + +/[\x{100}]/8BM + +/[Z\x{100}]/8BM + +/^[\x{100}\E-\Q\E\x{150}]/B8M + +/^[\QÄ€\E-\QÅ\E]/B8M + +/^[\QÄ€\E-\QÅ\E/B8M + +/[\p{L}]/BM + +/[\p{^L}]/BM + +/[\P{L}]/BM + +/[\P{^L}]/BM + +/[abc\p{L}\x{0660}]/8BM + +/[\p{Nd}]/8BM + +/[\p{Nd}+-]+/8BM + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM + +/[\x{105}-\x{109}]/8iBM + +/( ( (?(1)0|) )* )/xBM + +/( (?(1)0|)* )/xBM + +/[a]/BM + +/[a]/8BM + +/[\xaa]/BM + +/[\xaa]/8BM + +/[^a]/BM + +/[^a]/8BM + +/[^\xaa]/BM + +/[^\xaa]/8BM + +/[^\d]/8WB + +/[[:^alpha:][:^cntrl:]]+/8WB + +/[[:^cntrl:][:^alpha:]]+/8WB + +/[[:alpha:]]+/8WB + +/[[:^alpha:]\S]+/8WB + +/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B + +/-- End of testinput11 --/ diff --git a/tools/pcre/testdata/testinput12 b/tools/pcre/testdata/testinput12 new file mode 100644 index 00000000..7deba3c4 --- /dev/null +++ b/tools/pcre/testdata/testinput12 @@ -0,0 +1,89 @@ +/-- This test is run only when JIT support is available. It checks for a +successful and an unsuccessful JIT compile and save and restore behaviour, +and a couple of things that are different with JIT. --/ + +/abc/S+I + +/ab(*THEN)/S+I + +/abc/S+I>testsavedregex + +b)c/PN + abc + +/a?|b?/P + abc + ** Failers + ddd\N + +/\w+A/P + CDAAAAB + +/\w+A/PU + CDAAAAB + +/\Biss\B/I+P + Mississippi + +/abc/\P + +/-- End of POSIX tests --/ + +/a\Cb/ + aXb + a\nb + ** Failers (too big char) + A\x{123}B + +/\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 --git a/tools/pcre/testdata/testinput15 b/tools/pcre/testdata/testinput15 new file mode 100644 index 00000000..6445d435 --- /dev/null +++ b/tools/pcre/testdata/testinput15 @@ -0,0 +1,430 @@ +/-- 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 + +/badutf/8 + \xdf + \xef + \xef\x80 + \xf7 + \xf7\x80 + \xf7\x80\x80 + \xfb + \xfb\x80 + \xfb\x80\x80 + \xfb\x80\x80\x80 + \xfd + \xfd\x80 + \xfd\x80\x80 + \xfd\x80\x80\x80 + \xfd\x80\x80\x80\x80 + \xdf\x7f + \xef\x7f\x80 + \xef\x80\x7f + \xf7\x7f\x80\x80 + \xf7\x80\x7f\x80 + \xf7\x80\x80\x7f + \xfb\x7f\x80\x80\x80 + \xfb\x80\x7f\x80\x80 + \xfb\x80\x80\x7f\x80 + \xfb\x80\x80\x80\x7f + \xfd\x7f\x80\x80\x80\x80 + \xfd\x80\x7f\x80\x80\x80 + \xfd\x80\x80\x7f\x80\x80 + \xfd\x80\x80\x80\x7f\x80 + \xfd\x80\x80\x80\x80\x7f + \xed\xa0\x80 + \xc0\x8f + \xe0\x80\x8f + \xf0\x80\x80\x8f + \xf8\x80\x80\x80\x8f + \xfc\x80\x80\x80\x80\x8f + \x80 + \xfe + \xff + \xef\xb7\x90 + +/badutf/8 + \xfb\x80\x80\x80\x80 + \xfd\x80\x80\x80\x80\x80 + \xf7\xbf\xbf\xbf + +/shortutf/8 + \P\P\xdf + \P\P\xef + \P\P\xef\x80 + \P\P\xf7 + \P\P\xf7\x80 + \P\P\xf7\x80\x80 + \P\P\xfb + \P\P\xfb\x80 + \P\P\xfb\x80\x80 + \P\P\xfb\x80\x80\x80 + \P\P\xfd + \P\P\xfd\x80 + \P\P\xfd\x80\x80 + \P\P\xfd\x80\x80\x80 + \P\P\xfd\x80\x80\x80\x80 + +/anything/8 + \xc0\x80 + \xc1\x8f + \xe0\x9f\x80 + \xf0\x8f\x80\x80 + \xf8\x87\x80\x80\x80 + \xfc\x83\x80\x80\x80\x80 + \xfe\x80\x80\x80\x80\x80 + \xff\x80\x80\x80\x80\x80 + \xc3\x8f + \xe0\xaf\x80 + \xe1\x80\x80 + \xf0\x9f\x80\x80 + \xf1\x8f\x80\x80 + \xf8\x88\x80\x80\x80 + \xf9\x87\x80\x80\x80 + \xfc\x84\x80\x80\x80\x80 + \xfd\x83\x80\x80\x80\x80 + \?\xf8\x88\x80\x80\x80 + \?\xf9\x87\x80\x80\x80 + \?\xfc\x84\x80\x80\x80\x80 + \?\xfd\x83\x80\x80\x80\x80 + +/noncharacter/8 + \x{fffe} + \x{ffff} + \x{1fffe} + \x{1ffff} + \x{2fffe} + \x{2ffff} + \x{3fffe} + \x{3ffff} + \x{4fffe} + \x{4ffff} + \x{5fffe} + \x{5ffff} + \x{6fffe} + \x{6ffff} + \x{7fffe} + \x{7ffff} + \x{8fffe} + \x{8ffff} + \x{9fffe} + \x{9ffff} + \x{afffe} + \x{affff} + \x{bfffe} + \x{bffff} + \x{cfffe} + \x{cffff} + \x{dfffe} + \x{dffff} + \x{efffe} + \x{effff} + \x{ffffe} + \x{fffff} + \x{10fffe} + \x{10ffff} + \x{fdd0} + \x{fdd1} + \x{fdd2} + \x{fdd3} + \x{fdd4} + \x{fdd5} + \x{fdd6} + \x{fdd7} + \x{fdd8} + \x{fdd9} + \x{fdda} + \x{fddb} + \x{fddc} + \x{fddd} + \x{fdde} + \x{fddf} + \x{fde0} + \x{fde1} + \x{fde2} + \x{fde3} + \x{fde4} + \x{fde5} + \x{fde6} + \x{fde7} + \x{fde8} + \x{fde9} + \x{fdea} + \x{fdeb} + \x{fdec} + \x{fded} + \x{fdee} + \x{fdef} + +/\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)(*UTF)(*BSR_UNICODE)a\Rb/I + +/\h/SI8 + ABC\x{09} + ABC\x{20} + ABC\x{a0} + ABC\x{1680} + ABC\x{180e} + ABC\x{2000} + ABC\x{202f} + ABC\x{205f} + ABC\x{3000} + +/\v/SI8 + ABC\x{0a} + ABC\x{0b} + ABC\x{0c} + ABC\x{0d} + ABC\x{85} + ABC\x{2028} + +/\h*A/SI8 + CDBABC + +/\v+A/SI8 + +/\s?xxx\s/8SI + +/\sxxx\s/I8ST1 + AB\x{85}xxx\x{a0}XYZ + AB\x{a0}xxx\x{85}XYZ + +/\S \S/I8ST1 + \x{a2} \x{84} + A Z + +/a+/8 + a\x{123}aa\>1 + a\x{123}aa\>2 + a\x{123}aa\>3 + a\x{123}aa\>4 + a\x{123}aa\>5 + a\x{123}aa\>6 + +/\x{1234}+/iS8I + +/\x{1234}+?/iS8I + +/\x{1234}++/iS8I + +/\x{1234}{2}/iS8I + +/[^\x{c4}]/8DZ + +/X+\x{200}/8DZ + +/\R/SI8 + +/\777/8DZ + +/\w+\x{C4}/8BZ + a\x{C4}\x{C4} + +/\w+\x{C4}/8BZT1 + a\x{C4}\x{C4} + +/\W+\x{C4}/8BZ + !\x{C4} + +/\W+\x{C4}/8BZT1 + !\x{C4} + +/\W+\x{A1}/8BZ + !\x{A1} + +/\W+\x{A1}/8BZT1 + !\x{A1} + +/X\s+\x{A0}/8BZ + X\x20\x{A0}\x{A0} + +/X\s+\x{A0}/8BZT1 + X\x20\x{A0}\x{A0} + +/\S+\x{A0}/8BZ + X\x{A0}\x{A0} + +/\S+\x{A0}/8BZT1 + X\x{A0}\x{A0} + +/\x{a0}+\s!/8BZ + \x{a0}\x20! + +/\x{a0}+\s!/8BZT1 + \x{a0}\x20! + +/A/8 + \x{ff000041} + \x{7f000041} + +/-- End of testinput15 --/ diff --git a/tools/pcre/testdata/testinput16 b/tools/pcre/testdata/testinput16 new file mode 100644 index 00000000..e7a05ae0 --- /dev/null +++ b/tools/pcre/testdata/testinput16 @@ -0,0 +1,35 @@ +/-- This set of tests is run only with the 8-bit library when Unicode property + support is available. It starts with tests of the POSIX interface, because + that is supported only with the 8-bit library. --/ + +/\w/P + +++\x{c2} + +/\w/WP + +++\x{c2} + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ + +/AB\x{1fb0}/8DZ + +/AB\x{1fb0}/8DZi + +/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI + \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + +/[â±¥]/8iBZ + +/[^â±¥]/8iBZ + +/\h/SI + +/\v/SI + +/\R/SI + +/[[:blank:]]/WBZ + +/-- End of testinput16 --/ diff --git a/tools/pcre/testdata/testinput17 b/tools/pcre/testdata/testinput17 new file mode 100644 index 00000000..ba803188 --- /dev/null +++ b/tools/pcre/testdata/testinput17 @@ -0,0 +1,296 @@ +/-- This set of tests is for the 16- and 32-bit library's basic (non-UTF-16 + or -32) features that are not compatible with the 8-bit library, or which + give different output in 16- or 32-bit mode. --/ + +/a\Cb/ + aXb + a\nb + +/[^\x{c4}]/DZ + +/\x{100}/I + +/ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional leading comment +(?: (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # one word, optionally followed by.... +(?: +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... +\( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) | # comments, or... + +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +# quoted strings +)* +< (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # leading < +(?: @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* + +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* , (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +)* # further okay, if led by comma +: # closing colon +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* )? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address spec +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* > # trailing > +# name and address +) (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional trailing comment +/xSI + +/[\h]/BZ + >\x09< + +/[\h]+/BZ + >\x09\x20\xa0< + +/[\v]/BZ + +/[^\h]/BZ + +/\h+/SI + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\xa0\x{2000} + +/[\h\x{dc00}]+/BZSI + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\xa0\x{2000} + +/\H+/SI + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} + +/[\H\x{d800}]+/ + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} + +/\v+/SI + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + +/[\v\x{dc00}]+/BZSI + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + +/\V+/SI + \x{2028}\x{2029}\x{2027}\x{2030} + \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 + +/[\V\x{d800}]+/ + \x{2028}\x{2029}\x{2027}\x{2030} + \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 + +/\R+/SI + \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 + +/^\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 testinput17 --/ diff --git a/tools/pcre/testdata/testinput18 b/tools/pcre/testdata/testinput18 new file mode 100644 index 00000000..7f87ca2c --- /dev/null +++ b/tools/pcre/testdata/testinput18 @@ -0,0 +1,296 @@ +/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to the + 16- and 32-bit library. --/ + +/ÃÃÃxxx/8?DZSS + +/abc/8 + Ã] + +/X(\C{3})/8 + X\x{11234}Y + X\x{11234}YZ + +/X(\C{4})/8 + X\x{11234}YZ + X\x{11234}YZW + +/X\C*/8 + XYZabcdce + +/X\C*?/8 + XYZabcde + +/X\C{3,5}/8 + Xabcdefg + X\x{11234}Y + X\x{11234}YZ + X\x{11234}\x{512} + X\x{11234}\x{512}YZ + X\x{11234}\x{512}\x{11234}Z + +/X\C{3,5}?/8 + Xabcdefg + X\x{11234}Y + X\x{11234}YZ + X\x{11234}\x{512}YZ + *** Failers + X\x{11234} + +/a\Cb/8 + aXb + a\nb + +/a\C\Cb/8 + a\x{12257}b + a\x{12257}\x{11234}b + ** Failers + a\x{100}b + +/ab\Cde/8 + abXde + +/-- Check maximum character size --/ + +/\x{ffff}/8DZ + +/\x{10000}/8DZ + +/\x{100}/8DZ + +/\x{1000}/8DZ + +/\x{10000}/8DZ + +/\x{100000}/8DZ + +/\x{10ffff}/8DZ + +/[\x{ff}]/8DZ + +/[\x{100}]/8DZ + +/\x80/8DZ + +/\xff/8DZ + +/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 + \x{D55c}\x{ad6d}\x{C5B4} + +/\x{65e5}\x{672c}\x{8a9e}/DZ8 + \x{65e5}\x{672c}\x{8a9e} + +/\x{80}/DZ8 + +/\x{084}/DZ8 + +/\x{104}/DZ8 + +/\x{861}/DZ8 + +/\x{212ab}/DZ8 + +/-- This one is here not because it's different to Perl, but because the way +the captured single-byte is displayed. (In Perl it becomes a character, and you +can't tell the difference.) --/ + +/X(\C)(.*)/8 + X\x{1234} + X\nabc + +/-- This one is here because Perl gives out a grumbly error message (quite +correctly, but that messes up comparisons). --/ + +/a\Cb/8 + *** Failers + a\x{100}b + +/[^ab\xC0-\xF0]/8SDZ + \x{f1} + \x{bf} + \x{100} + \x{1000} + *** Failers + \x{c0} + \x{f0} + +/Ä€{3,4}/8SDZ + \x{100}\x{100}\x{100}\x{100\x{100} + +/(\x{100}+|x)/8SDZ + +/(\x{100}*a|x)/8SDZ + +/(\x{100}{0,2}a|x)/8SDZ + +/(\x{100}{1,2}a|x)/8SDZ + +/\x{100}/8DZ + +/a\x{100}\x{101}*/8DZ + +/a\x{100}\x{101}+/8DZ + +/[^\x{c4}]/DZ + +/[\x{100}]/8DZ + \x{100} + Z\x{100} + \x{100}Z + *** Failers + +/[\xff]/DZ8 + >\x{ff}< + +/[^\xff]/8DZ + +/\x{100}abc(xyz(?1))/8DZ + +/\777/8I + \x{1ff} + \777 + +/\x{100}+\x{200}/8DZ + +/\x{100}+X/8DZ + +/^[\QÄ€\E-\QÅ\E/BZ8 + +/X/8 + \x{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 + +/(*UTF)\x{11234}/I + abcd\x{11234}pqr + +/(*UTF-32)\x{11234}/ + abcd\x{11234}pqr + +/(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I + +/(*CRLF)(*UTF32)(*BSR_UNICODE)a\Rb/I + +/\h/SI8 + ABC\x{09} + ABC\x{20} + ABC\x{a0} + ABC\x{1680} + ABC\x{180e} + ABC\x{2000} + ABC\x{202f} + ABC\x{205f} + ABC\x{3000} + +/\v/SI8 + ABC\x{0a} + ABC\x{0b} + ABC\x{0c} + ABC\x{0d} + ABC\x{85} + ABC\x{2028} + +/\h*A/SI8 + CDBABC + \x{2000}ABC + +/\R*A/SI8 + CDBABC + \x{2028}A + +/\v+A/SI8 + +/\s?xxx\s/8SI + +/\sxxx\s/I8ST1 + AB\x{85}xxx\x{a0}XYZ + AB\x{a0}xxx\x{85}XYZ + +/\S \S/I8ST1 + \x{a2} \x{84} + A Z + +/a+/8 + a\x{123}aa\>1 + a\x{123}aa\>2 + a\x{123}aa\>3 + a\x{123}aa\>4 + a\x{123}aa\>5 + a\x{123}aa\>6 + +/\x{1234}+/iS8I + +/\x{1234}+?/iS8I + +/\x{1234}++/iS8I + +/\x{1234}{2}/iS8I + +/[^\x{c4}]/8DZ + +/X+\x{200}/8DZ + +/\R/SI8 + +/-- Check bad offset --/ + +/a/8 + \x{10000}\>1 + \x{10000}ab\>1 + \x{10000}ab\>2 + \x{10000}ab\>3 + \x{10000}ab\>4 + \x{10000}ab\>5 + +/í¼€/8 + +/\w+\x{C4}/8BZ + a\x{C4}\x{C4} + +/\w+\x{C4}/8BZT1 + a\x{C4}\x{C4} + +/\W+\x{C4}/8BZ + !\x{C4} + +/\W+\x{C4}/8BZT1 + !\x{C4} + +/\W+\x{A1}/8BZ + !\x{A1} + +/\W+\x{A1}/8BZT1 + !\x{A1} + +/X\s+\x{A0}/8BZ + X\x20\x{A0}\x{A0} + +/X\s+\x{A0}/8BZT1 + X\x20\x{A0}\x{A0} + +/\S+\x{A0}/8BZ + X\x{A0}\x{A0} + +/\S+\x{A0}/8BZT1 + X\x{A0}\x{A0} + +/\x{a0}+\s!/8BZ + \x{a0}\x20! + +/\x{a0}+\s!/8BZT1 + \x{a0}\x20! + +/-- End of testinput18 --/ diff --git a/tools/pcre/testdata/testinput19 b/tools/pcre/testdata/testinput19 new file mode 100644 index 00000000..00d80203 --- /dev/null +++ b/tools/pcre/testdata/testinput19 @@ -0,0 +1,22 @@ +/-- This set of tests is for Unicode property support, relevant only to the + 16- and 32-bit library. --/ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ + +/AB\x{1fb0}/8DZ + +/AB\x{1fb0}/8DZi + +/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI + \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + +/[â±¥]/8iBZ + +/[^â±¥]/8iBZ + +/[[:blank:]]/WBZ + +/-- End of testinput19 --/ diff --git a/tools/pcre/testdata/testinput2 b/tools/pcre/testdata/testinput2 new file mode 100644 index 00000000..9670104e --- /dev/null +++ b/tools/pcre/testdata/testinput2 @@ -0,0 +1,3813 @@ +/-- This set of tests is not Perl-compatible. It checks on special features + of PCRE's API, error diagnostics, and the compiled code of some patterns. + 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. + + 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. --/ + +/(a)b|/I + +/abc/I + abc + defabc + \Aabc + *** Failers + \Adefabc + ABC + +/^abc/I + abc + \Aabc + *** Failers + defabc + \Adefabc + +/a+bc/I + +/a*bc/I + +/a{3}bc/I + +/(abc|a+z)/I + +/^abc$/I + abc + *** Failers + def\nabc + +/ab\idef/X + +/(?X)ab\idef/X + +/x{5,4}/ + +/z{65536}/ + +/[abcd/ + +/(?X)[\B]/ + +/(?X)[\R]/ + +/(?X)[\X]/ + +/[\B]/BZ + +/[\R]/BZ + +/[\X]/BZ + +/[z-a]/ + +/^*/ + +/(abc/ + +/(?# abc/ + +/(?z)abc/ + +/.*b/I + +/.*?b/I + +/cat|dog|elephant/I + this sentence eventually mentions a cat + this sentences rambles on and on for a while and then reaches elephant + +/cat|dog|elephant/IS + this sentence eventually mentions a cat + this sentences rambles on and on for a while and then reaches elephant + +/cat|dog|elephant/IiS + this sentence eventually mentions a CAT cat + this sentences rambles on and on for a while to elephant ElePhant + +/a|[bcd]/IS + +/(a|[^\dZ])/IS + +/(a|b)*[\s]/IS + +/(ab\2)/ + +/{4,5}abc/ + +/(a)(b)(c)\2/I + abcb + \O0abcb + \O3abcb + \O6abcb + \O9abcb + \O12abcb + +/(a)bc|(a)(b)\2/I + abc + \O0abc + \O3abc + \O6abc + aba + \O0aba + \O3aba + \O6aba + \O9aba + \O12aba + +/abc$/IE + abc + *** Failers + abc\n + abc\ndef + +/(a)(b)(c)(d)(e)\6/ + +/the quick brown fox/I + the quick brown fox + this is a line with the quick brown fox + +/the quick brown fox/IA + the quick brown fox + *** Failers + this is a line with the quick brown fox + +/ab(?z)cd/ + +/^abc|def/I + abcdef + abcdef\B + +/.*((abc)$|(def))/I + defabc + \Zdefabc + +/)/ + +/a[]b/ + +/[^aeiou ]{3,}/I + co-processors, and for + +/<.*>/I + abcghinop + +/<.*?>/I + abcghinop + +/<.*>/IU + abcghinop + +/(?U)<.*>/I + abcghinop + +/<.*?>/IU + abcghinop + +/={3,}/IU + abc========def + +/(?U)={3,}?/I + abc========def + +/(?^abc)/Im + abc + def\nabc + *** Failers + defabc + +/(?<=ab(c+)d)ef/ + +/(?<=ab(?<=c+)d)ef/ + +/(?<=ab(c|de)f)g/ + +/The next three are in testinput2 because they have variable length branches/ + +/(?<=bullock|donkey)-cart/I + the bullock-cart + a donkey-cart race + *** Failers + cart + horse-and-cart + +/(?<=ab(?i)x|y|z)/I + +/(?>.*)(?<=(abcd)|(xyz))/I + alphabetabcd + endingxyz + +/(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/I + abxyZZ + abXyZZ + ZZZ + zZZ + bZZ + BZZ + *** Failers + ZZ + abXYZZ + zzz + bzz + +/(?[^()]+) # Either a sequence of non-brackets (no backtracking) + | # Or + (?R) # Recurse - i.e. nested bracketed string + )* # Zero or more contents + \) # Closing ) + /Ix + (abcd) + (abcd)xyz + xyz(abcd) + (ab(xy)cd)pqr + (ab(xycd)pqr + () abc () + 12(abcde(fsh)xyz(foo(bar))lmno)89 + *** Failers + abcd + abcd) + (abcd + +/\( ( (?>[^()]+) | (?R) )* \) /Ixg + (ab(xy)cd)pqr + 1(abcd)(x(y)z)pqr + +/\( (?: (?>[^()]+) | (?R) ) \) /Ix + (abcd) + (ab(xy)cd) + (a(b(c)d)e) + ((ab)) + *** Failers + () + +/\( (?: (?>[^()]+) | (?R) )? \) /Ix + () + 12(abcde(fsh)xyz(foo(bar))lmno)89 + +/\( ( (?>[^()]+) | (?R) )* \) /Ix + (ab(xy)cd) + +/\( ( ( (?>[^()]+) | (?R) )* ) \) /Ix + (ab(xy)cd) + +/\( (123)? ( ( (?>[^()]+) | (?R) )* ) \) /Ix + (ab(xy)cd) + (123ab(xy)cd) + +/\( ( (123)? ( (?>[^()]+) | (?R) )* ) \) /Ix + (ab(xy)cd) + (123ab(xy)cd) + +/\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \) /Ix + (ab(xy)cd) + +/\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \) /Ix + (abcd(xyz

qrs)123) + +/\( ( ( (?>[^()]+) | ((?R)) )* ) \) /Ix + (ab(cd)ef) + (ab(cd(ef)gh)ij) + +/^[[:alnum:]]/DZ + +/^[[:^alnum:]]/DZ + +/^[[:alpha:]]/DZ + +/^[[:^alpha:]]/DZ + +/[_[:alpha:]]/IS + +/^[[:ascii:]]/DZ + +/^[[:^ascii:]]/DZ + +/^[[:blank:]]/DZ + +/^[[:^blank:]]/DZ + +/[\n\x0b\x0c\x0d[:blank:]]/IS + +/^[[:cntrl:]]/DZ + +/^[[:digit:]]/DZ + +/^[[:graph:]]/DZ + +/^[[:lower:]]/DZ + +/^[[:print:]]/DZ + +/^[[:punct:]]/DZ + +/^[[:space:]]/DZ + +/^[[:upper:]]/DZ + +/^[[:xdigit:]]/DZ + +/^[[:word:]]/DZ + +/^[[:^cntrl:]]/DZ + +/^[12[:^digit:]]/DZ + +/^[[:^blank:]]/DZ + +/[01[:alpha:]%]/DZ + +/[[.ch.]]/I + +/[[=ch=]]/I + +/[[:rhubarb:]]/I + +/[[:upper:]]/Ii + A + a + +/[[:lower:]]/Ii + A + a + +/((?-i)[[:lower:]])[[:lower:]]/Ii + ab + aB + *** Failers + Ab + AB + +/[\200-\110]/I + +/^(?(0)f|b)oo/I + +/This one's here because of the large output vector needed/I + +/(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\w+)\s+(\270)/I + \O900 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC + +/This one's here because Perl does this differently and PCRE can't at present/I + +/(main(O)?)+/I + mainmain + mainOmain + +/These are all cases where Perl does it differently (nested captures)/I + +/^(a(b)?)+$/I + aba + +/^(aa(bb)?)+$/I + aabbaa + +/^(aa|aa(bb))+$/I + aabbaa + +/^(aa(bb)??)+$/I + aabbaa + +/^(?:aa(bb)?)+$/I + aabbaa + +/^(aa(b(b))?)+$/I + aabbaa + +/^(?:aa(b(b))?)+$/I + aabbaa + +/^(?:aa(b(?:b))?)+$/I + aabbaa + +/^(?:aa(bb(?:b))?)+$/I + aabbbaa + +/^(?:aa(b(?:bb))?)+$/I + aabbbaa + +/^(?:aa(?:b(b))?)+$/I + aabbaa + +/^(?:aa(?:b(bb))?)+$/I + aabbbaa + +/^(aa(b(bb))?)+$/I + aabbbaa + +/^(aa(bb(bb))?)+$/I + aabbbbaa + +/--------------------------------------------------------------------/I + +/#/IxDZ + +/a#/IxDZ + +/[\s]/DZ + +/[\S]/DZ + +/a(?i)b/DZ + ab + aB + *** Failers + AB + +/(a(?i)b)/DZ + ab + aB + *** Failers + AB + +/ (?i)abc/IxDZ + +/#this is a comment + (?i)abc/IxDZ + +/123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/DZ + +/\Q123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/DZ + +/\Q\E/DZ + \ + +/\Q\Ex/DZ + +/ \Q\E/DZ + +/a\Q\E/DZ + abc + bca + bac + +/a\Q\Eb/DZ + abc + +/\Q\Eabc/DZ + +/x*+\w/DZ + *** Failers + xxxxx + +/x?+/DZ + +/x++/DZ + +/x{1,3}+/DZ + +/(x)*+/DZ + +/^(\w++|\s++)*$/I + 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)/I + 12345a + *** Failers + 12345+ + +/a++b/I + aaab + +/(a++b)/I + aaab + +/(a++)b/I + aaab + +/([^()]++|\([^()]*\))+/I + ((abc(ade)ufh()()x + +/\(([^()]++|\([^()]+\))+\)/I + (abc) + (abc(def)xyz) + *** Failers + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/(abc){1,3}+/DZ + +/a+?+/I + +/a{2,3}?+b/I + +/(?U)a+?+/I + +/a{2,3}?+b/IU + +/x(?U)a++b/DZ + xaaaab + +/(?U)xa++b/DZ + xaaaab + +/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/DZ + +/^x(?U)a+b/DZ + +/^x(?U)(a+)b/DZ + +/[.x.]/I + +/[=x=]/I + +/[:x:]/I + +/\l/I + +/\L/I + +/\N{name}/I + +/\u/I + +/\U/I + +/[/I + +/[a-/I + +/[[:space:]/I + +/[\s]/IDZ + +/[[:space:]]/IDZ + +/[[:space:]abcde]/IDZ + +/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/Ix + <> + + hij> + hij> + def> + + *** Failers + 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 + +|\$\<\.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 + +/(.*)\d+\1/I + +/(.*)\d+/I + +/(.*)\d+\1/Is + +/(.*)\d+/Is + +/(.*(xyz))\d+\2/I + +/((.*))\d+\1/I + abc123bc + +/a[b]/I + +/(?=a).*/I + +/(?=abc).xyz/IiI + +/(?=abc)(?i).xyz/I + +/(?=a)(?=b)/I + +/(?=.)a/I + +/((?=abcda)a)/I + +/((?=abcda)ab)/I + +/()a/I + +/(?(1)ab|ac)(.)/I + +/(?(1)abz|acz)(.)/I + +/(?(1)abz)(.)/I + +/(?(1)abz)(1)23/I + +/(a)+/I + +/(a){2,3}/I + +/(a)*/I + +/[a]/I + +/[ab]/I + +/[ab]/IS + +/[^a]/I + +/\d456/I + +/\d456/IS + +/a^b/I + +/^a/Im + abcde + xy\nabc + *** Failers + xyabc + +/c|abc/I + +/(?i)[ab]/IS + +/[ab](?i)cd/IS + +/abc(?C)def/I + abcdef + 1234abcdef + *** Failers + abcxyz + abcxyzf + +/abc(?C)de(?C1)f/I + 123abcdef + +/(?C1)\dabc(?C2)def/IS + 1234abcdef + *** Failers + abcdef + +/(?C1)\dabc(?C2)def/ISS + 1234abcdef + *** Failers + abcdef + +/(?C255)ab/I + +/(?C256)ab/I + +/(?Cab)xx/I + +/(?C12vr)x/I + +/abc(?C)def/I + *** Failers + \x83\x0\x61bcdef + +/(abc)(?C)de(?C1)f/I + 123abcdef + 123abcdef\C+ + 123abcdef\C- + *** Failers + 123abcdef\C!1 + +/(?C0)(abc(?C1))*/I + abcabcabc + abcabc\C!1!3 + *** Failers + abcabcabc\C!1!3 + +/(\d{3}(?C))*/I + 123\C+ + 123456\C+ + 123456789\C+ + +/((xyz)(?C)p|(?C1)xyzabc)/I + xyzabc\C+ + +/(X)((xyz)(?C)p|(?C1)xyzabc)/I + Xxyzabc\C+ + +/(?=(abc))(?C)abcdef/I + abcdef\C+ + +/(?!(abc)(?C1)d)(?C2)abcxyz/I + abcxyz\C+ + +/(?<=(abc)(?C))xyz/I + abcxyz\C+ + +/a(b+)(c*)(?C1)/I + abbbbbccc\C*1 + +/a(b+?)(c*?)(?C1)/I + abbbbbccc\C*1 + +/(?C)abc/I + +/(?C)^abc/I + +/(?C)a|b/IS + +/(?R)/I + +/(a|(?R))/I + +/(ab|(bc|(de|(?R))))/I + +/x(ab|(bc|(de|(?R))))/I + xab + xbc + xde + xxab + xxxab + *** Failers + xyab + +/(ab|(bc|(de|(?1))))/I + +/x(ab|(bc|(de|(?1)x)x)x)/I + +/^([^()]|\((?1)*\))*$/I + abc + a(b)c + a(b(c))d + *** Failers) + a(b(c)d + +/^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)]*+) | (?2)) * >))/Ix + <> + + hij> + hij> + def> + + *** Failers + b|c)d(?Pe)/DZ + abde + acde + +/(?:a(?Pc(?Pd)))(?Pa)/DZ + +/(?Pa)...(?P=a)bbb(?P>a)d/DZ + +/^\W*(?:(?P(?P.)\W*(?P>one)\W*(?P=two)|)|(?P(?P.)\W*(?P>three)\W*(?P=four)|\W*.\W*))\W*$/Ii + 1221 + Satan, oscillate my metallic sonatas! + A man, a plan, a canal: Panama! + Able was I ere I saw Elba. + *** Failers + The quick brown fox + +/((?(R)a|b))\1(?1)?/I + bb + bbaa + +/(.*)a/Is + +/(.*)a\1/Is + +/(.*)a(b)\2/Is + +/((.*)a|(.*)b)z/Is + +/((.*)a|(.*)b)z\1/Is + +/((.*)a|(.*)b)z\2/Is + +/((.*)a|(.*)b)z\3/Is + +/((.*)a|^(.*)b)z\3/Is + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/Is + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/Is + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/Is + +/(a)(bc)/INDZ + abc + +/(?Pa)(bc)/INDZ + abc + +/(a)(?Pbc)/INDZ + +/(a+)*zz/I + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\M + aaaaaaaaaaaaaz\M + +/(aaa(?C1)bbb|ab)/I + aaabbb + aaabbb\C*0 + aaabbb\C*1 + aaabbb\C*-1 + +/ab(?Pcd)ef(?Pgh)/I + abcdefgh + abcdefgh\C1\Gtwo + abcdefgh\Cone\Ctwo + abcdefgh\Cthree + +/(?P)(?P)/DZ + +/(?P)(?P)/DZ + +/(?Pzz)(?Paa)/I + zzaa\CZ + zzaa\CA + +/(?Peks)(?Peccs)/I + +/(?Pabc(?Pdef)(?Pxyz))/I + +"\[((?P\d+)(,(?P>elem))*)\]"I + [10,20,30,5,5,4,4,2,43,23,4234] + *** Failers + [] + +"\[((?P\d+)(,(?P>elem))*)?\]"I + [10,20,30,5,5,4,4,2,43,23,4234] + [] + +/(a(b(?2)c))?/DZ + +/(a(b(?2)c))*/DZ + +/(a(b(?2)c)){0,2}/DZ + +/[ab]{1}+/DZ + +/((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/Ii + Baby Bjorn Active Carrier - With free SHIPPING!! + +/((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/IiS + Baby Bjorn Active Carrier - With free SHIPPING!! + +/a*.*b/ISDZ + +/(a|b)*.?c/ISDZ + +/abc(?C255)de(?C)f/DZ + +/abcde/ICDZ + abcde + abcdfe + +/a*b/ICDZS + ab + aaaab + aaaacb + +/a*b/ICDZSS + ab + aaaab + aaaacb + +/a+b/ICDZ + ab + aaaab + aaaacb + +/(abc|def)x/ICDZS + abcx + defx + ** Failers + abcdefzx + +/(abc|def)x/ICDZSS + abcx + defx + ** Failers + abcdefzx + +/(ab|cd){3,4}/IC + ababab + abcdabcd + abcdcdcdcdcd + +/([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 + aacaacaacaacaac123 + +/\b.*/I + ab cd\>1 + +/\b.*/Is + ab cd\>1 + +/(?!.bcd).*/I + Xbcd12345 + +/abcde/I + ab\P + abc\P + abcd\P + abcde\P + the quick brown abc\P + ** Failers\P + the quick brown abxyz fox\P + +"^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/(20)?\d\d$"I + 13/05/04\P + 13/5/2004\P + 02/05/09\P + 1\P + 1/2\P + 1/2/0\P + 1/2/04\P + 0\P + 02/\P + 02/0\P + 02/1\P + ** Failers\P + \P + 123\P + 33/4/04\P + 3/13/04\P + 0/1/2003\P + 0/\P + 02/0/\P + 02/13\P + +/0{0,2}ABC/I + +/\d{3,}ABC/I + +/\d*ABC/I + +/[abc]+DE/I + +/[abc]?123/I + 123\P + a\P + b\P + c\P + c12\P + c123\P + +/^(?:\d){3,5}X/I + 1\P + 123\P + 123X + 1234\P + 1234X + 12345\P + 12345X + *** Failers + 1X + 123456\P + +/abc/IS>testsavedregex +testsavedregex +testsavedregex +testsavedregex +testsavedregex +testsavedregex +testsavedregex +testsavedregex +(.)*~smgI + \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 + +/line\nbreak/I + this is a line\nbreak + line one\nthis is a line\nbreak in the second line + +/line\nbreak/If + this is a line\nbreak + ** Failers + line one\nthis is a line\nbreak in the second line + +/line\nbreak/Imf + this is a line\nbreak + ** Failers + line one\nthis is a line\nbreak in the second line + +/(?i)(?-i)AbCd/I + AbCd + ** Failers + abcd + +/a{11111111111111111111}/I + +/(){64294967295}/I + +/(){2,4294967295}/I + +"(?i:a)(?i:b)(?i:c)(?i:d)(?i:e)(?i:f)(?i:g)(?i:h)(?i:i)(?i:j)(k)(?i:l)A\1B"I + abcdefghijklAkB + +"(?Pa)(?Pb)(?Pc)(?Pd)(?Pe)(?Pf)(?Pg)(?Ph)(?Pi)(?Pj)(?Pk)(?Pl)A\11B"I + abcdefghijklAkB + +"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)A\11B"I + abcdefghijklAkB + +"(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)"I + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +"(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)"I + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/[^()]*(?:\((?R)\)[^()]*)*/I + (this(and)that + (this(and)that) + (this(and)that)stuff + +/[^()]*(?:\((?>(?R))\)[^()]*)*/I + (this(and)that + (this(and)that) + +/[^()]*(?:\((?R)\))*[^()]*/I + (this(and)that + (this(and)that) + +/(?:\((?R)\))*[^()]*/I + (this(and)that + (this(and)that) + ((this)) + +/(?:\((?R)\))|[^()]*/I + (this(and)that + (this(and)that) + (this) + ((this)) + +/\x{0000ff}/I + +/^((?Pa1)|(?Pa2)b)/I + +/^((?Pa1)|(?Pa2)b)/IJ + a1b\CA + a2b\CA + ** Failers + a1b\CZ\CA + +/^(?Pa)(?Pb)/IJ + ab\CA + +/^(?Pa)(?Pb)|cd/IJ + ab\CA + cd\CA + +/^(?Pa)(?Pb)|cd(?Pef)(?Pgh)/IJ + cdefgh\CA + +/^((?Pa1)|(?Pa2)b)/IJ + a1b\GA + a2b\GA + ** Failers + a1b\GZ\GA + +/^(?Pa)(?Pb)/IJ + ab\GA + +/^(?Pa)(?Pb)|cd/IJ + ab\GA + cd\GA + +/^(?Pa)(?Pb)|cd(?Pef)(?Pgh)/IJ + cdefgh\GA + +/(?J)^((?Pa1)|(?Pa2)b)/I + a1b\CA + a2b\CA + +/^(?Pa) (?J:(?Pb)(?Pc)) (?Pd)/I + +/ In this next test, J is not set at the outer level; consequently it isn't +set in the pattern's options; consequently pcre_get_named_substring() produces +a random value. /Ix + +/^(?Pa) (?J:(?Pb)(?Pc)) (?Pd)/I + a bc d\CA\CB\CC + +/^(?Pa)?(?(A)a|b)/I + aabc + bc + ** Failers + abc + +/(?:(?(ZZ)a|b)(?PX))+/I + bXaX + +/(?:(?(2y)a|b)(X))+/I + +/(?:(?(ZA)a|b)(?PX))+/I + +/(?:(?(ZZ)a|b)(?(ZZ)a|b)(?PX))+/I + bbXaaX + +/(?:(?(ZZ)a|\(b\))\\(?PX))+/I + (b)\\Xa\\X + +/(?PX|Y))+/I + bXXaYYaY + bXYaXXaX + +/()()()()()()()()()(?:(?(A)(?P=A)a|b)(?PX|Y))+/I + bXXaYYaY + +/\s*,\s*/IS + \x0b,\x0b + \x0c,\x0d + +/^abc/Im + xyz\nabc + xyz\nabc\ + xyz\r\nabc\ + xyz\rabc\ + xyz\r\nabc\ + ** Failers + xyz\nabc\ + xyz\r\nabc\ + xyz\nabc\ + xyz\rabc\ + xyz\rabc\ + +/abc$/Im + 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/Im + xyz\rabcdef + xyz\nabcdef\ + ** Failers + xyz\nabcdef + +/^abc/Im + xyz\nabcdef + xyz\rabcdef\ + ** Failers + xyz\rabcdef + +/^abc/Im + xyz\r\nabcdef + xyz\rabcdef\ + ** Failers + xyz\rabcdef + +/^abc/Im + +/abc/I + xyz\rabc\ + abc + +/.*/I + abc\ndef + abc\rdef + abc\r\ndef + \abc\ndef + \abc\rdef + \abc\r\ndef + \abc\ndef + \abc\rdef + \abc\r\ndef + +/\w+(.)(.)?def/Is + abc\ndef + abc\rdef + abc\r\ndef + ++((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)+I + /* this is a C style comment */\M + +/(?P25[0-5]|2[0-4]\d|[01]?\d?\d)(?:\.(?P>B)){3}/I + +/()()()()()()()()()()()()()()()()()()()() + ()()()()()()()()()()()()()()()()()()()() + ()()()()()()()()()()()()()()()()()()()() + ()()()()()()()()()()()()()()()()()()()() + ()()()()()()()()()()()()()()()()()()()() + (.(.))/Ix + XY\O400 + +/(a*b|(?i:c*(?-i)d))/IS + +/()[ab]xyz/IS + +/(|)[ab]xyz/IS + +/(|c)[ab]xyz/IS + +/(|c?)[ab]xyz/IS + +/(d?|c?)[ab]xyz/IS + +/(d?|c)[ab]xyz/IS + +/^a*b\d/DZ + +/^a*+b\d/DZ + +/^a*?b\d/DZ + +/^a+A\d/DZ + aaaA5 + ** Failers + aaaa5 + +/^a*A\d/IiDZ + aaaA5 + aaaa5 + +/(a*|b*)[cd]/IS + +/(a+|b*)[cd]/IS + +/(a*|b+)[cd]/IS + +/(a+|b+)[cd]/IS + +/(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + ((( + a + )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + ))) +/Ix + large nest + +/a*\d/BZ + +/a*\D/BZ + +/0*\d/BZ + +/0*\D/BZ + +/a*\s/BZ + +/a*\S/BZ + +/ *\s/BZ + +/ *\S/BZ + +/a*\w/BZ + +/a*\W/BZ + +/=*\w/BZ + +/=*\W/BZ + +/\d*a/BZ + +/\d*2/BZ + +/\d*\d/BZ + +/\d*\D/BZ + +/\d*\s/BZ + +/\d*\S/BZ + +/\d*\w/BZ + +/\d*\W/BZ + +/\D*a/BZ + +/\D*2/BZ + +/\D*\d/BZ + +/\D*\D/BZ + +/\D*\s/BZ + +/\D*\S/BZ + +/\D*\w/BZ + +/\D*\W/BZ + +/\s*a/BZ + +/\s*2/BZ + +/\s*\d/BZ + +/\s*\D/BZ + +/\s*\s/BZ + +/\s*\S/BZ + +/\s*\w/BZ + +/\s*\W/BZ + +/\S*a/BZ + +/\S*2/BZ + +/\S*\d/BZ + +/\S*\D/BZ + +/\S*\s/BZ + +/\S*\S/BZ + +/\S*\w/BZ + +/\S*\W/BZ + +/\w*a/BZ + +/\w*2/BZ + +/\w*\d/BZ + +/\w*\D/BZ + +/\w*\s/BZ + +/\w*\S/BZ + +/\w*\w/BZ + +/\w*\W/BZ + +/\W*a/BZ + +/\W*2/BZ + +/\W*\d/BZ + +/\W*\D/BZ + +/\W*\s/BZ + +/\W*\S/BZ + +/\W*\w/BZ + +/\W*\W/BZ + +/[^a]+a/BZ + +/[^a]+a/BZi + +/[^a]+A/BZi + +/[^a]+b/BZ + +/[^a]+\d/BZ + +/a*[^a]/BZ + +/(?Px)(?Py)/I + xy\Cabc\Cxyz + +/(?x)(?'xyz'y)/I + xy\Cabc\Cxyz + +/(?x)(?'xyz>y)/I + +/(?P'abc'x)(?Py)/I + +/^(?:(?(ZZ)a|b)(?X))+/ + bXaX + bXbX + ** Failers + aXaX + aXbX + +/^(?P>abc)(?xxx)/ + +/^(?P>abc)(?x|y)/ + xx + xy + yy + yx + +/^(?P>abc)(?Px|y)/ + xx + xy + yy + yx + +/^((?(abc)a|b)(?x|y))+/ + bxay + bxby + ** Failers + axby + +/^(((?P=abc)|X)(?x|y))+/ + XxXxxx + XxXyyx + XxXyxx + ** Failers + x + +/^(?1)(abc)/ + abcabc + +/^(?:(?:\1|X)(a|b))+/ + Xaaa + Xaba + +/^[\E\Qa\E-\Qz\E]+/BZ + +/^[a\Q]bc\E]/BZ + +/^[a-\Q\E]/BZ + +/^(?P>abc)[()](?)/BZ + +/^((?(abc)y)[()](?Px))+/BZ + (xy)x + +/^(?P>abc)\Q()\E(?)/BZ + +/^(?P>abc)[a\Q(]\E(](?)/BZ + +/^(?P>abc) # this is (a comment) + (?)/BZx + +/^\W*(?:(?(?.)\W*(?&one)\W*\k|)|(?(?.)\W*(?&three)\W*\k'four'|\W*.\W*))\W*$/Ii + 1221 + Satan, oscillate my metallic sonatas! + A man, a plan, a canal: Panama! + Able was I ere I saw Elba. + *** Failers + The quick brown fox + +/(?=(\w+))\1:/I + abcd: + +/(?=(?'abc'\w+))\k:/I + abcd: + +/(?'abc'a|b)(?d|e)\k{2}/J + adaa + ** Failers + addd + adbb + +/(?'abc'a|b)(?d|e)(?&abc){2}/J + bdaa + bdab + ** Failers + bddd + +/(?( (?'B' abc (?(R) (?(R&A)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x + abcabc1Xabc2XabcXabcabc + +/(? (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x + +/(?<1> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x + abcabc1Xabc2XabcXabcabc + +/^(?(DEFINE) abc | xyz ) /x + +/(?(DEFINE) abc) xyz/xI + +/(a|)*\d/ + \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/^a.b/ + a\rb + a\nb\ + a\x85b\ + ** Failers + a\nb + a\nb\ + a\rb\ + a\rb\ + a\x85b\ + 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 abc7 abc9 + +/a/ + +/a/ + +/^a\Rb/ + a\nb + a\rb + a\r\nb + a\x0bb + a\x0cb + a\x85b + ** Failers + a\n\rb + +/^a\R*b/ + ab + a\nb + a\rb + a\r\nb + a\x0bb + a\x0cb + a\x85b + a\n\rb + a\n\r\x85\x0cb + +/^a\R+b/ + a\nb + a\rb + a\r\nb + a\x0bb + a\x0cb + a\x85b + a\n\rb + a\n\r\x85\x0cb + ** Failers + ab + +/^a\R{1,3}b/ + a\nb + a\n\rb + a\n\r\x85b + a\r\n\r\nb + a\r\n\r\n\r\nb + a\n\r\n\rb + a\n\n\r\nb + ** Failers + a\n\n\n\rb + a\r + +/^a[\R]b/ + aRb + ** Failers + a\nb + +/(?&abc)X(?P)/I + abcPXP123 + +/(?1)X(?P)/I + abcPXP123 + +/(?:a(?&abc)b)*(?x)/ + 123axbaxbaxbx456 + 123axbaxbaxb456 + +/(?:a(?&abc)b){1,5}(?x)/ + 123axbaxbaxbx456 + +/(?:a(?&abc)b){2,5}(?x)/ + 123axbaxbaxbx456 + +/(?:a(?&abc)b){2,}(?x)/ + 123axbaxbaxbx456 + +/(abc)(?i:(?1))/ + defabcabcxyz + DEFabcABCXYZ + +/(abc)(?:(?i)(?1))/ + defabcabcxyz + DEFabcABCXYZ + +/^(a)\g-2/ + +/^(a)\g/ + +/^(a)\g{0}/ + +/^(a)\g{3/ + +/^(a)\g{4a}/ + +/^a.b/ + a\rb + *** 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 + +/(?m)^$/g+ + abc\r\n\r\n + +/(?m)^$|^\r\n/g+ + abc\r\n\r\n + +/(?m)$/g+ + abc\r\n\r\n + +/abc.$/mgx + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 + +/^X/m + XABC + ** Failers + XABC\B + +/(ab|c)(?-1)/BZ + abc + +/xy(?+1)(abc)/BZ + xyabcabc + ** Failers + xyabc + +/x(?-0)y/ + +/x(?-1)y/ + +/x(?+0)y/ + +/x(?+1)y/ + +/^(abc)?(?(-1)X|Y)/BZ + abcX + Y + ** Failers + abcY + +/^((?(+1)X|Y)(abc))+/BZ + YabcXabc + YabcXabcXabc + ** Failers + XabcXabc + +/(?(-1)a)/BZ + +/((?(-1)a))/BZ + +/((?(-2)a))/BZ + +/^(?(+1)X|Y)(.)/BZ + Y! + +/(?tom|bon)-\k{A}/ + tom-tom + bon-bon + ** Failers + tom-bon + +/\g{A/ + +/(?|(abc)|(xyz))/BZ + >abc< + >xyz< + +/(x)(?|(abc)|(xyz))(x)/BZ + xabcx + xxyzx + +/(x)(?|(abc)(pqr)|(xyz))(x)/BZ + xabcpqrx + xxyzx + +/\H++X/BZ + ** Failers + XXXX + +/\H+\hY/BZ + XXXX Y + +/\H+ Y/BZ + +/\h+A/BZ + +/\v*B/BZ + +/\V+\x0a/BZ + +/A+\h/BZ + +/ *\H/BZ + +/A*\v/BZ + +/\x0b*\V/BZ + +/\d+\h/BZ + +/\d*\v/BZ + +/S+\h\S+\v/BZ + +/\w{3,}\h\w+\v/BZ + +/\h+\d\h+\w\h+\S\h+\H/BZ + +/\v+\d\v+\w\v+\S\v+\V/BZ + +/\H+\h\H+\d/BZ + +/\V+\v\V+\w/BZ + +/\( (?: [^()]* | (?R) )* \)/x +\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/ + +/[\Q\E]AAA/ + +/[^\E]AAA/ + +/[^\Q\E]AAA/ + +/[\E^]AAA/ + +/[\Q\E^]AAA/ + +/A(*PRUNE)B(*SKIP)C(*THEN)D(*COMMIT)E(*F)F(*FAIL)G(?!)H(*ACCEPT)I/BZ + +/^a+(*FAIL)/C + aaaaaa + +/a+b?c+(*FAIL)/C + aaabccc + +/a+b?(*PRUNE)c+(*FAIL)/C + aaabccc + +/a+b?(*COMMIT)c+(*FAIL)/C + aaabccc + +/a+b?(*SKIP)c+(*FAIL)/C + aaabcccaaabccc + +/a+b?(*THEN)c+(*FAIL)/C + aaabccc + +/a(*MARK)b/ + +/(?i:A{1,}\6666666666)/ + +/\g6666666666/ + +/[\g6666666666]/BZ + +/(?1)\c[/ + +/.+A/ + \r\nA + +/\nA/ + \r\nA + +/[\r\n]A/ + \r\nA + +/(\r|\n)A/ + \r\nA + +/a(*CR)b/ + +/(*CR)a.b/ + a\nb + ** Failers + a\rb + +/(*CR)a.b/ + a\nb + ** Failers + a\rb + +/(*LF)a.b/ + a\rb + ** Failers + a\nb + +/(*CRLF)a.b/ + a\rb + a\nb + ** Failers + a\r\nb + +/(*ANYCRLF)a.b/ + ** Failers + a\rb + a\nb + a\r\nb + +/(*ANY)a.b/ + ** Failers + a\rb + a\nb + a\r\nb + a\x85b + +/(*ANY).*/g + abc\r\ndef + +/(*ANYCRLF).*/g + abc\r\ndef + +/(*CRLF).*/g + abc\r\ndef + +/a\Rb/I + a\rb + a\nb + a\r\nb + ** Failers + a\x85b + a\x0bb + +/a\Rb/I + a\rb + a\nb + a\r\nb + a\x85b + a\x0bb + ** Failers + a\x85b\ + a\x0bb\ + +/a\R?b/I + a\rb + a\nb + a\r\nb + ** Failers + a\x85b + a\x0bb + +/a\R?b/I + a\rb + a\nb + a\r\nb + a\x85b + a\x0bb + ** Failers + a\x85b\ + a\x0bb\ + +/a\R{2,4}b/I + a\r\n\nb + a\n\r\rb + a\r\n\r\n\r\n\r\nb + ** Failers + a\x85\85b + a\x0b\0bb + +/a\R{2,4}b/I + a\r\rb + a\n\n\nb + a\r\n\n\r\rb + a\x85\85b + a\x0b\0bb + ** Failers + a\r\r\r\r\rb + a\x85\85b\ + a\x0b\0bb\ + +/(*BSR_ANYCRLF)a\Rb/I + a\nb + a\rb + +/(*BSR_UNICODE)a\Rb/I + a\x85b + +/(*BSR_ANYCRLF)(*CRLF)a\Rb/I + a\nb + a\rb + +/(*CRLF)(*BSR_UNICODE)a\Rb/I + a\x85b + +/(*CRLF)(*BSR_ANYCRLF)(*CR)ab/I + +/(?)(?&)/ + +/(?)(?&a)/ + +/(?)(?&aaaaaaaaaaaaaaaaaaaaaaa)/ + +/(?+-a)/ + +/(?-+a)/ + +/(?(-1))/ + +/(?(+10))/ + +/(?(10))/ + +/(?(+2))()()/ + +/(?(2))()()/ + +/\k''/ + +/\k<>/ + +/\k{}/ + +/\k/ + +/\kabc/ + +/(?P=)/ + +/(?P>)/ + +/(?!\w)(?R)/ + +/(?=\w)(?R)/ + +/(?x|y){0}z/ + xzxx + yzyy + ** Failers + xxz + +/(\3)(\1)(a)/ + cat + +/(\3)(\1)(a)/ + cat + +/TA]/ + The ACTA] comes + +/TA]/ + The ACTA] comes + +/(?2)[]a()b](abc)/ + abcbabc + +/(?2)[^]a()b](abc)/ + abcbabc + +/(?1)[]a()b](abc)/ + abcbabc + ** Failers + abcXabc + +/(?1)[^]a()b](abc)/ + abcXabc + ** Failers + abcbabc + +/(?2)[]a()b](abc)(xyz)/ + xyzbabcxyz + +/(?&N)[]a(?)](?abc)/ + abc)](abc)/ + abc + ** 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 + +/a(?!)+b/ + +/a(*FAIL)+b/ + +/(abc|pqr|123){0}[xyz]/SI + +/(?(?=.*b)b|^)/CI + adc + abc + +/(?(?=b).*b|^d)/I + +/(?(?=.*b).*b|^d)/I + +/xyz/C + xyz + abcxyz + abcxyz\Y + ** Failers + abc + abc\Y + abcxypqr + abcxypqr\Y + +/(*NO_START_OPT)xyz/C + abcxyz + +/xyz/CY + abcxyz + +/^"((?(?=[a])[^"])|b)*"$/C + "ab" + +/^"((?(?=[a])[^"])|b)*"$/ + "ab" + +/^X(?5)(a)(?|(b)|(q))(c)(d)Y/ + XYabcdY + +/^X(?&N)(a)(?|(b)|(q))(c)(d)(?Y)/ + XYabcdY + +/Xa{2,4}b/ + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/Xa{2,4}?b/ + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/Xa{2,4}+b/ + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X\d{2,4}b/ + X\P + X3\P + X33\P + X333\P + X3333\P + +/X\d{2,4}?b/ + X\P + X3\P + X33\P + X333\P + X3333\P + +/X\d{2,4}+b/ + X\P + X3\P + X33\P + X333\P + X3333\P + +/X\D{2,4}b/ + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X\D{2,4}?b/ + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X\D{2,4}+b/ + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X[abc]{2,4}b/ + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X[abc]{2,4}?b/ + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X[abc]{2,4}+b/ + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X[^a]{2,4}b/ + X\P + Xz\P + Xzz\P + Xzzz\P + Xzzzz\P + +/X[^a]{2,4}?b/ + X\P + Xz\P + Xzz\P + Xzzz\P + Xzzzz\P + +/X[^a]{2,4}+b/ + X\P + Xz\P + Xzz\P + Xzzz\P + Xzzzz\P + +/(Y)X\1{2,4}b/ + YX\P + YXY\P + YXYY\P + YXYYY\P + YXYYYY\P + +/(Y)X\1{2,4}?b/ + YX\P + YXY\P + YXYY\P + YXYYY\P + YXYYYY\P + +/(Y)X\1{2,4}+b/ + YX\P + YXY\P + YXYY\P + YXYYY\P + YXYYYY\P + +/\++\KZ|\d+X|9+Y/ + ++++123999\P + ++++123999Y\P + ++++Z1234\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 + +/\bthe cat\b/ + the cat\P + the cat\P\P + +/abc/ + abc\P + abc\P\P + +/abc\K123/ + xyzabc123pqr + xyzabc12\P + xyzabc12\P\P + +/(?<=abc)123/ + xyzabc123pqr + xyzabc12\P + xyzabc12\P\P + +/\babc\b/ + +++abc+++ + +++ab\P + +++ab\P\P + +/(?&word)(?&element)(?(DEFINE)(?<[^m][^>]>[^<])(?\w*+))/BZ + +/(?&word)(?&element)(?(DEFINE)(?<[^\d][^>]>[^<])(?\w*+))/BZ + +/(ab)(x(y)z(cd(*ACCEPT)))pq/BZ + +/abc\K/+ + abcdef + abcdef\N\N + xyzabcdef\N\N + ** Failers + abcdef\N + xyzabcdef\N + +/^(?:(?=abc)|abc\K)/+ + abcdef + abcdef\N\N + ** Failers + abcdef\N + +/a?b?/+ + xyz + xyzabc + xyzabc\N + xyzabc\N\N + xyz\N\N + ** Failers + xyz\N + +/^a?b?/+ + xyz + xyzabc + ** Failers + xyzabc\N + xyzabc\N\N + xyz\N\N + xyz\N + +/^(?a|b\gc)/ + aaaa + bacxxx + bbaccxxx + bbbacccxx + +/^(?a|b\g'name'c)/ + aaaa + bacxxx + bbaccxxx + bbbacccxx + +/^(a|b\g<1>c)/ + aaaa + bacxxx + bbaccxxx + bbbacccxx + +/^(a|b\g'1'c)/ + aaaa + bacxxx + bbaccxxx + bbbacccxx + +/^(a|b\g'-1'c)/ + aaaa + bacxxx + bbaccxxx + bbbacccxx + +/(^(a|b\g<-1>c))/ + aaaa + bacxxx + bbaccxxx + bbbacccxx + +/(?-i:\g)(?i:(?a))/ + XaaX + XAAX + +/(?i:\g)(?-i:(?a))/ + XaaX + ** Failers + XAAX + +/(?-i:\g<+1>)(?i:(a))/ + XaaX + XAAX + +/(?=(?(?#simplesyntax)\$(?[a-zA-Z_\x{7f}-\x{ff}][a-zA-Z0-9_\x{7f}-\x{ff}]*)(?:\[(?[a-zA-Z0-9_\x{7f}-\x{ff}]+|\$\g)\]|->\g(\(.*?\))?)?|(?#simple syntax withbraces)\$\{(?:\g(?\[(?:\g|'(?:\\.|[^'\\])*'|"(?:\g|\\.|[^"\\])*")\])?|\g|\$\{\g\})\}|(?#complexsyntax)\{(?\$(?\g(\g*|\(.*?\))?)(?:->\g)*|\$\g|\$\{\g\})\}))\{/ + +/(?a|b|c)\g*/ + abc + accccbbb + +/^X(?7)(a)(?|(b)|(q)(r)(s))(c)(d)(Y)/ + XYabcdY + +/(?<=b(?1)|zzz)(a)/ + xbaax + xzzzax + +/(a)(?<=b\1)/ + +/(a)(?<=b+(?1))/ + +/(a+)(?<=b(?1))/ + +/(a(?<=b(?1)))/ + +/(?<=b(?1))xyz/ + +/(?<=b(?1))xyz(b+)pqrstuvew/ + +/(a|bc)\1/SI + +/(a|bc)\1{2,3}/SI + +/(a|bc)(?1)/SI + +/(a|b\1)(a|b\1)/SI + +/(a|b\1){2}/SI + +/(a|bbbb\1)(a|bbbb\1)/SI + +/(a|bbbb\1){2}/SI + +/^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 + +/]{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 + +/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /xSI + +/(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/iSI + +/(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/SI + +/A)|(?
B))/I + AB\Ca + BA\Ca + +/(?|(?A)|(?B))/ + +/(?:a(? (?')|(?")) | + b(? (?')|(?")) ) + (?('quote')[a-z]+|[0-9]+)/JIx + a"aaaaa + b"aaaaa + ** Failers + b"11111 + a"11111 + +/^(?|(a)(b)(c)(?d)|(?e)) (?('D')X|Y)/JDZx + abcdX + eX + ** Failers + abcdY + ey + +/(?a) (b)(c) (?d (?(R&A)$ | (?4)) )/JDZx + abcdd + ** Failers + abcdde + +/abcd*/ + xxxxabcd\P + xxxxabcd\P\P + +/abcd*/i + xxxxabcd\P + xxxxabcd\P\P + XXXXABCD\P + XXXXABCD\P\P + +/abc\d*/ + xxxxabc1\P + xxxxabc1\P\P + +/(a)bc\1*/ + xxxxabca\P + xxxxabca\P\P + +/abc[de]*/ + xxxxabcde\P + xxxxabcde\P\P + +/-- This is not in the Perl >= 5.10 test because Perl seems currently to be + broken and not behaving as specified in that it *does* bumpalong after + hitting (*COMMIT). --/ + +/(?1)(A(*COMMIT)|B)D/ + ABD + XABD + BAD + ABXABD + ** Failers + ABX + BAXBAD + +/(\3)(\1)(a)/ + cat + +/(\3)(\1)(a)/SI + cat + +/(\3)(\1)(a)/SI + cat + +/i(?(DEFINE)(?a))/SI + i + +/()i(?(1)a)/SI + ia + +/(?i)a(?-i)b|c/BZ + XabX + XAbX + CcC + ** Failers + XABX + +/(?i)a(?s)b|c/BZ + +/(?i)a(?s-i)b|c/BZ + +/^(ab(c\1)d|x){2}$/BZ + xabcxd + +/^(?&t)*+(?(DEFINE)(?.))$/BZ + +/^(?&t)*(?(DEFINE)(?.))$/BZ + +/ -- The first four of these are not in the Perl >= 5.10 test because Perl + documents that the use of \K in assertions is "not well defined". The + last is here because Perl gives the match as "b" rather than "ab". I + believe this to be a Perl bug. --/ + +/(?=a\Kb)ab/ + ab + +/(?!a\Kb)ac/ + ac + +/^abc(?<=b\Kc)d/ + abcd + +/^abc(?a\Kb)z|(ab)/ + ab + +/----------------------/ + +/(?P(?P0|)|(?P>L2)(?P>L1))/ + +/abc(*MARK:)pqr/ + +/abc(*:)pqr/ + +/abc(*FAIL:123)xyz/ + +/--- This should, and does, fail. In Perl, it does not, which I think is a + bug because replacing the B in the pattern by (B|D) does make it fail. ---/ + +/A(*COMMIT)B/+K + ACABX + +/--- These should be different, but in Perl 5.11 are not, which I think + is a bug in Perl. ---/ + +/A(*THEN)B|A(*THEN)C/K + AC + +/A(*PRUNE)B|A(*PRUNE)C/K + AC + +/--- This should fail; the SKIP advances by one, but when we get to AC, the + PRUNE kills it. Perl behaves differently. ---/ + +/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK + AAAC + +/--- Mark names can be duplicated. Perl doesn't give a mark for this one, +though PCRE does. ---/ + +/^A(*:A)B|^X(*:A)Y/K + ** Failers + XAQQ + +/--- 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. ---/ + +/(*COMMIT)ABC/ + ABCDEFG + ** Failers + DEFGABC\Y + +/^(ab (c+(*THEN)cd) | xyz)/x + abcccd + +/^(ab (c+(*PRUNE)cd) | xyz)/x + abcccd + +/^(ab (c+(*FAIL)cd) | xyz)/x + abcccd + +/--- Perl 5.11 gets some of these wrong ---/ + +/(?>.(*ACCEPT))*?5/ + abcde + +/(.(*ACCEPT))*?5/ + abcde + +/(.(*ACCEPT))5/ + abcde + +/(.(*ACCEPT))*5/ + abcde + +/A\NB./BZ + ACBD + *** Failers + A\nB + ACB\n + +/A\NB./sBZ + ACBD + ACB\n + *** Failers + A\nB + +/A\NB/ + A\nB + A\rB + ** Failers + A\r\nB + +/\R+b/BZ + +/\R+\n/BZ + +/\R+\d/BZ + +/\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. --/ + +/^((abc|abcx)(*THEN)y|abcd)/ + abcd + *** Failers + abcxy + +/(?<=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 + +/^\cÄ£/ + +/(?P(?P=abn)xxx)/BZ + +/(a\1z)/BZ + +/(?P(?P=abn)(?(?P=axn)xxx)/BZ + +/(?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 + +/-- These are all run as real matches in test 1; here we are just checking the +settings of the anchored and startline bits. --/ + +/(?>.*?a)(?<=ba)/I + +/(?:.*?a)(?<=ba)/I + +/.*?a(*PRUNE)b/I + +/.*?a(*PRUNE)b/sI + +/^a(*PRUNE)b/sI + +/.*?a(*SKIP)b/I + +/(?>.*?a)b/sI + +/(?>.*?a)b/I + +/(?>^a)b/sI + +/(?>.*?)(?<=(abcd)|(wxyz))/I + +/(?>.*)(?<=(abcd)|(wxyz))/I + +"(?>.*)foo"I + +"(?>.*?)foo"I + +/(?>^abc)/mI + +/(?>.*abc)/mI + +/(?:.*abc)/mI + +/-- Check PCRE_STUDY_EXTRA_NEEDED --/ + +/.?/S-I + +/.?/S!I + +/-- End of testinput2 --/ diff --git a/tools/pcre/testdata/testinput20 b/tools/pcre/testdata/testinput20 new file mode 100644 index 00000000..2a6b8f23 --- /dev/null +++ b/tools/pcre/testdata/testinput20 @@ -0,0 +1,19 @@ +/-- These DFA tests are for the handling of characters greater than 255 in + 16- or 32-bit, non-UTF mode. --/ + +/^\x{ffff}+/i + \x{ffff} + +/^\x{ffff}?/i + \x{ffff} + +/^\x{ffff}*/i + \x{ffff} + +/^\x{ffff}{3}/i + \x{ffff}\x{ffff}\x{ffff} + +/^\x{ffff}{0,3}/i + \x{ffff} + +/-- End of testinput20 --/ diff --git a/tools/pcre/testdata/testinput21 b/tools/pcre/testdata/testinput21 new file mode 100644 index 00000000..0f201ada --- /dev/null +++ b/tools/pcre/testdata/testinput21 @@ -0,0 +1,16 @@ +/-- 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 + +>>\xaa<<< + >>>\xba<<< + +/[\W]+/Lfr_FR + >>>\xaa<<< + >>>\xba<<< + +/[^[:alpha:]]+/Lfr_FR + >>>\xaa<<< + >>>\xba<<< + +/\w+/Lfr_FR + >>>\xaa<<< + >>>\xba<<< + +/[\w]+/Lfr_FR + >>>\xaa<<< + >>>\xba<<< + +/[[:alpha:]]+/Lfr_FR + >>>\xaa<<< + >>>\xba<<< + +/[[:alpha:]][[:lower:]][[:upper:]]/DZLfr_FR + +/-- End of testinput3 --/ diff --git a/tools/pcre/testdata/testinput4 b/tools/pcre/testdata/testinput4 new file mode 100644 index 00000000..c7bb370c --- /dev/null +++ b/tools/pcre/testdata/testinput4 @@ -0,0 +1,624 @@ +/-- This set of tests is for UTF support, excluding Unicode properties. It is + compatible with all versions of Perl >= 5.10 and both the 8-bit and 16-bit + PCRE libraries. --/ + +/a.b/8 + acb + a\x7fb + a\x{100}b + *** Failers + a\nb + +/a(.{3})b/8 + a\x{4000}xyb + a\x{4000}\x7fyb + a\x{4000}\x{100}yb + *** Failers + a\x{4000}b + ac\ncb + +/a(.*?)(.)/ + a\xc0\x88b + +/a(.*?)(.)/8 + a\x{100}b + +/a(.*)(.)/ + a\xc0\x88b + +/a(.*)(.)/8 + a\x{100}b + +/a(.)(.)/ + a\xc0\x92bcd + +/a(.)(.)/8 + a\x{240}bcd + +/a(.?)(.)/ + a\xc0\x92bcd + +/a(.?)(.)/8 + a\x{240}bcd + +/a(.??)(.)/ + a\xc0\x92bcd + +/a(.??)(.)/8 + a\x{240}bcd + +/a(.{3})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + *** Failers + a\x{1234}b + ac\ncb + +/a(.{3,})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers + a\x{1234}b + +/a(.{3,}?)b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers + a\x{1234}b + +/a(.{3,5})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + axxxxxbcdefghijb + *** Failers + a\x{1234}b + axxxxxxbcdefghijb + +/a(.{3,5}?)b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + axxxxxbcdefghijb + *** Failers + a\x{1234}b + axxxxxxbcdefghijb + +/^[a\x{c0}]/8 + *** Failers + \x{100} + +/(?<=aXb)cd/8 + aXbcd + +/(?<=a\x{100}b)cd/8 + a\x{100}bcd + +/(?<=a\x{100000}b)cd/8 + a\x{100000}bcd + +/(?:\x{100}){3}b/8 + \x{100}\x{100}\x{100}b + *** Failers + \x{100}\x{100}b + +/\x{ab}/8 + \x{ab} + \xc2\xab + *** Failers + \x00{ab} + +/(?<=(.))X/8 + WXYZ + \x{256}XYZ + *** Failers + XYZ + +/[^a]+/8g + bcd + \x{100}aY\x{256}Z + +/^[^a]{2}/8 + \x{100}bc + +/^[^a]{2,}/8 + \x{100}bcAa + +/^[^a]{2,}?/8 + \x{100}bca + +/[^a]+/8ig + bcd + \x{100}aY\x{256}Z + +/^[^a]{2}/8i + \x{100}bc + +/^[^a]{2,}/8i + \x{100}bcAa + +/^[^a]{2,}?/8i + \x{100}bca + +/\x{100}{0,0}/8 + abcd + +/\x{100}?/8 + abcd + \x{100}\x{100} + +/\x{100}{0,3}/8 + \x{100}\x{100} + \x{100}\x{100}\x{100}\x{100} + +/\x{100}*/8 + abce + \x{100}\x{100}\x{100}\x{100} + +/\x{100}{1,1}/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}{1,3}/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}+/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}{3}/8 + abcd\x{100}\x{100}\x{100}XX + +/\x{100}{3,5}/8 + abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX + +/\x{100}{3,}/8 + abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX + +/(?<=a\x{100}{2}b)X/8+ + Xyyya\x{100}\x{100}bXzzz + +/\D*/8 + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/\D*/8 + \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + +/\D/8 + 1X2 + 1\x{100}2 + +/>\S/8 + > >X Y + > >\x{100} Y + +/\d/8 + \x{100}3 + +/\s/8 + \x{100} X + +/\D+/8 + 12abcd34 + *** Failers + 1234 + +/\D{2,3}/8 + 12abcd34 + 12ab34 + *** Failers + 1234 + 12a34 + +/\D{2,3}?/8 + 12abcd34 + 12ab34 + *** Failers + 1234 + 12a34 + +/\d+/8 + 12abcd34 + *** Failers + +/\d{2,3}/8 + 12abcd34 + 1234abcd + *** Failers + 1.4 + +/\d{2,3}?/8 + 12abcd34 + 1234abcd + *** Failers + 1.4 + +/\S+/8 + 12abcd34 + *** Failers + \ \ + +/\S{2,3}/8 + 12abcd34 + 1234abcd + *** Failers + \ \ + +/\S{2,3}?/8 + 12abcd34 + 1234abcd + *** Failers + \ \ + +/>\s+ <34 + *** Failers + +/>\s{2,3} \s{2,3}? \xff< + +/[\xff]/8 + >\x{ff}< + +/[^\xFF]/ + XYZ + +/[^\xff]/8 + XYZ + \x{123} + +/^[ac]*b/8 + xb + +/^[ac\x{100}]*b/8 + xb + +/^[^x]*b/8i + xb + +/^[^x]*b/8 + xb + +/^\d*b/8 + xb + +/(|a)/g8 + catac + a\x{256}a + +/^\x{85}$/8i + \x{85} + +/^ሴ/8 + ሴ + +/^\ሴ/8 + ሴ + +"(?s)(.{1,5})"8 + abcdefg + ab + +/a*\x{100}*\w/8 + a + +/\S\S/8g + A\x{a3}BC + +/\S{2}/8g + A\x{a3}BC + +/\W\W/8g + +\x{a3}== + +/\W{2}/8g + +\x{a3}== + +/\S/8g + \x{442}\x{435}\x{441}\x{442} + +/[\S]/8g + \x{442}\x{435}\x{441}\x{442} + +/\D/8g + \x{442}\x{435}\x{441}\x{442} + +/[\D]/8g + \x{442}\x{435}\x{441}\x{442} + +/\W/8g + \x{2442}\x{2435}\x{2441}\x{2442} + +/[\W]/8g + \x{2442}\x{2435}\x{2441}\x{2442} + +/[\S\s]*/8 + abc\n\r\x{442}\x{435}\x{441}\x{442}xyz + +/[\x{41f}\S]/8g + \x{442}\x{435}\x{441}\x{442} + +/.[^\S]./8g + abc def\x{442}\x{443}xyz\npqr + +/.[^\S\n]./8g + abc def\x{442}\x{443}xyz\npqr + +/[[:^alnum:]]/8g + +\x{2442} + +/[[:^alpha:]]/8g + +\x{2442} + +/[[:^ascii:]]/8g + A\x{442} + +/[[:^blank:]]/8g + A\x{442} + +/[[:^cntrl:]]/8g + A\x{442} + +/[[:^digit:]]/8g + A\x{442} + +/[[:^graph:]]/8g + \x19\x{e01ff} + +/[[:^lower:]]/8g + A\x{422} + +/[[:^print:]]/8g + \x{19}\x{e01ff} + +/[[:^punct:]]/8g + A\x{442} + +/[[:^space:]]/8g + A\x{442} + +/[[:^upper:]]/8g + a\x{442} + +/[[:^word:]]/8g + +\x{2442} + +/[[:^xdigit:]]/8g + M\x{442} + +/[^ABCDEFGHIJKLMNOPQRSTUVWXYZÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖØÙÚÛÜÃÞĀĂĄĆĈĊČĎÄĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶĹĻĽĿÅŃŅŇŊŌŎÅŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽÆƂƄƆƇƉƊƋƎÆÆƑƓƔƖƗƘƜÆƟƠƢƤƦƧƩƬƮƯƱƲƳƵƷƸƼDŽLJNJÇÇǑǓǕǗǙǛǞǠǢǤǦǨǪǬǮDZǴǶǷǸǺǼǾȀȂȄȆȈȊȌȎÈȒȔȖȘȚȜȞȠȢȤȦȨȪȬȮȰȲȺȻȽȾÉΆΈΉΊΌΎÎΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩΪΫϒϓϔϘϚϜϞϠϢϤϦϨϪϬϮϴϷϹϺϽϾϿЀÐЂЃЄЅІЇЈЉЊЋЌÐÐŽÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎÒҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾӀÓÓƒÓ…Ó‡Ó‰Ó‹ÓÓӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӶӸԀԂԄԆԈԊԌԎԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀÕÕ‚ÕƒÕ„Õ…Õ†Õ‡ÕˆÕ‰ÕŠÕ‹ÕŒÕÕŽÕÕՑՒՓՔՕՖႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀáƒáƒ‚ჃჄჅḀḂḄḆḈḊḌḎá¸á¸’ḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎá¹á¹’ṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎáºáº’ẔẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎá»á»’ỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸἈἉἊἋἌá¼á¼Žá¼á¼˜á¼™á¼šá¼›á¼œá¼á¼¨á¼©á¼ªá¼«á¼¬á¼­á¼®á¼¯á¼¸á¼¹á¼ºá¼»á¼¼á¼½á¼¾á¼¿á½ˆá½‰á½Šá½‹á½Œá½á½™á½›á½á½Ÿá½¨á½©á½ªá½«á½¬á½­á½®á½¯á¾¸á¾¹á¾ºá¾»á¿ˆá¿‰á¿Šá¿‹á¿˜á¿™á¿šá¿›á¿¨á¿©á¿ªá¿«á¿¬á¿¸á¿¹á¿ºá¿»abcdefghijklmnopqrstuvwxyzªµºßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿÄăąćĉċÄÄđēĕėęěÄğġģĥħĩīĭįıijĵķĸĺļľŀłńņňʼnŋÅÅőœŕŗřśÅşšţťŧũūŭůűųŵŷźżžſƀƃƅƈƌƃƕƙƚƛƞơƣƥƨƪƫƭưƴƶƹƺƽƾƿdžljnjǎÇǒǔǖǘǚǜÇǟǡǣǥǧǩǫǭǯǰdzǵǹǻǽǿÈȃȅȇȉȋÈÈȑȓȕȗșțÈȟȡȣȥȧȩȫȭȯȱȳȴȵȶȷȸȹȼȿɀÉɑɒɓɔɕɖɗɘəɚɛɜÉɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀÊʂʃʄʅʆʇʈʉʊʋʌÊÊŽÊÊʑʒʓʔʕʖʗʘʙʚʛʜÊʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯÎάέήίΰαβγδεζηθικλμνξοπÏςστυφχψωϊϋόÏÏŽÏϑϕϖϗϙϛÏϟϡϣϥϧϩϫϭϯϰϱϲϳϵϸϻϼабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÑёђѓєѕіїјљњћќÑўџѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿÒÒ‹ÒÒÒ‘Ò“Ò•Ò—Ò™Ò›ÒҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӂӄӆӈӊӌӎӑӓӕӗәӛÓÓŸÓ¡Ó£Ó¥Ó§Ó©Ó«Ó­Ó¯Ó±Ó³ÓµÓ·Ó¹ÔÔƒÔ…Ô‡Ô‰Ô‹ÔÔÕ¡Õ¢Õ£Õ¤Õ¥Õ¦Õ§Õ¨Õ©ÕªÕ«Õ¬Õ­Õ®Õ¯Õ°Õ±Õ²Õ³Õ´ÕµÕ¶Õ·Õ¸Õ¹ÕºÕ»Õ¼Õ½Õ¾Õ¿Ö€Öւփքօֆևᴀá´á´‚ᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌá´á´Žá´á´á´‘ᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜá´á´žá´Ÿá´ á´¡á´¢á´£á´¤á´¥á´¦á´§á´¨á´©á´ªá´«áµ¢áµ£áµ¤áµ¥áµ¦áµ§áµ¨áµ©áµªáµ«áµ¬áµ­áµ®áµ¯áµ°áµ±áµ²áµ³áµ´áµµáµ¶áµ·áµ¹áµºáµ»áµ¼áµ½áµ¾áµ¿á¶€á¶á¶‚ᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌá¶á¶Žá¶á¶á¶‘ᶒᶓᶔᶕᶖᶗᶘᶙᶚá¸á¸ƒá¸…ḇḉḋá¸á¸á¸‘ḓḕḗḙḛá¸á¸Ÿá¸¡á¸£á¸¥á¸§á¸©á¸«á¸­á¸¯á¸±á¸³á¸µá¸·á¸¹á¸»á¸½á¸¿á¹á¹ƒá¹…ṇṉṋá¹á¹á¹‘ṓṕṗṙṛá¹á¹Ÿá¹¡á¹£á¹¥á¹§á¹©á¹«á¹­á¹¯á¹±á¹³á¹µá¹·á¹¹á¹»á¹½á¹¿áºáºƒáº…ẇẉẋáºáºáº‘ẓẕẖẗẘẙẚẛạảấầẩẫậắằẳẵặẹẻẽếá»á»ƒá»…ệỉịá»á»á»‘ồổỗộớá»á»Ÿá»¡á»£á»¥á»§á»©á»«á»­á»¯á»±á»³á»µá»·á»¹á¼€á¼á¼‚ἃἄἅἆἇá¼á¼‘ἒἓἔἕἠἡἢἣἤἥἦἧἰἱἲἳἴἵἶἷὀá½á½‚ὃὄὅá½á½‘ὒὓὔὕὖὗὠὡὢὣὤὥὦὧὰάὲέὴήὶίὸόὺύὼώᾀá¾á¾‚ᾃᾄᾅᾆᾇá¾á¾‘ᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷιῂῃῄῆῇá¿á¿‘ῒΐῖῗῠῡῢΰῤῥῦῧῲῳῴῶῷâ²â²ƒâ²…ⲇⲉⲋâ²â²â²‘ⲓⲕⲗⲙⲛâ²â²Ÿâ²¡â²£â²¥â²§â²©â²«â²­â²¯â²±â²³â²µâ²·â²¹â²»â²½â²¿â³â³ƒâ³…ⳇⳉⳋâ³â³â³‘ⳓⳕⳗⳙⳛâ³â³Ÿâ³¡â³£â³¤â´€â´â´‚ⴃⴄⴅⴆⴇⴈⴉⴊⴋⴌâ´â´Žâ´â´â´‘ⴒⴓⴔⴕⴖⴗⴘⴙⴚⴛⴜâ´â´žâ´Ÿâ´ â´¡â´¢â´£â´¤â´¥ï¬€ï¬ï¬‚ffifflſtstﬓﬔﬕﬖﬗ\d-_^]/8 + +/^[^d]*?$/ + abc + +/^[^d]*?$/8 + abc + +/^[^d]*?$/i + abc + +/^[^d]*?$/8i + abc + +/(?i)[\xc3\xa9\xc3\xbd]|[\xc3\xa9\xc3\xbdA]/8 + +/^[a\x{c0}]b/8 + \x{c0}b + +/^([a\x{c0}]*?)aa/8 + a\x{c0}aaaa/ + +/^([a\x{c0}]*?)aa/8 + a\x{c0}aaaa/ + a\x{c0}a\x{c0}aaa/ + +/^([a\x{c0}]*)aa/8 + a\x{c0}aaaa/ + a\x{c0}a\x{c0}aaa/ + +/^([a\x{c0}]*)a\x{c0}/8 + a\x{c0}aaaa/ + a\x{c0}a\x{c0}aaa/ + +/A*/g8 + AAB\x{123}BAA + +/(abc)\1/8i + abc + +/(abc)\1/8 + abc + +/a(*:a\x{1234}b)/8K + abc + +/a(*:a£b)/8K + abc + +/-- End of testinput4 --/ diff --git a/tools/pcre/testdata/testinput5 b/tools/pcre/testdata/testinput5 new file mode 100644 index 00000000..642749c3 --- /dev/null +++ b/tools/pcre/testdata/testinput5 @@ -0,0 +1,772 @@ +/-- 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{110000}/8DZ + +/\x{ffffffff}/8 + +/\x{100000000}/8 + +/\x{d800}/8 + +/\x{dfff}/8 + +/\x{d7ff}/8 + +/\x{e000}/8 + +/^\x{100}a\x{1234}/8 + \x{100}a\x{1234}bcd + +/\x{0041}\x{2262}\x{0391}\x{002e}/DZ8 + \x{0041}\x{2262}\x{0391}\x{002e} + +/.{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 + +/^[ab]/8DZ + bar + *** Failers + c + \x{ff} + \x{100} + +/^[^ab]/8DZ + c + \x{ff} + \x{100} + *** Failers + aaa + +/\x{100}*(\d+|"(?1)")/8 + 1234 + "1234" + \x{100}1234 + "\x{100}1234" + \x{100}\x{100}12ab + \x{100}\x{100}"12" + *** Failers + \x{100}\x{100}abcd + +/\x{100}*/8DZ + +/a\x{100}*/8DZ + +/ab\x{100}*/8DZ + +/\x{100}*A/8DZ + A + +/\x{100}*\d(?R)/8DZ + +/[Z\x{100}]/8DZ + Z\x{100} + \x{100} + \x{100}Z + *** Failers + +/[\x{200}-\x{100}]/8 + +/[Ä€-Ä„]/8 + \x{100} + \x{104} + *** Failers + \x{105} + \x{ff} + +/[z-\x{100}]/8DZ + +/[z\Qa-d]Ä€\E]/8DZ + \x{100} + Ä€ + +/[\xFF]/DZ + >\xff< + +/[^\xFF]/DZ + +/[Ä-Ãœ]/8 + Ö # Matches without Study + \x{d6} + +/[Ä-Ãœ]/8S + Ö <-- Same with Study + \x{d6} + +/[\x{c4}-\x{dc}]/8 + Ö # Matches without Study + \x{d6} + +/[\x{c4}-\x{dc}]/8S + Ö <-- Same with Study + \x{d6} + +/[^\x{100}]abc(xyz(?1))/8DZ + +/[ab\x{100}]abc(xyz(?1))/8DZ + +/(\x{100}(b(?2)c))?/DZ8 + +/(\x{100}(b(?2)c)){0,2}/DZ8 + +/(\x{100}(b(?1)c))?/DZ8 + +/(\x{100}(b(?1)c)){0,2}/DZ8 + +/\W/8 + A.B + A\x{100}B + +/\w/8 + \x{100}X + +/^\ሴ/8DZ + +/\x{100}*\d/8DZ + +/\x{100}*\s/8DZ + +/\x{100}*\w/8DZ + +/\x{100}*\D/8DZ + +/\x{100}*\S/8DZ + +/\x{100}*\W/8DZ + +/()()()()()()()()()() + ()()()()()()()()()() + ()()()()()()()()()() + ()()()()()()()()()() + A (x) (?41) B/8x + AxxB + +/^[\x{100}\E-\Q\E\x{150}]/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 + +/abc.$/mgx8 + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 + +/^a\Rb/8 + a\nb + a\rb + a\r\nb + a\x0bb + a\x0cb + a\x{85}b + a\x{2028}b + a\x{2029}b + ** Failers + a\n\rb + +/^a\R*b/8 + ab + a\nb + a\rb + a\r\nb + a\x0bb + a\x0c\x{2028}\x{2029}b + a\x{85}b + a\n\rb + a\n\r\x{85}\x0cb + +/^a\R+b/8 + a\nb + a\rb + a\r\nb + a\x0bb + a\x0c\x{2028}\x{2029}b + a\x{85}b + a\n\rb + a\n\r\x{85}\x0cb + ** Failers + ab + +/^a\R{1,3}b/8 + a\nb + a\n\rb + a\n\r\x{85}b + a\r\n\r\nb + a\r\n\r\n\r\nb + a\n\r\n\rb + a\n\n\r\nb + ** Failers + a\n\n\n\rb + a\r + +/\H\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 + +/[\h]/8BZ + >\x{1680} + +/[\h]{3,}/8BZ + >\x{1680}\x{180e}\x{2000}\x{2003}\x{200a}\x{202f}\x{205f}\x{3000}< + +/[\v]/8BZ + +/[\H]/8BZ + +/[\V]/8BZ + +/.*$/8 + \x{1ec5} + +/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\ + +/.*a.*=.b.*/8 + QQQ\x{2029}ABCaXYZ=!bPQR + ** Failers + a\x{2029}b + \x61\xe2\x80\xa9\x62 + +/[[:a\x{100}b:]]/8 + +/a[^]b/8 + a\x{1234}b + a\nb + ** Failers + ab + +/a[^]+b/8 + aXb + a\nX\nX\x{1234}b + ** Failers + ab + +/(\x{de})\1/ + \x{de}\x{de} + +/X/8f + A\x{1ec5}ABCXYZ + +/Xa{2,4}b/8 + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/Xa{2,4}?b/8 + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/Xa{2,4}+b/8 + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X\x{123}{2,4}b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X\x{123}{2,4}?b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X\x{123}{2,4}+b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X\x{123}{2,4}b/8 + Xx\P + X\x{123}x\P + X\x{123}\x{123}x\P + X\x{123}\x{123}\x{123}x\P + X\x{123}\x{123}\x{123}\x{123}x\P + +/X\x{123}{2,4}?b/8 + Xx\P + X\x{123}x\P + X\x{123}\x{123}x\P + X\x{123}\x{123}\x{123}x\P + X\x{123}\x{123}\x{123}\x{123}x\P + +/X\x{123}{2,4}+b/8 + Xx\P + X\x{123}x\P + X\x{123}\x{123}x\P + X\x{123}\x{123}\x{123}x\P + X\x{123}\x{123}\x{123}\x{123}x\P + +/X\d{2,4}b/8 + X\P + X3\P + X33\P + X333\P + X3333\P + +/X\d{2,4}?b/8 + X\P + X3\P + X33\P + X333\P + X3333\P + +/X\d{2,4}+b/8 + X\P + X3\P + X33\P + X333\P + X3333\P + +/X\D{2,4}b/8 + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X\D{2,4}?b/8 + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X\D{2,4}+b/8 + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X\D{2,4}b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X\D{2,4}?b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X\D{2,4}+b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X[abc]{2,4}b/8 + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X[abc]{2,4}?b/8 + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X[abc]{2,4}+b/8 + X\P + Xa\P + Xaa\P + Xaaa\P + Xaaaa\P + +/X[abc\x{123}]{2,4}b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X[abc\x{123}]{2,4}?b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X[abc\x{123}]{2,4}+b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X[^a]{2,4}b/8 + X\P + Xz\P + Xzz\P + Xzzz\P + Xzzzz\P + +/X[^a]{2,4}?b/8 + X\P + Xz\P + Xzz\P + Xzzz\P + Xzzzz\P + +/X[^a]{2,4}+b/8 + X\P + Xz\P + Xzz\P + Xzzz\P + Xzzzz\P + +/X[^a]{2,4}b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X[^a]{2,4}?b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/X[^a]{2,4}+b/8 + X\P + X\x{123}\P + X\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\P + X\x{123}\x{123}\x{123}\x{123}\P + +/(Y)X\1{2,4}b/8 + YX\P + YXY\P + YXYY\P + YXYYY\P + YXYYYY\P + +/(Y)X\1{2,4}?b/8 + YX\P + YXY\P + YXYY\P + YXYYY\P + YXYYYY\P + +/(Y)X\1{2,4}+b/8 + YX\P + YXY\P + YXYY\P + YXYYY\P + YXYYYY\P + +/(\x{123})X\1{2,4}b/8 + \x{123}X\P + \x{123}X\x{123}\P + \x{123}X\x{123}\x{123}\P + \x{123}X\x{123}\x{123}\x{123}\P + \x{123}X\x{123}\x{123}\x{123}\x{123}\P + +/(\x{123})X\1{2,4}?b/8 + \x{123}X\P + \x{123}X\x{123}\P + \x{123}X\x{123}\x{123}\P + \x{123}X\x{123}\x{123}\x{123}\P + \x{123}X\x{123}\x{123}\x{123}\x{123}\P + +/(\x{123})X\1{2,4}+b/8 + \x{123}X\P + \x{123}X\x{123}\P + \x{123}X\x{123}\x{123}\P + \x{123}X\x{123}\x{123}\x{123}\P + \x{123}X\x{123}\x{123}\x{123}\x{123}\P + +/\bthe cat\b/8 + the cat\P + the cat\P\P + +/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 + +/(a)bc\1*/8 + xxxxabca\P + xxxxabca\P\P + +/abc[de]*/8 + xxxxabcde\P + xxxxabcde\P\P + +/X\W{3}X/8 + \PX + +/\sxxx\s/8T1 + AB\x{85}xxx\x{a0}XYZ + AB\x{a0}xxx\x{85}XYZ + +/\S \S/8T1 + \x{a2} \x{84} + +'A#хц'8xBZ + +'A#хц + PQ'8xBZ + +/a+#Ñ…aa + z#XX?/8xBZ + +/a+#Ñ…aa + z#Ñ…?/8xBZ + +/\g{A}xxx#bXX(?'A'123) (?'A'456)/8xBZ + +/\g{A}xxx#bÑ…(?'A'123) (?'A'456)/8xBZ + +/^\cÄ£/8 + +/(\R*)(.)/s8 + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/(\R)*(.)/s8 + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/[^\x{1234}]+/iS8I + +/[^\x{1234}]+?/iS8I + +/[^\x{1234}]++/iS8I + +/[^\x{1234}]{2}/iS8I + +// + +/f.*/ + \P\Pfor + +/f.*/s + \P\Pfor + +/f.*/8 + \P\Pfor + +/f.*/8s + \P\Pfor + +/\x{d7ff}\x{e000}/8 + +/\x{d800}/8 + +/\x{dfff}/8 + +/\h+/8 + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} + +/[\h\x{e000}]+/8BZ + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} + +/\H+/8 + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} + +/[\H\x{d7ff}]+/8BZ + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} + +/\v+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + +/[\v\x{e000}]+/8BZ + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + +/\V+/8 + \x{2028}\x{2029}\x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + +/[\V\x{d7ff}]+/8BZ + \x{2028}\x{2029}\x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + +/\R+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + +/(..)\1/8 + ab\P + aba\P + abab\P + +/(..)\1/8i + ab\P + abA\P + aBAb\P + +/(..)\1{2,}/8 + ab\P + aba\P + abab\P + ababa\P + ababab\P + ababab\P\P + abababa\P + abababa\P\P + +/(..)\1{2,}/8i + ab\P + aBa\P + aBAb\P + AbaBA\P + abABAb\P + aBAbaB\P\P + abABabA\P + abaBABa\P\P + +/(..)\1{2,}?x/8i + ab\P + abA\P + aBAb\P + abaBA\P + abAbaB\P + abaBabA\P + abAbABaBx\P + +/./8 + \r\P + \r\P\P + +/.{2,3}/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZ + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZi + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZ + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZi + +/(?<=\x{1234}\x{1234})\bxy/I8 + +/(?8BZ + +/[\u0100-\u0200]/8BZ + +/\ud800/8 + +/-- End of testinput5 --/ diff --git a/tools/pcre/testdata/testinput6 b/tools/pcre/testdata/testinput6 new file mode 100644 index 00000000..a4bfb3c1 --- /dev/null +++ b/tools/pcre/testdata/testinput6 @@ -0,0 +1,1319 @@ +/-- This set of tests is for Unicode property support. It is compatible with + Perl >= 5.15. --/ + +/^\pC\pL\pM\pN\pP\pS\pZ\s+/8W + >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} + +/^>\pZ+/8W + >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} + +/^>[[:space:]]*/8W + >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} + +/^>[[:blank:]]*/8W + >\x{20}\x{a0}\x{1680}\x{180e}\x{2000}\x{202f}\x{9}\x{b}\x{2028} + +/^[[:alpha:]]*/8W + Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d} + +/^[[:alnum:]]*/8W + Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d}1\x{660}\x{bef}\x{16ee} + +/^[[:cntrl:]]*/8W + \x{0}\x{09}\x{1f}\x{7f}\x{9f} + +/^[[:graph:]]*/8W + A\x{a1}\x{a0} + +/^[[:print:]]*/8W + A z\x{a0}\x{a1} + +/^[[:punct:]]*/8W + .+\x{a1}\x{a0} + +/\p{Zs}*?\R/ + ** Failers + a\xFCb + +/\p{Zs}*\R/ + ** Failers + a\xFCb + +/â±¥/8i + â±¥ + Ⱥx + Ⱥ + +/[â±¥]/8i + â±¥ + Ⱥx + Ⱥ + +/Ⱥ/8i + Ⱥ + â±¥ + +/-- These are tests for extended grapheme clusters --/ + +/^\X/8+ + G\x{34e}\x{34e}X + \x{34e}\x{34e}X + \x04X + \x{1100}X + \x{1100}\x{34e}X + \x{1b04}\x{1b04}X + *These match up to the roman letters + \x{1111}\x{1111}L,L + \x{1111}\x{1111}\x{1169}L,L,V + \x{1111}\x{ae4c}L, LV + \x{1111}\x{ad89}L, LVT + \x{1111}\x{ae4c}\x{1169}L, LV, V + \x{1111}\x{ae4c}\x{1169}\x{1169}L, LV, V, V + \x{1111}\x{ae4c}\x{1169}\x{11fe}L, LV, V, T + \x{1111}\x{ad89}\x{11fe}L, LVT, T + \x{1111}\x{ad89}\x{11fe}\x{11fe}L, LVT, T, T + \x{ad89}\x{11fe}\x{11fe}LVT, T, T + *These match just the first codepoint (invalid sequence) + \x{1111}\x{11fe}L, T + \x{ae4c}\x{1111}LV, L + \x{ae4c}\x{ae4c}LV, LV + \x{ae4c}\x{ad89}LV, LVT + \x{1169}\x{1111}V, L + \x{1169}\x{ae4c}V, LV + \x{1169}\x{ad89}V, LVT + \x{ad89}\x{1111}LVT, L + \x{ad89}\x{1169}LVT, V + \x{ad89}\x{ae4c}LVT, LV + \x{ad89}\x{ad89}LVT, LVT + \x{11fe}\x{1111}T, L + \x{11fe}\x{1169}T, V + \x{11fe}\x{ae4c}T, LV + \x{11fe}\x{ad89}T, LVT + *Test extend and spacing mark + \x{1111}\x{ae4c}\x{0711}L, LV, extend + \x{1111}\x{ae4c}\x{1b04}L, LV, spacing mark + \x{1111}\x{ae4c}\x{1b04}\x{0711}\x{1b04}L, LV, spacing mark, extend, spacing mark + *Test CR, LF, and control + \x0d\x{0711}CR, extend + \x0d\x{1b04}CR, spacingmark + \x0a\x{0711}LF, extend + \x0a\x{1b04}LF, spacingmark + \x0b\x{0711}Control, extend + \x09\x{1b04}Control, spacingmark + *There are no Prepend characters, so we can't test Prepend, CR + +/^(?>\X{2})X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + +/^\X{2,4}X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + +/^\X{2,4}?X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + +/-- --/ + +/\x{1e9e}+/8i + \x{1e9e}\x{00df} + +/[z\x{1e9e}]+/8i + \x{1e9e}\x{00df} + +/\x{00df}+/8i + \x{1e9e}\x{00df} + +/[z\x{00df}]+/8i + \x{1e9e}\x{00df} + +/\x{1f88}+/8i + \x{1f88}\x{1f80} + +/[z\x{1f88}]+/8i + \x{1f88}\x{1f80} + +/-- Characters with more than one other case; test in classes --/ + +/[z\x{00b5}]+/8i + \x{00b5}\x{039c}\x{03bc} + +/[z\x{039c}]+/8i + \x{00b5}\x{039c}\x{03bc} + +/[z\x{03bc}]+/8i + \x{00b5}\x{039c}\x{03bc} + +/[z\x{00c5}]+/8i + \x{00c5}\x{00e5}\x{212b} + +/[z\x{00e5}]+/8i + \x{00c5}\x{00e5}\x{212b} + +/[z\x{212b}]+/8i + \x{00c5}\x{00e5}\x{212b} + +/[z\x{01c4}]+/8i + \x{01c4}\x{01c5}\x{01c6} + +/[z\x{01c5}]+/8i + \x{01c4}\x{01c5}\x{01c6} + +/[z\x{01c6}]+/8i + \x{01c4}\x{01c5}\x{01c6} + +/[z\x{01c7}]+/8i + \x{01c7}\x{01c8}\x{01c9} + +/[z\x{01c8}]+/8i + \x{01c7}\x{01c8}\x{01c9} + +/[z\x{01c9}]+/8i + \x{01c7}\x{01c8}\x{01c9} + +/[z\x{01ca}]+/8i + \x{01ca}\x{01cb}\x{01cc} + +/[z\x{01cb}]+/8i + \x{01ca}\x{01cb}\x{01cc} + +/[z\x{01cc}]+/8i + \x{01ca}\x{01cb}\x{01cc} + +/[z\x{01f1}]+/8i + \x{01f1}\x{01f2}\x{01f3} + +/[z\x{01f2}]+/8i + \x{01f1}\x{01f2}\x{01f3} + +/[z\x{01f3}]+/8i + \x{01f1}\x{01f2}\x{01f3} + +/[z\x{0345}]+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + +/[z\x{0399}]+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + +/[z\x{03b9}]+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + +/[z\x{1fbe}]+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + +/[z\x{0392}]+/8i + \x{0392}\x{03b2}\x{03d0} + +/[z\x{03b2}]+/8i + \x{0392}\x{03b2}\x{03d0} + +/[z\x{03d0}]+/8i + \x{0392}\x{03b2}\x{03d0} + +/[z\x{0395}]+/8i + \x{0395}\x{03b5}\x{03f5} + +/[z\x{03b5}]+/8i + \x{0395}\x{03b5}\x{03f5} + +/[z\x{03f5}]+/8i + \x{0395}\x{03b5}\x{03f5} + +/[z\x{0398}]+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + +/[z\x{03b8}]+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + +/[z\x{03d1}]+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + +/[z\x{03f4}]+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + +/[z\x{039a}]+/8i + \x{039a}\x{03ba}\x{03f0} + +/[z\x{03ba}]+/8i + \x{039a}\x{03ba}\x{03f0} + +/[z\x{03f0}]+/8i + \x{039a}\x{03ba}\x{03f0} + +/[z\x{03a0}]+/8i + \x{03a0}\x{03c0}\x{03d6} + +/[z\x{03c0}]+/8i + \x{03a0}\x{03c0}\x{03d6} + +/[z\x{03d6}]+/8i + \x{03a0}\x{03c0}\x{03d6} + +/[z\x{03a1}]+/8i + \x{03a1}\x{03c1}\x{03f1} + +/[z\x{03c1}]+/8i + \x{03a1}\x{03c1}\x{03f1} + +/[z\x{03f1}]+/8i + \x{03a1}\x{03c1}\x{03f1} + +/[z\x{03a3}]+/8i + \x{03A3}\x{03C2}\x{03C3} + +/[z\x{03c2}]+/8i + \x{03A3}\x{03C2}\x{03C3} + +/[z\x{03c3}]+/8i + \x{03A3}\x{03C2}\x{03C3} + +/[z\x{03a6}]+/8i + \x{03a6}\x{03c6}\x{03d5} + +/[z\x{03c6}]+/8i + \x{03a6}\x{03c6}\x{03d5} + +/[z\x{03d5}]+/8i + \x{03a6}\x{03c6}\x{03d5} + +/[z\x{03c9}]+/8i + \x{03c9}\x{03a9}\x{2126} + +/[z\x{03a9}]+/8i + \x{03c9}\x{03a9}\x{2126} + +/[z\x{2126}]+/8i + \x{03c9}\x{03a9}\x{2126} + +/[z\x{1e60}]+/8i + \x{1e60}\x{1e61}\x{1e9b} + +/[z\x{1e61}]+/8i + \x{1e60}\x{1e61}\x{1e9b} + +/[z\x{1e9b}]+/8i + \x{1e60}\x{1e61}\x{1e9b} + +/-- Perl 5.12.4 gets these wrong, but 5.15.3 is OK --/ + +/[z\x{004b}]+/8i + \x{004b}\x{006b}\x{212a} + +/[z\x{006b}]+/8i + \x{004b}\x{006b}\x{212a} + +/[z\x{212a}]+/8i + \x{004b}\x{006b}\x{212a} + +/[z\x{0053}]+/8i + \x{0053}\x{0073}\x{017f} + +/[z\x{0073}]+/8i + \x{0053}\x{0073}\x{017f} + +/[z\x{017f}]+/8i + \x{0053}\x{0073}\x{017f} + +/-- --/ + +/(ΣΆΜΟΣ) \1/8i + ΣΆΜΟΣ ΣΆΜΟΣ + ΣΆΜΟΣ σάμος + σάμος σάμος + σάμος σάμοσ + σάμος ΣΆΜΟΣ + +/(σάμος) \1/8i + ΣΆΜΟΣ ΣΆΜΟΣ + ΣΆΜΟΣ σάμος + σάμος σάμος + σάμος σάμοσ + σάμος ΣΆΜΟΣ + +/(ΣΆΜΟΣ) \1*/8i + ΣΆΜΟΣ\x20 + ΣΆΜΟΣ ΣΆΜΟΣσάμοςσάμος + +/-- Perl matches these --/ + +/\x{00b5}+/8i + \x{00b5}\x{039c}\x{03bc} + +/\x{039c}+/8i + \x{00b5}\x{039c}\x{03bc} + +/\x{03bc}+/8i + \x{00b5}\x{039c}\x{03bc} + + +/\x{00c5}+/8i + \x{00c5}\x{00e5}\x{212b} + +/\x{00e5}+/8i + \x{00c5}\x{00e5}\x{212b} + +/\x{212b}+/8i + \x{00c5}\x{00e5}\x{212b} + + +/\x{01c4}+/8i + \x{01c4}\x{01c5}\x{01c6} + +/\x{01c5}+/8i + \x{01c4}\x{01c5}\x{01c6} + +/\x{01c6}+/8i + \x{01c4}\x{01c5}\x{01c6} + + +/\x{01c7}+/8i + \x{01c7}\x{01c8}\x{01c9} + +/\x{01c8}+/8i + \x{01c7}\x{01c8}\x{01c9} + +/\x{01c9}+/8i + \x{01c7}\x{01c8}\x{01c9} + + +/\x{01ca}+/8i + \x{01ca}\x{01cb}\x{01cc} + +/\x{01cb}+/8i + \x{01ca}\x{01cb}\x{01cc} + +/\x{01cc}+/8i + \x{01ca}\x{01cb}\x{01cc} + + +/\x{01f1}+/8i + \x{01f1}\x{01f2}\x{01f3} + +/\x{01f2}+/8i + \x{01f1}\x{01f2}\x{01f3} + +/\x{01f3}+/8i + \x{01f1}\x{01f2}\x{01f3} + + +/\x{0345}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + +/\x{0399}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + +/\x{03b9}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + +/\x{1fbe}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + + +/\x{0392}+/8i + \x{0392}\x{03b2}\x{03d0} + +/\x{03b2}+/8i + \x{0392}\x{03b2}\x{03d0} + +/\x{03d0}+/8i + \x{0392}\x{03b2}\x{03d0} + + +/\x{0395}+/8i + \x{0395}\x{03b5}\x{03f5} + +/\x{03b5}+/8i + \x{0395}\x{03b5}\x{03f5} + +/\x{03f5}+/8i + \x{0395}\x{03b5}\x{03f5} + + +/\x{0398}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + +/\x{03b8}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + +/\x{03d1}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + +/\x{03f4}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + + +/\x{039a}+/8i + \x{039a}\x{03ba}\x{03f0} + +/\x{03ba}+/8i + \x{039a}\x{03ba}\x{03f0} + +/\x{03f0}+/8i + \x{039a}\x{03ba}\x{03f0} + + +/\x{03a0}+/8i + \x{03a0}\x{03c0}\x{03d6} + +/\x{03c0}+/8i + \x{03a0}\x{03c0}\x{03d6} + +/\x{03d6}+/8i + \x{03a0}\x{03c0}\x{03d6} + + +/\x{03a1}+/8i + \x{03a1}\x{03c1}\x{03f1} + +/\x{03c1}+/8i + \x{03a1}\x{03c1}\x{03f1} + +/\x{03f1}+/8i + \x{03a1}\x{03c1}\x{03f1} + + +/\x{03a3}+/8i + \x{03A3}\x{03C2}\x{03C3} + +/\x{03c2}+/8i + \x{03A3}\x{03C2}\x{03C3} + +/\x{03c3}+/8i + \x{03A3}\x{03C2}\x{03C3} + + +/\x{03a6}+/8i + \x{03a6}\x{03c6}\x{03d5} + +/\x{03c6}+/8i + \x{03a6}\x{03c6}\x{03d5} + +/\x{03d5}+/8i + \x{03a6}\x{03c6}\x{03d5} + + +/\x{03c9}+/8i + \x{03c9}\x{03a9}\x{2126} + +/\x{03a9}+/8i + \x{03c9}\x{03a9}\x{2126} + +/\x{2126}+/8i + \x{03c9}\x{03a9}\x{2126} + + +/\x{1e60}+/8i + \x{1e60}\x{1e61}\x{1e9b} + +/\x{1e61}+/8i + \x{1e60}\x{1e61}\x{1e9b} + +/\x{1e9b}+/8i + \x{1e60}\x{1e61}\x{1e9b} + + +/\x{1e9e}+/8i + \x{1e9e}\x{00df} + +/\x{00df}+/8i + \x{1e9e}\x{00df} + + +/\x{1f88}+/8i + \x{1f88}\x{1f80} + +/\x{1f80}+/8i + \x{1f88}\x{1f80} + + +/-- Perl 5.12.4 gets these wrong, but 5.15.3 is OK --/ + +/\x{004b}+/8i + \x{004b}\x{006b}\x{212a} + +/\x{006b}+/8i + \x{004b}\x{006b}\x{212a} + +/\x{212a}+/8i + \x{004b}\x{006b}\x{212a} + + +/\x{0053}+/8i + \x{0053}\x{0073}\x{017f} + +/\x{0073}+/8i + \x{0053}\x{0073}\x{017f} + +/\x{017f}+/8i + \x{0053}\x{0073}\x{017f} + +/-- End of testinput6 --/ diff --git a/tools/pcre/testdata/testinput7 b/tools/pcre/testdata/testinput7 new file mode 100644 index 00000000..b265f1f9 --- /dev/null +++ b/tools/pcre/testdata/testinput7 @@ -0,0 +1,672 @@ +/-- These tests for Unicode property support test PCRE's API and show some of + the compiled code. They are not Perl-compatible. --/ + +/[\p{L}]/DZ + +/[\p{^L}]/DZ + +/[\P{L}]/DZ + +/[\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 + +/[\x{105}-\x{109}]/8iDZ + \x{104} + \x{105} + \x{109} + ** Failers + \x{100} + \x{10a} + +/[z-\x{100}]/8iDZ + Z + z + \x{39c} + \x{178} + | + \x{80} + \x{ff} + \x{100} + \x{101} + ** Failers + \x{102} + Y + y + +/[z-\x{100}]/8DZi + +/(?:[\PPa*]*){8,}/ + +/[\P{Any}]/BZ + +/[\P{Any}\E]/BZ + +/(\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 + 

 + \x{2028}\x{2028}\x{2028} + +/\p{Zl}/8BZ + +/\p{Lu}{3}+/8BZ + +/\pL{2}+/8BZ + +/\p{Cc}{2}+/8BZ + +/^\p{Cs}/8 + \?\x{dfff} + ** Failers + \x{09f} + +/^\p{Sc}+/8 + $\x{a2}\x{a3}\x{a4}\x{a5}\x{a6} + \x{9f2} + ** Failers + X + \x{2c2} + +/^\p{Zs}/8 + \ \ + \x{a0} + \x{1680} + \x{180e} + \x{2000} + \x{2001} + ** Failers + \x{2028} + \x{200d} + +/-- These four are here rather than in test 6 because Perl has problems with + the negative versions of the properties. --/ + +/\p{^Lu}/8i + 1234 + ** Failers + ABC + +/\P{Lu}/8i + 1234 + ** Failers + ABC + +/\p{Ll}/8i + a + Az + ** Failers + ABC + +/\p{Lu}/8i + A + a\x{10a0}B + ** Failers + a + \x{1d00} + +/[\x{c0}\x{391}]/8i + \x{c0} + \x{e0} + +/-- The next two are special cases where the lengths of the different cases of +the same character differ. The first went wrong with heap frame storage; the +second was broken in all cases. --/ + +/^\x{023a}+?(\x{0130}+)/8i + \x{023a}\x{2c65}\x{0130} + +/^\x{023a}+([^X])/8i + \x{023a}\x{2c65}X + +/\x{c0}+\x{116}+/8i + \x{c0}\x{e0}\x{116}\x{117} + +/[\x{c0}\x{116}]+/8i + \x{c0}\x{e0}\x{116}\x{117} + +/(\x{de})\1/8i + \x{de}\x{de} + \x{de}\x{fe} + \x{fe}\x{fe} + \x{fe}\x{de} + +/^\x{c0}$/8i + \x{c0} + \x{e0} + +/^\x{e0}$/8i + \x{c0} + \x{e0} + +/-- The next two should be Perl-compatible, but it fails to match \x{e0}. PCRE +will match it only with UCP support, because without that it has no notion +of case for anything other than the ASCII letters. --/ + +/((?i)[\x{c0}])/8 + \x{c0} + \x{e0} + +/(?i:[\x{c0}])/8 + \x{c0} + \x{e0} + +/-- These are PCRE's extra properties to help with Unicodizing \d etc. --/ + +/^\p{Xan}/8 + ABCD + 1234 + \x{6ca} + \x{a6c} + \x{10a7} + ** Failers + _ABC + +/^\p{Xan}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + ** Failers + _ABC + +/^\p{Xan}+?/8 + \x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xan}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xan}{2,9}/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xan}{2,9}?/8 + \x{6ca}\x{a6c}\x{10a7}_ + +/^[\p{Xan}]/8 + ABCD1234_ + 1234abcd_ + \x{6ca} + \x{a6c} + \x{10a7} + ** Failers + _ABC + +/^[\p{Xan}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + ** Failers + _ABC + +/^>\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 + +/[[:cntrl:]]/WBZ + +/[[:digit:]]/WBZ + +/[[:graph:]]/WBZ + +/[[:print:]]/WBZ + +/[[:punct:]]/WBZ + +/[[:space:]]/WBZ + +/[[:word:]]/WBZ + +/[[:xdigit:]]/WBZ + +/-- Unicode properties for \b abd \B --/ + +/\b...\B/8W + abc_ + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ + +/\b...\B/8 + abc_ + ** Failers + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ + +/\b...\B/W + abc_ + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- Some of these are silly, but they check various combinations --/ + +/[[:^alpha:][:^cntrl:]]+/8WBZ + 123 + abc + +/[[:^cntrl:][:^alpha:]]+/8WBZ + 123 + abc + +/[[:alpha:]]+/8WBZ + abc + +/[[:^alpha:]\S]+/8WBZ + 123 + abc + +/[^\d]+/8WBZ + abc123 + abc\x{123} + \x{660}abc + +/\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 + +/-- 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} + +/(ȺȺȺ)?\1/8i + ȺȺȺⱥⱥ + +/(\x{23a}\x{23a}\x{23a})?\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + +/(ȺȺȺ)?\1/8i + ȺȺȺⱥⱥⱥ + +/(\x{23a}\x{23a}\x{23a})\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} + +/(ȺȺȺ)\1/8i + ȺȺȺⱥⱥ + +/(\x{23a}\x{23a}\x{23a})\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + +/(ȺȺȺ)\1/8i + ȺȺȺⱥⱥⱥ + +/(\x{2c65}\x{2c65})\1/8i + \x{2c65}\x{2c65}\x{23a}\x{23a} + +/(ⱥⱥ)\1/8i + ⱥⱥȺȺ + +/(\x{23a}\x{23a}\x{23a})\1Y/8i + X\x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}YZ + +/(\x{2c65}\x{2c65})\1Y/8i + X\x{2c65}\x{2c65}\x{23a}\x{23a}YZ + +/-- --/ + +/-- These scripts weren't yet in Perl when I added Unicode 6.0.0 to PCRE --/ + +/^[\p{Batak}]/8 + \x{1bc0} + \x{1bff} + ** Failers + \x{1bf4} + +/^[\p{Brahmi}]/8 + \x{11000} + \x{1106f} + ** Failers + \x{1104e} + +/^[\p{Mandaic}]/8 + \x{840} + \x{85e} + ** Failers + \x{85c} + \x{85d} + +/-- --/ + +/(\X*)(.)/s8 + A\x{300} + +/^S(\X*)e(\X*)$/8 + SteÌreÌo + +/^\X/8 + ÌreÌo + +/^a\X41z/ + aX41z + *** Failers + aAz + +/(?<=ab\Cde)X/8 + +/\X/ + a\P + a\P\P + +/\Xa/ + aa\P + aa\P\P + +/\X{2}/ + aa\P + aa\P\P + +/\X+a/ + a\P + aa\P + aa\P\P + +/\X+?a/ + a\P + ab\P + aa\P + aa\P\P + aba\P + +/-- These Unicode 6.1.0 scripts are not known to Perl. --/ + +/\p{Chakma}\d/8W + \x{11100}\x{1113c} + +/\p{Takri}\d/8W + \x{11680}\x{116c0} + +/^\X/8 + A\P + A\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{301}\P + A\x{301}\P\P + +/^\X{2,3}/8 + A\P + A\P\P + AA\P + AA\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X{2}/8 + AA\P + AA\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X+/8 + AA\P + AA\P\P + +/^\X+?Z/8 + AA\P + AA\P\P + +/A\x{3a3}B/8iDZ + +/\x{3a3}B/8iDZ + +/[\x{3a3}]/8iBZ + +/[^\x{3a3}]/8iBZ + +/[\x{3a3}]+/8iBZ + +/[^\x{3a3}]+/8iBZ + +/a*\x{3a3}/8iBZ + +/\x{3a3}+a/8iBZ + +/\x{3a3}*\x{3c2}/8iBZ + +/\x{3a3}{3}/8i+ + \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} + +/\x{3a3}{2,4}/8i+ + \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} + +/\x{3a3}{2,4}?/8i+ + \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} + +/\x{3a3}+./8i+ + \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} + +/\x{3a3}++./8i+ + ** Failers + \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} + +/\x{3a3}*\x{3c2}/8iBZ + +/[^\x{3a3}]*\x{3c2}/8iBZ + +/[^a]*\x{3c2}/8iBZ + +/ist/8iBZ + ikt + +/is+t/8i + iSs\x{17f}t + ikt + +/is+?t/8i + ikt + +/is?t/8i + ikt + +/is{2}t/8i + iskt + +/-- End of testinput7 --/ diff --git a/tools/pcre/testdata/testinput8 b/tools/pcre/testdata/testinput8 new file mode 100644 index 00000000..e235445e --- /dev/null +++ b/tools/pcre/testdata/testinput8 @@ -0,0 +1,4801 @@ +/-- 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 + +/(?a+)ab/ + +/(?>a+)b/ + aaab + +/([[:]+)/ + a:[b]: + +/([[=]+)/ + a=[b]= + +/([[.]+)/ + a.[b]. + +/((?>a+)b)/ + aaab + +/(?>(a+))b/ + aaab + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/a\Z/ + *** Failers + aaab + a\nb\n + +/b\Z/ + a\nb\n + +/b\z/ + +/b\Z/ + a\nb + +/b\z/ + a\nb + *** Failers + +/(?>.*)(?<=(abcd|wxyz))/ + alphabetabcd + endingwxyz + *** Failers + a rather long string that doesn't end with one of them + +/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark + +/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope + +/(?<=\d{3}(?!999))foo/ + 999foo + 123999foo + *** Failers + 123abcfoo + +/(?<=(?!...999)\d{3})foo/ + 999foo + 123999foo + *** Failers + 123abcfoo + +/(?<=\d{3}(?!999)...)foo/ + 123abcfoo + 123456foo + *** Failers + 123999foo + +/(?<=\d{3}...)(?Z)+|A)*/ + ZABCDEFG + +/((?>)+|A)*/ + ZABCDEFG + +/a*/g + abbab + +/^[a-\d]/ + abcde + -things + 0digit + *** Failers + bcdef + +/^[\d-a]/ + abcde + -things + 0digit + *** Failers + bcdef + +/[[:space:]]+/ + > \x09\x0a\x0c\x0d\x0b< + +/[[:blank:]]+/ + > \x09\x0a\x0c\x0d\x0b< + +/[\s]+/ + > \x09\x0a\x0c\x0d\x0b< + +/\s+/ + > \x09\x0a\x0c\x0d\x0b< + +/a b/x + ab + +/(?!\A)x/m + a\nxb\n + +/(?!^)x/m + a\nxb\n + +/abc\Qabc\Eabc/ + abcabcabc + +/abc\Q(*+|\Eabc/ + abc(*+|abc + +/ abc\Q abc\Eabc/x + abc abcabc + *** Failers + abcabcabc + +/abc#comment + \Q#not comment + literal\E/x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal/x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal\E #more comment + /x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal\E #more comment/x + abc#not comment\n literal + +/\Qabc\$xyz\E/ + abc\\\$xyz + +/\Qabc\E\$\Qxyz\E/ + abc\$xyz + +/\Gabc/ + abc + *** Failers + xyzabc + +/\Gabc./g + abc1abc2xyzabc3 + +/abc./g + abc1abc2xyzabc3 + +/a(?x: b c )d/ + XabcdY + *** Failers + Xa b c d Y + +/((?x)x y z | a b c)/ + XabcY + AxyzB + +/(?i)AB(?-i)C/ + XabCY + *** Failers + XabcY + +/((?i)AB(?-i)C|D)E/ + abCE + DE + *** Failers + abcE + abCe + dE + De + +/[z\Qa-d]\E]/ + z + a + - + d + ] + *** Failers + b + +/[\z\C]/ + z + C + +/\M/ + M + +/(a+)*b/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ + REGular + regulaer + Regex + regulär + +/Åæåä[à-ÿÀ-ß]+/ + Åæåäà + Åæåäÿ + ÅæåäÀ + Åæåäß + +/(?<=Z)X./ + \x84XAZXB + +/^(?(2)a|(1)(2))+$/ + 123a + +/(?<=a|bbbb)c/ + ac + bbbbc + +/abc/SS>testsavedregex +testsavedregex +testsavedregex +testsavedregex + + xyz\r\nabc\ + xyz\rabc\ + xyz\r\nabc\ + ** Failers + xyz\nabc\ + xyz\r\nabc\ + xyz\nabc\ + xyz\rabc\ + xyz\rabc\ + +/abc$/m + xyzabc + xyzabc\n + xyzabc\npqr + xyzabc\r\ + xyzabc\rpqr\ + xyzabc\r\n\ + xyzabc\r\npqr\ + ** Failers + xyzabc\r + xyzabc\rpqr + xyzabc\r\n + xyzabc\r\npqr + +/^abc/m + xyz\rabcdef + xyz\nabcdef\ + ** Failers + xyz\nabcdef + +/^abc/m + xyz\nabcdef + xyz\rabcdef\ + ** Failers + xyz\rabcdef + +/^abc/m + xyz\r\nabcdef + xyz\rabcdef\ + ** Failers + xyz\rabcdef + +/.*/ + abc\ndef + abc\rdef + abc\r\ndef + \abc\ndef + \abc\rdef + \abc\r\ndef + \abc\ndef + \abc\rdef + \abc\r\ndef + +/\w+(.)(.)?def/s + abc\ndef + abc\rdef + abc\r\ndef + +/^\w+=.*(\\\n.*)*/ + abc=xyz\\\npqr + +/^(a()*)*/ + aaaa + +/^(?:a(?:(?:))*)*/ + aaaa + +/^(a()+)+/ + aaaa + +/^(?:a(?:(?:))+)+/ + aaaa + +/(a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?>a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?:a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/^a.b/ + a\rb + a\nb\ + ** Failers + a\nb + a\nb\ + a\rb\ + a\rb\ + +/^abc./mgx + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK + +/abc.$/mgx + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 + +/^a\Rb/ + a\nb + a\rb + a\r\nb + a\x0bb + a\x0cb + a\x85b + ** Failers + a\n\rb + +/^a\R*b/ + ab + a\nb + a\rb + a\r\nb + a\x0bb + a\x0cb + a\x85b + a\n\rb + a\n\r\x85\x0cb + +/^a\R+b/ + a\nb + a\rb + a\r\nb + a\x0bb + a\x0cb + a\x85b + a\n\rb + a\n\r\x85\x0cb + ** Failers + ab + +/^a\R{1,3}b/ + a\nb + a\n\rb + a\n\r\x85b + a\r\n\r\nb + a\r\n\r\n\r\nb + a\n\r\n\rb + a\n\n\r\nb + ** Failers + a\n\n\n\rb + a\r + +/^a[\R]b/ + aRb + ** Failers + a\nb + +/.+foo/ + afoo + ** Failers + \r\nfoo + \nfoo + +/.+foo/ + afoo + \nfoo + ** Failers + \r\nfoo + +/.+foo/ + afoo + ** Failers + \nfoo + \r\nfoo + +/.+foo/s + afoo + \r\nfoo + \nfoo + +/^$/mg + abc\r\rxyz + abc\n\rxyz + ** Failers + abc\r\nxyz + +/^X/m + XABC + ** Failers + XABC\B + +/(?m)^$/g+ + abc\r\n\r\n + +/(?m)^$|^\r\n/g+ + abc\r\n\r\n + +/(?m)$/g+ + abc\r\n\r\n + +/(?|(abc)|(xyz))/ + >abc< + >xyz< + +/(x)(?|(abc)|(xyz))(x)/ + xabcx + xxyzx + +/(x)(?|(abc)(pqr)|(xyz))(x)/ + xabcpqrx + xxyzx + +/(?|(abc)|(xyz))(?1)/ + abcabc + xyzabc + ** Failers + xyzxyz + +/\H\h\V\v/ + X X\x0a + X\x09X\x0b + ** Failers + \xa0 X\x0a + +/\H*\h+\V?\v{3,4}/ + \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a + \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a + \x09\x20\xa0\x0a\x0b\x0c + ** Failers + \x09\x20\xa0\x0a\x0b + +/\H{3,4}/ + XY ABCDE + XY PQR ST + +/.\h{3,4}./ + XY AB PQRS + +/\h*X\h?\H+Y\H?Z/ + >XNNNYZ + > X NYQZ + ** Failers + >XYZ + > X NY Z + +/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ + >XY\x0aZ\x0aA\x0bNN\x0c + >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + +/.+A/ + \r\nA + +/\nA/ + \r\nA + +/[\r\n]A/ + \r\nA + +/(\r|\n)A/ + \r\nA + +/a\Rb/I + a\rb + a\nb + a\r\nb + ** Failers + a\x85b + a\x0bb + +/a\Rb/I + a\rb + a\nb + a\r\nb + a\x85b + a\x0bb + ** Failers + a\x85b\ + a\x0bb\ + +/a\R?b/I + a\rb + a\nb + a\r\nb + ** Failers + a\x85b + a\x0bb + +/a\R?b/I + a\rb + a\nb + a\r\nb + a\x85b + a\x0bb + ** Failers + a\x85b\ + a\x0bb\ + +/a\R{2,4}b/I + a\r\n\nb + a\n\r\rb + a\r\n\r\n\r\n\r\nb + ** Failers + a\x85\85b + a\x0b\0bb + +/a\R{2,4}b/I + a\r\rb + a\n\n\nb + a\r\n\n\r\rb + a\x85\85b + a\x0b\0bb + ** Failers + a\r\r\r\r\rb + a\x85\85b\ + a\x0b\0bb\ + +/a(?!)|\wbc/ + abc + +/a[]b/ + ** Failers + ab + +/a[]+b/ + ** Failers + ab + +/a[]*+b/ + ** Failers + ab + +/a[^]b/ + aXb + a\nb + ** Failers + ab + +/a[^]+b/ + aXb + a\nX\nXb + ** Failers + ab + +/X$/E + X + ** Failers + X\n + +/X$/ + X + X\n + +/xyz/C + xyz + abcxyz + abcxyz\Y + ** Failers + abc + abc\Y + abcxypqr + abcxypqr\Y + +/(*NO_START_OPT)xyz/C + abcxyz + +/(?C)ab/ + ab + \C-ab + +/ab/C + ab + \C-ab + +/^"((?(?=[a])[^"])|b)*"$/C + "ab" + \C-"ab" + +/\d+X|9+Y/ + ++++123999\P + ++++123999Y\P + +/Z(*F)/ + Z\P + ZA\P + +/Z(?!)/ + Z\P + ZA\P + +/dog(sbody)?/ + dogs\P + dogs\P\P + +/dog(sbody)??/ + dogs\P + dogs\P\P + +/dog|dogsbody/ + dogs\P + dogs\P\P + +/dogsbody|dog/ + dogs\P + dogs\P\P + +/Z(*F)Q|ZXY/ + Z\P + ZA\P + X\P + +/\bthe cat\b/ + the cat\P + the cat\P\P + +/dog(sbody)?/ + dogs\D\P + body\D\R + +/dog(sbody)?/ + dogs\D\P\P + body\D\R + +/abc/ + abc\P + abc\P\P + +/abc\K123/ + xyzabc123pqr + +/(?<=abc)123/ + xyzabc123pqr + xyzabc12\P + xyzabc12\P\P + +/\babc\b/ + +++abc+++ + +++ab\P + +++ab\P\P + +/(?=C)/g+ + ABCDECBA + +/(abc|def|xyz)/I + terhjk;abcdaadsfe + the quick xyz brown fox + \Yterhjk;abcdaadsfe + \Ythe quick xyz brown fox + ** Failers + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + +/(abc|def|xyz)/SI + terhjk;abcdaadsfe + the quick xyz brown fox + \Yterhjk;abcdaadsfe + \Ythe quick xyz brown fox + ** Failers + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + +/abcd*/+ + xxxxabcd\P + xxxxabcd\P\P + dddxxx\R + xxxxabcd\P\P + xxx\R + +/abcd*/i + xxxxabcd\P + xxxxabcd\P\P + XXXXABCD\P + XXXXABCD\P\P + +/abc\d*/ + xxxxabc1\P + xxxxabc1\P\P + +/abc[de]*/ + xxxxabcde\P + xxxxabcde\P\P + +/(?:(?1)|B)(A(*F)|C)/ + ABCD + CCD + ** Failers + CAD + +/^(?:(?1)|B)(A(*F)|C)/ + CCD + BCD + ** Failers + ABCD + CAD + BAD + +/^(?!a(*SKIP)b)/ + ac + +/^(?=a(*SKIP)b|ac)/ + ** Failers + ac + +/^(?=a(*THEN)b|ac)/ + ac + +/^(?=a(*PRUNE)b)/ + ab + ** Failers + ac + +/^(?(?!a(*SKIP)b))/ + ac + +/(?<=abc)def/ + abc\P\P + +/abc$/ + abc + abc\P + abc\P\P + +/abc$/m + abc + abc\n + abc\P\P + abc\n\P\P + abc\P + abc\n\P + +/abc\z/ + abc + abc\P + abc\P\P + +/abc\Z/ + abc + abc\P + abc\P\P + +/abc\b/ + abc + abc\P + abc\P\P + +/abc\B/ + abc + abc\P + abc\P\P + +/.+/ + abc\>0 + abc\>1 + abc\>2 + abc\>3 + abc\>4 + abc\>-4 + +/^(?:a)++\w/ + aaaab + ** Failers + aaaa + bbb + +/^(?:aa|(?:a)++\w)/ + aaaab + aaaa + ** Failers + bbb + +/^(?:a)*+\w/ + aaaab + bbb + ** Failers + aaaa + +/^(a)++\w/ + aaaab + ** Failers + aaaa + bbb + +/^(a|)++\w/ + aaaab + ** Failers + aaaa + bbb + +/(?=abc){3}abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc)+abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc)++abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc){0}xyz/ + xyz + +/(?=abc){1}xyz/ + ** Failers + xyz + +/(?=(a))?./ + ab + bc + +/(?=(a))??./ + ab + bc + +/^(?=(a)){0}b(?1)/ + backgammon + +/^(?=(?1))?[az]([abc])d/ + abd + zcdxx + +/^(?!a){0}\w+/ + aaaaa + +/(?<=(abc))?xyz/ + abcxyz + pqrxyz + +/((?2))((?1))/ + abc + +/(?(R)a+|(?R)b)/ + aaaabcde + +/(?(R)a+|((?R))b)/ + aaaabcde + +/((?(R)a+|(?1)b))/ + aaaabcde + +/((?(R2)a+|(?1)b))/ + aaaabcde + +/(?(R)a*(?1)|((?R))b)/ + aaaabcde + +/(a+)/ + \O6aaaa + \O8aaaa + +/ab\Cde/ + abXde + +/(?<=ab\Cde)X/ + abZdeX + +/^\R/ + \r\P + \r\P\P + +/^\R{2,3}x/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + \r\rx + \r\r\rx + +/^\R{2,3}?x/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + \r\rx + \r\r\rx + +/^\R?x/ + \r\P + \r\P\P + x + \rx + +/^\R+x/ + \r\P + \r\P\P + \r\n\P + \r\n\P\P + \rx + +/^a$/ + a\r\P + a\r\P\P + +/^a$/m + a\r\P + a\r\P\P + +/^(a$|a\r)/ + a\r\P + a\r\P\P + +/^(a$|a\r)/m + a\r\P + a\r\P\P + +/./ + \r\P + \r\P\P + +/.{2,3}/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/-- Test simple validity check for restarts --/ + +/abcdef/ + abc\R + +/)(.)|(?R))++)*F>/ + text text xxxxx text F> text2 more text. + +/^(?>.{4})abc|^\w\w.xabcd/ + xxxxabcd + xx\xa0xabcd + +/^(.{4}){2}+abc|^\w\w.x\w\w\w\wabcd/ + xxxxxxxxabcd + xx\xa0xxxxxabcd + +/-- End of testinput8 --/ diff --git a/tools/pcre/testdata/testinput9 b/tools/pcre/testdata/testinput9 new file mode 100644 index 00000000..766c9c0f --- /dev/null +++ b/tools/pcre/testdata/testinput9 @@ -0,0 +1,717 @@ +/-- 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 + 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} + +/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 + ab99 + \x{123}\x{123}45 + \x{400}\x{401}\x{402}6 + *** Failers + d99 + \x{123}\x{122}4 + \x{400}\x{403}6 + \x{400}\x{401}\x{402}\x{402}6 + +/a.b/8 + acb + a\x7fb + a\x{100}b + *** Failers + a\nb + +/a(.{3})b/8 + a\x{4000}xyb + a\x{4000}\x7fyb + a\x{4000}\x{100}yb + *** Failers + a\x{4000}b + ac\ncb + +/a(.*?)(.)/ + a\xc0\x88b + +/a(.*?)(.)/8 + a\x{100}b + +/a(.*)(.)/ + a\xc0\x88b + +/a(.*)(.)/8 + a\x{100}b + +/a(.)(.)/ + a\xc0\x92bcd + +/a(.)(.)/8 + a\x{240}bcd + +/a(.?)(.)/ + a\xc0\x92bcd + +/a(.?)(.)/8 + a\x{240}bcd + +/a(.??)(.)/ + a\xc0\x92bcd + +/a(.??)(.)/8 + a\x{240}bcd + +/a(.{3})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + *** Failers + a\x{1234}b + ac\ncb + +/a(.{3,})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers + a\x{1234}b + +/a(.{3,}?)b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers + a\x{1234}b + +/a(.{3,5})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + axxxxxbcdefghijb + *** Failers + a\x{1234}b + axxxxxxbcdefghijb + +/a(.{3,5}?)b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + axxxxxbcdefghijb + *** Failers + a\x{1234}b + axxxxxxbcdefghijb + +/^[a\x{c0}]/8 + *** Failers + \x{100} + +/(?<=aXb)cd/8 + aXbcd + +/(?<=a\x{100}b)cd/8 + a\x{100}bcd + +/(?<=a\x{100000}b)cd/8 + a\x{100000}bcd + +/(?:\x{100}){3}b/8 + \x{100}\x{100}\x{100}b + *** Failers + \x{100}\x{100}b + +/\x{ab}/8 + \x{ab} + \xc2\xab + *** Failers + \x00{ab} + +/(?<=(.))X/8 + WXYZ + \x{256}XYZ + *** Failers + XYZ + +/[^a]+/8g + bcd + \x{100}aY\x{256}Z + +/^[^a]{2}/8 + \x{100}bc + +/^[^a]{2,}/8 + \x{100}bcAa + +/^[^a]{2,}?/8 + \x{100}bca + +/[^a]+/8ig + bcd + \x{100}aY\x{256}Z + +/^[^a]{2}/8i + \x{100}bc + +/^[^a]{2,}/8i + \x{100}bcAa + +/^[^a]{2,}?/8i + \x{100}bca + +/\x{100}{0,0}/8 + abcd + +/\x{100}?/8 + abcd + \x{100}\x{100} + +/\x{100}{0,3}/8 + \x{100}\x{100} + \x{100}\x{100}\x{100}\x{100} + +/\x{100}*/8 + abce + \x{100}\x{100}\x{100}\x{100} + +/\x{100}{1,1}/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}{1,3}/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}+/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}{3}/8 + abcd\x{100}\x{100}\x{100}XX + +/\x{100}{3,5}/8 + abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX + +/\x{100}{3,}/8 + abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX + +/(?<=a\x{100}{2}b)X/8 + Xyyya\x{100}\x{100}bXzzz + +/\D*/8 + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/\D*/8 + \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + +/\D/8 + 1X2 + 1\x{100}2 + +/>\S/8 + > >X Y + > >\x{100} Y + +/\d/8 + \x{100}3 + +/\s/8 + \x{100} X + +/\D+/8 + 12abcd34 + *** Failers + 1234 + +/\D{2,3}/8 + 12abcd34 + 12ab34 + *** Failers + 1234 + 12a34 + +/\D{2,3}?/8 + 12abcd34 + 12ab34 + *** Failers + 1234 + 12a34 + +/\d+/8 + 12abcd34 + *** Failers + +/\d{2,3}/8 + 12abcd34 + 1234abcd + *** Failers + 1.4 + +/\d{2,3}?/8 + 12abcd34 + 1234abcd + *** Failers + 1.4 + +/\S+/8 + 12abcd34 + *** Failers + \ \ + +/\S{2,3}/8 + 12abcd34 + 1234abcd + *** Failers + \ \ + +/\S{2,3}?/8 + 12abcd34 + 1234abcd + *** Failers + \ \ + +/>\s+ <34 + *** Failers + +/>\s{2,3} \s{2,3}? \xff< + +/[\xff]/8 + >\x{ff}< + +/[^\xFF]/ + XYZ + +/[^\xff]/8 + XYZ + \x{123} + +/^[ac]*b/8 + xb + +/^[ac\x{100}]*b/8 + xb + +/^[^x]*b/8i + xb + +/^[^x]*b/8 + xb + +/^\d*b/8 + xb + +/(|a)/g8 + catac + a\x{256}a + +/^\x{85}$/8i + \x{85} + +/^abc./mgx8 + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK + +/abc.$/mgx8 + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 + +/^a\Rb/8 + a\nb + a\rb + a\r\nb + a\x0bb + a\x0cb + a\x{85}b + a\x{2028}b + a\x{2029}b + ** Failers + a\n\rb + +/^a\R*b/8 + ab + a\nb + a\rb + a\r\nb + a\x0bb + a\x0c\x{2028}\x{2029}b + a\x{85}b + a\n\rb + a\n\r\x{85}\x0cb + +/^a\R+b/8 + a\nb + a\rb + a\r\nb + a\x0bb + a\x0c\x{2028}\x{2029}b + a\x{85}b + a\n\rb + a\n\r\x{85}\x0cb + ** Failers + ab + +/^a\R{1,3}b/8 + a\nb + a\n\rb + a\n\r\x{85}b + a\r\n\r\nb + a\r\n\r\n\r\nb + a\n\r\n\rb + a\n\n\r\nb + ** Failers + a\n\n\n\rb + a\r + +/\h+\V?\v{3,4}/8 + \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + +/\V?\v{3,4}/8 + \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + +/\h+\V?\v{3,4}/8 + >\x09\x20\x{a0}X\x0a\x0a\x0a< + +/\V?\v{3,4}/8 + >\x09\x20\x{a0}X\x0a\x0a\x0a< + +/\H\h\V\v/8 + X X\x0a + X\x09X\x0b + ** Failers + \x{a0} X\x0a + +/\H*\h+\V?\v{3,4}/8 + \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a + \x09\x20\x{a0}\x0a\x0b\x0c + ** Failers + \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\ + +/X/8f + A\x{1ec5}ABCXYZ + +/abcd*/8 + xxxxabcd\P + xxxxabcd\P\P + +/abcd*/i8 + xxxxabcd\P + xxxxabcd\P\P + XXXXABCD\P + XXXXABCD\P\P + +/abc\d*/8 + xxxxabc1\P + xxxxabc1\P\P + +/abc[de]*/8 + xxxxabcde\P + xxxxabcde\P\P + +/\bthe cat\b/8 + the cat\P + the cat\P\P + +/ab\Cde/8 + abXde + +/(?<=ab\Cde)X/8 + +/./8 + \r\P + \r\P\P + +/.{2,3}/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/[^\x{100}]/8 + \x{100}\x{101}X + +/[^\x{100}]+/8 + \x{100}\x{101}X + +/-- End of testinput9 --/ diff --git a/tools/pcre/testdata/testinputEBC b/tools/pcre/testdata/testinputEBC new file mode 100644 index 00000000..56efcd00 --- /dev/null +++ b/tools/pcre/testdata/testinputEBC @@ -0,0 +1,121 @@ +/-- This is a specialized test for checking, when PCRE is compiled with the +EBCDIC option but in an ASCII environment, that newline and white space +functionality is working. It catches cases where explicit values such as 0x0a +have been used instead of names like CHAR_LF. Needless to say, it is not a +genuine EBCDIC test! In patterns, alphabetic characters that follow a backslash +must be in EBCDIC code. In data, newlines and other spacing characters must be +in EBCDIC, but can be specified as escapes. --/ + +/-- Test default newline and variations --/ + +/^A/m + ABC + 12\x15ABC + +/^A/m + 12\x15ABC + 12\x0dABC + 12\x0d\x15ABC + 12\x25ABC + +/^A/m + 12\x15ABC + 12\x0dABC + 12\x0d\x15ABC + ** Fail + 12\x25ABC + +/-- Test \h --/ + +/^A\ˆ/ + A B + +/-- Test \H --/ + +/^A\È/ + AB + ** Fail + A B + +/-- Test \R --/ + +/^A\Ù/ + A\x15B + A\x0dB + A\x25B + A\x0bB + A\x0cB + ** Fail + A B + +/-- Test \v --/ + +/^A\¥/ + A\x15B + A\x0dB + A\x25B + A\x0bB + A\x0cB + ** Fail + A B + +/-- Test \V --/ + +/^A\å/ + A B + ** Fail + A\x15B + A\x0dB + A\x25B + A\x0bB + A\x0cB + +/-- For repeated items, use an atomic group so that the output is the same +for DFA matching (otherwise it may show multiple matches). --/ + +/-- Test \h+ --/ + +/^A(?>\ˆ+)/ + A B + +/-- Test \H+ --/ + +/^A(?>\È+)/ + AB + ** Fail + A B + +/-- Test \R+ --/ + +/^A(?>\Ù+)/ + A\x15B + A\x0dB + A\x25B + A\x0bB + A\x0cB + ** Fail + A B + +/-- Test \v+ --/ + +/^A(?>\¥+)/ + A\x15B + A\x0dB + A\x25B + A\x0bB + A\x0cB + ** Fail + A B + +/-- Test \V+ --/ + +/^A(?>\å+)/ + A B + ** Fail + A\x15B + A\x0dB + A\x25B + A\x0bB + A\x0cB + +/-- End --/ diff --git a/tools/pcre/testdata/testoutput1 b/tools/pcre/testdata/testoutput1 new file mode 100644 index 00000000..8310e946 --- /dev/null +++ b/tools/pcre/testdata/testoutput1 @@ -0,0 +1,8798 @@ +/-- This set of tests is for features that are compatible with all versions of + Perl >= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and + 16-bit PCRE libraries. --/ + +/the quick brown fox/ + the quick brown fox + 0: the quick brown fox + The quick brown FOX +No match + What do you know about the quick brown fox? + 0: the quick brown fox + What do you know about THE QUICK BROWN FOX? +No match + +/The quick brown fox/i + the quick brown fox + 0: the quick brown fox + The quick brown FOX + 0: The quick brown FOX + What do you know about the quick brown fox? + 0: the quick brown fox + What do you know about THE QUICK BROWN FOX? + 0: THE QUICK BROWN FOX + +/abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/ + abcd\t\n\r\f\a\e9;\$\\?caxyz + 0: abcd\x09\x0a\x0d\x0c\x07\x1b9;$\?caxyz + +/a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ + abxyzpqrrrabbxyyyypqAzz + 0: abxyzpqrrrabbxyyyypqAzz + abxyzpqrrrabbxyyyypqAzz + 0: abxyzpqrrrabbxyyyypqAzz + aabxyzpqrrrabbxyyyypqAzz + 0: aabxyzpqrrrabbxyyyypqAzz + aaabxyzpqrrrabbxyyyypqAzz + 0: aaabxyzpqrrrabbxyyyypqAzz + aaaabxyzpqrrrabbxyyyypqAzz + 0: aaaabxyzpqrrrabbxyyyypqAzz + abcxyzpqrrrabbxyyyypqAzz + 0: abcxyzpqrrrabbxyyyypqAzz + aabcxyzpqrrrabbxyyyypqAzz + 0: aabcxyzpqrrrabbxyyyypqAzz + aaabcxyzpqrrrabbxyyyypAzz + 0: aaabcxyzpqrrrabbxyyyypAzz + aaabcxyzpqrrrabbxyyyypqAzz + 0: aaabcxyzpqrrrabbxyyyypqAzz + aaabcxyzpqrrrabbxyyyypqqAzz + 0: aaabcxyzpqrrrabbxyyyypqqAzz + aaabcxyzpqrrrabbxyyyypqqqAzz + 0: aaabcxyzpqrrrabbxyyyypqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqAzz + 0: aaabcxyzpqrrrabbxyyyypqqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqqAzz + 0: aaabcxyzpqrrrabbxyyyypqqqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqqqAzz + 0: aaabcxyzpqrrrabbxyyyypqqqqqqAzz + aaaabcxyzpqrrrabbxyyyypqAzz + 0: aaaabcxyzpqrrrabbxyyyypqAzz + abxyzzpqrrrabbxyyyypqAzz + 0: abxyzzpqrrrabbxyyyypqAzz + aabxyzzzpqrrrabbxyyyypqAzz + 0: aabxyzzzpqrrrabbxyyyypqAzz + aaabxyzzzzpqrrrabbxyyyypqAzz + 0: aaabxyzzzzpqrrrabbxyyyypqAzz + aaaabxyzzzzpqrrrabbxyyyypqAzz + 0: aaaabxyzzzzpqrrrabbxyyyypqAzz + abcxyzzpqrrrabbxyyyypqAzz + 0: abcxyzzpqrrrabbxyyyypqAzz + aabcxyzzzpqrrrabbxyyyypqAzz + 0: aabcxyzzzpqrrrabbxyyyypqAzz + aaabcxyzzzzpqrrrabbxyyyypqAzz + 0: aaabcxyzzzzpqrrrabbxyyyypqAzz + aaaabcxyzzzzpqrrrabbxyyyypqAzz + 0: aaaabcxyzzzzpqrrrabbxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyypqAzz + 0: aaaabcxyzzzzpqrrrabbbxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyyypqAzz + 0: aaaabcxyzzzzpqrrrabbbxyyyyypqAzz + aaabcxyzpqrrrabbxyyyypABzz + 0: aaabcxyzpqrrrabbxyyyypABzz + aaabcxyzpqrrrabbxyyyypABBzz + 0: aaabcxyzpqrrrabbxyyyypABBzz + >>>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 + 1: abc + abcabczz + 0: abcabczz + 1: abc + *** Failers +No match + zz +No match + abcabcabczz +No match + >>abczz +No match + +/^(b+?|a){1,2}?c/ + bc + 0: bc + 1: b + bbc + 0: bbc + 1: b + bbbc + 0: bbbc + 1: bb + bac + 0: bac + 1: a + bbac + 0: bbac + 1: a + aac + 0: aac + 1: a + abbbbbbbbbbbc + 0: abbbbbbbbbbbc + 1: bbbbbbbbbbb + bbbbbbbbbbbac + 0: bbbbbbbbbbbac + 1: a + *** Failers +No match + aaac +No match + abbbbbbbbbbbac +No match + +/^(b+|a){1,2}c/ + bc + 0: bc + 1: b + bbc + 0: bbc + 1: bb + bbbc + 0: bbbc + 1: bbb + bac + 0: bac + 1: a + bbac + 0: bbac + 1: a + aac + 0: aac + 1: a + abbbbbbbbbbbc + 0: abbbbbbbbbbbc + 1: bbbbbbbbbbb + bbbbbbbbbbbac + 0: bbbbbbbbbbbac + 1: a + *** Failers +No match + aaac +No match + abbbbbbbbbbbac +No match + +/^(b+|a){1,2}?bc/ + bbc + 0: bbc + 1: b + +/^(b*|ba){1,2}?bc/ + babc + 0: babc + 1: ba + bbabc + 0: bbabc + 1: ba + bababc + 0: bababc + 1: ba + *** Failers +No match + bababbc +No match + babababc +No match + +/^(ba|b*){1,2}?bc/ + babc + 0: babc + 1: ba + bbabc + 0: bbabc + 1: ba + bababc + 0: bababc + 1: ba + *** 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 + 1: abc + 2: pqr + *** 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 + 1: 0abc + abc + 0: abc + 1: abc + fed + 0: fed + 1: fed + E + 0: E + 1: E + :: + 0: :: + 1: :: + 5f03:12C0::932e + 0: 5f03:12C0::932e + 1: 5f03:12C0::932e + fed def + 0: def + 1: def + Any old stuff + 0: ff + 1: 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 + 1: 1 + 2: 2 + 3: 3 + A.12.123.0 + 0: A.12.123.0 + 1: 12 + 2: 123 + 3: 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: 1 + 2: non-sp1 + 3: non-sp2 + 1 IN SOA non-sp1 non-sp2 ( + 0: 1 IN SOA non-sp1 non-sp2 ( + 1: 1 + 2: non-sp1 + 3: 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. + 1: .pq-r + sxk.zzz.ac.uk. + 0: sxk.zzz.ac.uk. + 1: .uk + x-.y-. + 0: x-.y-. + 1: .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 + 1: 0-a + *.c3-b.c + 0: *.c3-b.c + 1: 3-b + 2: .c + *.c-a.b-c + 0: *.c-a.b-c + 1: -a + 2: .b-c + 3: -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 + 1: de + 2: abd + 3: e + +/^(?!(ab)de|x)(abd)(f)/ + abdf + 0: abdf + 1: + 2: abd + 3: f + +/^(?=(ab(cd)))(ab)/ + abcd + 0: ab + 1: abcd + 2: cd + 3: ab + +/^[\da-f](\.[\da-f])*$/i + a.b.c.d + 0: a.b.c.d + 1: .d + A.B.C.D + 0: A.B.C.D + 1: .D + a.b.c.1.2.3.C + 0: a.b.c.1.2.3.C + 1: .C + +/^\".*\"\s*(;.*)?$/ + \"1234\" + 0: "1234" + \"abcd\" ; + 0: "abcd" ; + 1: ; + \"\" ; rhubarb + 0: "" ; rhubarb + 1: ; 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 + 1: abc + 2: bc + 3: c + 4: def + 5: ef + 6: f + 7: hij + 8: ij + 9: j +10: klm +11: lm +12: m + +/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ + abcdefhijklm + 0: abcdefhijklm + 1: bc + 2: c + 3: ef + 4: f + 5: ij + 6: j + 7: lm + 8: m + +/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ + a+ Z0+\x08\n\x1d\x12 + 0: a+ Z0+\x08\x0a\x1d\x12 + +/^[.^$|()*+?{,}]+/ + .^\$(*+)|{?,?} + 0: .^$(*+)|{?,?} + +/^a*\w/ + z + 0: z + az + 0: az + aaaz + 0: aaaz + a + 0: a + aa + 0: aa + aaaa + 0: aaaa + a+ + 0: a + aa+ + 0: aa + +/^a*?\w/ + z + 0: z + az + 0: a + aaaz + 0: a + a + 0: a + aa + 0: a + aaaa + 0: a + a+ + 0: a + aa+ + 0: a + +/^a+\w/ + az + 0: az + aaaz + 0: aaaz + aa + 0: aa + aaaa + 0: aaaa + aa+ + 0: aa + +/^a+?\w/ + az + 0: az + aaaz + 0: aa + aa + 0: aa + aaaa + 0: 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: 1234 + aaaaa + 0: aaaa + 123456 + 0: 1234 + +/\A(abc|def)=(\1){2,3}\Z/ + abc=abcabc + 0: abc=abcabc + 1: abc + 2: abc + def=defdefdef + 0: def=defdefdef + 1: def + 2: def + *** Failers +No match + abc=defdef +No match + +/^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/ + abcdefghijkcda2 + 0: abcdefghijkcda2 + 1: a + 2: b + 3: c + 4: d + 5: e + 6: f + 7: g + 8: h + 9: i +10: j +11: k +12: cd + abcdefghijkkkkcda2 + 0: abcdefghijkkkkcda2 + 1: a + 2: b + 3: c + 4: d + 5: e + 6: f + 7: g + 8: h + 9: i +10: j +11: k +12: cd + +/(cat(a(ract|tonic)|erpillar)) \1()2(3)/ + cataract cataract23 + 0: cataract cataract23 + 1: cataract + 2: aract + 3: ract + 4: + 5: 3 + catatonic catatonic23 + 0: catatonic catatonic23 + 1: catatonic + 2: atonic + 3: tonic + 4: + 5: 3 + caterpillar caterpillar23 + 0: caterpillar caterpillar23 + 1: caterpillar + 2: erpillar + 3: + 4: + 5: 3 + + +/^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 + 1: abcd + +/^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 + 1: Sep + From abcd Mon Sep 1 12:33:02 1997 + 0: From abcd Mon Sep 1 12:33 + 1: Sep + *** 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: lish see? + +/(?:(?!foo)...|^.{0,2})bar(.*)/ + foobar crowbar etc + 0: rowbar etc + 1: etc + barrel + 0: barrel + 1: rel + 2barrel + 0: 2barrel + 1: rel + A barrel + 0: A barrel + 1: rel + +/^(\D*)(?=\d)(?!123)/ + abc456 + 0: abc + 1: 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 + +/^(a)\1{2,3}(.)/ + aaab + 0: aaab + 1: a + 2: b + aaaab + 0: aaaab + 1: a + 2: b + aaaaab + 0: aaaaa + 1: a + 2: a + aaaaaab + 0: aaaaa + 1: a + 2: a + +/(?!^)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: aabb + 1: b + +/^[ab]{1,3}?(ab*|b)/ + aabbbbb + 0: aabbbbb + 1: abbbbb + +/^[ab]{1,3}?(ab*?|b)/ + aabbbbb + 0: aa + 1: a + +/^[ab]{1,3}(ab*?|b)/ + aabbbbb + 0: aabb + 1: b + +/ (?: [\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 + user\@dom.ain + 0: user@dom.ain + \"A. Other\" (a comment) + 0: "A. Other" (a comment) + A. Other (a comment) + 0: Other (a comment) + \"/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 + 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 + user\@dom.ain + 0: user@dom.ain + \"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 + A missing angle ?@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: .23 + 1.875000282 + 0: .875000282 + 1: .875 + 1.235 + 0: .235 + 1: .23 + +/(\.\d\d((?=0)|\d(?=\d)))/ + 1.230003938 + 0: .23 + 1: .23 + 2: + 1.875000282 + 0: .875 + 1: .875 + 2: 5 + *** 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 + 2: table + +/foo(.*)bar/ + The food is under the bar in the barn. + 0: food is under the bar in the bar + 1: d is under the bar in the + +/foo(.*?)bar/ + The food is under the bar in the barn. + 0: food is under the bar + 1: d is under the + +/(.*)(\d*)/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 53147 + 2: + +/(.*)(\d+)/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 5314 + 2: 7 + +/(.*?)(\d*)/ + I have 2 numbers: 53147 + 0: + 1: + 2: + +/(.*?)(\d+)/ + I have 2 numbers: 53147 + 0: I have 2 + 1: I have + 2: 2 + +/(.*)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 5314 + 2: 7 + +/(.*?)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: + 2: 53147 + +/(.*)\b(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: + 2: 53147 + +/(.*\D)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: + 2: 53147 + +/^\D*(?!123)/ + ABC123 + 0: AB + +/^(\D*)(?=\d)(?!123)/ + ABC445 + 0: ABC + 1: 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: a + aab + 0: a + 1: a + +/^(a){0,2}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: aa + 1: a + +/^(a){0,3}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + +/^(a){0,}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + aaaaaaaa + 0: aaaaaaaa + 1: a + +/^(a){1,1}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: a + 1: a + +/^(a){1,2}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: aa + 1: a + +/^(a){1,3}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + +/^(a){1,}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + aaaaaaaa + 0: aaaaaaaa + 1: 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 + +/.*$/ + 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 + +/.*$/ms + borfle\nbib.gif\nno\n + 0: borfle\x0abib.gif\x0ano\x0a + +/(.*X|^B)/ + abcde\n1234Xyz + 0: 1234X + 1: 1234X + BarFoo + 0: B + 1: B + *** Failers +No match + abcde\nBar +No match + +/(.*X|^B)/m + abcde\n1234Xyz + 0: 1234X + 1: 1234X + BarFoo + 0: B + 1: B + abcde\nBar + 0: B + 1: B + +/(.*X|^B)/s + abcde\n1234Xyz + 0: abcde\x0a1234X + 1: abcde\x0a1234X + BarFoo + 0: B + 1: B + *** Failers +No match + abcde\nBar +No match + +/(.*X|^B)/ms + abcde\n1234Xyz + 0: abcde\x0a1234X + 1: abcde\x0a1234X + BarFoo + 0: B + 1: B + abcde\nBar + 0: B + 1: B + +/(?s)(.*X|^B)/ + abcde\n1234Xyz + 0: abcde\x0a1234X + 1: abcde\x0a1234X + BarFoo + 0: B + 1: 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 + 1: c + +/^[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 + 1: + ab + 0: ab + 1: b + abbbb + 0: abbbb + 1: bbbb + *** Failers + 0: a + 1: + bbbbb +No match + +/ab\d{0}e/ + abe + 0: abe + *** Failers +No match + ab1e +No match + +/"([^\\"]+|\\.)*"/ + the \"quick\" brown fox + 0: "quick" + 1: quick + \"the \\\"quick\\\" brown fox\" + 0: "the \"quick\" brown fox" + 1: brown fox + +/.*?/g+ + abc + 0: + 0+ abc + 0: a + 0+ bc + 0: + 0+ bc + 0: b + 0+ c + 0: + 0+ c + 0: c + 0+ + 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 + 1: BGCOLOR='#DBE9E9' + 2: align=left valign=top + 3: 43. + 4: Word Processor
(N-1286) + 5: + 6: + 7: + 8: align=left valign=top + 9: Lega lstaff.com +10: align=left valign=top +11: CA - 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 + 1: a + bbac + 0: bbac + 1: a + bbbac + 0: bbbac + 1: a + bbbbac + 0: bbbbac + 1: a + bbbbbac + 0: bbbbbac + 1: a + +/^(b+|a){1,2}?c/ + bac + 0: bac + 1: a + bbac + 0: bbac + 1: a + bbbac + 0: bbbac + 1: a + bbbbac + 0: bbbbac + 1: a + bbbbbac + 0: bbbbbac + 1: a + +/(?!\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 + +/(AB)*?\1/ + ABABAB + 0: ABAB + 1: AB + +/(AB)*\1/ + ABABAB + 0: ABABAB + 1: AB + +/(?.*/)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: .23 + 1.875000282 + 0: .875000282 + 1: .875 + *** 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 + 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 + 12345+ + 0: 12345 + 1: 1234 + 2: 5 + +/((?>\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 + +/(?>b)+/ + aaabbbccc + 0: bbb + +/(?>a+|b+|c+)*c/ + aaabbbbccccd + 0: aaabbbbc + +/((?>[^()]+)|\([^()]*\))+/ + ((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 + +/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 + 1: a bc + *** 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 + 1: a bcde f + *** Failers +No match + abcdef +No match + +/(a(?i)b)c/ + abc + 0: abc + 1: ab + aBc + 0: aBc + 1: aB + *** 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 + 1: xx + aBxxc + 0: xxc + 1: xx + *** Failers +No match + Abxxc +No match + ABxxc +No match + abxxC +No match + +/(?:(a)|b)(?(1)A|B)/ + aA + 0: aA + 1: a + bB + 0: bB + *** Failers +No match + aB +No match + bA +No match + +/^(a)?(?(1)a|b)+$/ + aa + 0: aa + 1: a + b + 0: b + bb + 0: bb + *** Failers +No match + ab +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 + aa + 0: aa + aaaa + 0: aaaa + +/(abc|)+/ + abc + 0: abc + 1: + abcabc + 0: abcabc + 1: + abcabcabc + 0: abcabcabc + 1: + xyz + 0: + 1: + +/([a]*)*/ + a + 0: a + 1: + aaaaa + 0: aaaaa + 1: + +/([ab]*)*/ + a + 0: a + 1: + b + 0: b + 1: + ababab + 0: ababab + 1: + aaaabcde + 0: aaaab + 1: + bbbb + 0: bbbb + 1: + +/([^a]*)*/ + b + 0: b + 1: + bbbb + 0: bbbb + 1: + aaa + 0: + 1: + +/([^ab]*)*/ + cccc + 0: cccc + 1: + abab + 0: + 1: + +/([a]*?)*/ + a + 0: + 1: + aaaa + 0: + 1: + +/([ab]*?)*/ + a + 0: + 1: + b + 0: + 1: + abab + 0: + 1: + baba + 0: + 1: + +/([^a]*?)*/ + b + 0: + 1: + bbbb + 0: + 1: + aaa + 0: + 1: + +/([^ab]*?)*/ + c + 0: + 1: + cccc + 0: + 1: + baba + 0: + 1: + +/(?>a*)*/ + a + 0: a + aaabcde + 0: aaa + +/((?>a*))*/ + aaaaa + 0: aaaaa + 1: + aabbaa + 0: aa + 1: + +/((?>a*?))*/ + aaaaa + 0: + 1: + aabbaa + 0: + 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 + +/(?<=(foo))bar\1/ + foobarfoo + 0: barfoo + 1: foo + foobarfootling + 0: barfoo + 1: foo + *** Failers +No match + foobar +No match + barfoo +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 + 1: abc + aBCx + 0: aBCx + 1: aBC + bbx + 0: bbx + 1: bb + BBx + 0: BBx + 1: BB + *** Failers +No match + abcX +No match + aBCX +No match + bbX +No match + BBX +No match + +/^([ab](?i)[cd]|[ef])/ + ac + 0: ac + 1: ac + aC + 0: aC + 1: aC + bD + 0: bD + 1: bD + elephant + 0: e + 1: e + Europe + 0: E + 1: E + frog + 0: f + 1: f + France + 0: F + 1: F + *** Failers +No match + Africa +No match + +/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ + ab + 0: ab + 1: ab + aBd + 0: aBd + 1: aBd + xy + 0: xy + 1: xy + xY + 0: xY + 1: xY + zebra + 0: z + 1: z + Zambesi + 0: Z + 1: 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: <& + +/^(a\1?){4}$/ + aaaaaaaaaa + 0: aaaaaaaaaa + 1: aaaa + *** Failers +No match + AB +No match + aaaaaaaaa +No match + aaaaaaaaaaa +No match + +/^(a(?(1)\1)){4}$/ + aaaaaaaaaa + 0: aaaaaaaaaa + 1: aaaa + *** Failers +No match + aaaaaaaaa +No match + aaaaaaaaaaa +No match + +/(?:(f)(o)(o)|(b)(a)(r))*/ + foobar + 0: foobar + 1: f + 2: o + 3: o + 4: b + 5: a + 6: r + +/(?<=a)b/ + ab + 0: b + *** Failers +No match + cb +No match + b +No match + +/(? + 2: abcd + xy:z:::abcd + 0: xy:z:::abcd + 1: xy:z::: + 2: abcd + +/^[^bcd]*(c+)/ + aexycd + 0: aexyc + 1: c + +/(a*)b+/ + caab + 0: aab + 1: aa + +/([\w:]+::)?(\w+)$/ + abcd + 0: abcd + 1: + 2: abcd + xy:z:::abcd + 0: xy:z:::abcd + 1: xy:z::: + 2: abcd + *** Failers + 0: Failers + 1: + 2: Failers + abcd: +No match + abcd: +No match + +/^[^bcd]*(c+)/ + aexycd + 0: aexyc + 1: c + +/(>a+)ab/ + +/(?>a+)b/ + aaab + 0: aaab + +/([[:]+)/ + a:[b]: + 0: :[ + 1: :[ + +/([[=]+)/ + a=[b]= + 0: =[ + 1: =[ + +/([[.]+)/ + a.[b]. + 0: .[ + 1: .[ + +/((?>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 + +/a\Z/ + *** Failers +No match + aaab +No match + a\nb\n +No match + +/b\Z/ + a\nb\n + 0: b + +/b\z/ + +/b\Z/ + a\nb + 0: b + +/b\z/ + a\nb + 0: b + *** Failers +No match + +/^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/ + a + 0: a + 1: + abc + 0: abc + 1: + a-b + 0: a-b + 1: + 0-9 + 0: 0-9 + 1: + a.b + 0: a.b + 1: + 5.6.7 + 0: 5.6.7 + 1: + the.quick.brown.fox + 0: the.quick.brown.fox + 1: + a100.b200.300c + 0: a100.b200.300c + 1: + 12-ab.1245 + 0: 12-ab.1245 + 1: + *** Failers +No match + \ +No match + .a +No match + -a +No match + a- +No match + a. +No match + a_b +No match + a.- +No match + a.. +No match + ab..bc +No match + the.quick.brown.fox- +No match + the.quick.brown.fox. +No match + the.quick.brown.fox_ +No match + the.quick.brown.fox+ +No match + +/(?>.*)(?<=(abcd|wxyz))/ + alphabetabcd + 0: alphabetabcd + 1: abcd + endingwxyz + 0: endingwxyz + 1: wxyz + *** Failers +No match + a rather long string that doesn't end with one of them +No match + +/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark +No match + +/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 + +/(?<=\d{3}(?!999))foo/ + 999foo + 0: foo + 123999foo + 0: foo + *** Failers +No match + 123abcfoo +No match + +/(?<=(?!...999)\d{3})foo/ + 999foo + 0: foo + 123999foo + 0: foo + *** Failers +No match + 123abcfoo +No match + +/(?<=\d{3}(?!999)...)foo/ + 123abcfoo + 0: foo + 123456foo + 0: foo + *** Failers +No match + 123999foo +No match + +/(?<=\d{3}...)(? + 2: + 3: abcd +
+ 2: + 3: abcd + \s*)=(?>\s*) # find + 2: + 3: abcd + Z)+|A)*/ + ZABCDEFG + 0: ZA + 1: A + +/((?>)+|A)*/ + ZABCDEFG + 0: + 1: + +/a*/g + abbab + 0: a + 0: + 0: + 0: a + 0: + 0: + +/^[a-\d]/ + abcde + 0: a + -things + 0: - + 0digit + 0: 0 + *** Failers +No match + bcdef +No match + +/^[\d-a]/ + abcde + 0: a + -things + 0: - + 0digit + 0: 0 + *** Failers +No match + bcdef +No match + +/[[:space:]]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d\x0b + +/[[:blank:]]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09 + +/[\s]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d + +/\s+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d + +/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 + 1: abc + AxyzB + 0: xyz + 1: xyz + +/(?i)AB(?-i)C/ + XabCY + 0: abC + *** Failers +No match + XabcY +No match + +/((?i)AB(?-i)C|D)E/ + abCE + 0: abCE + 1: abC + DE + 0: DE + 1: D + *** Failers +No match + abcE +No match + abCe +No match + dE +No match + De +No match + +/(.*)\d+\1/ + abc123abc + 0: abc123abc + 1: abc + abc123bc + 0: bc123bc + 1: bc + +/(.*)\d+\1/s + abc123abc + 0: abc123abc + 1: abc + abc123bc + 0: bc123bc + 1: bc + +/((.*))\d+\1/ + abc123abc + 0: abc123abc + 1: abc + 2: abc + abc123bc + 0: bc123bc + 1: bc + 2: bc + +/-- This tests for an IPv6 address in the form where it can have up to --/ +/-- eight components, one and only one of which is empty. This must be --/ +No match +/-- an internal component. --/ +No match + +/^(?!:) # colon disallowed at start + (?: # start of item + (?: [0-9a-f]{1,4} | # 1-4 hex digits or + (?(1)0 | () ) ) # if null previously matched, fail; else null + : # followed by colon + ){1,7} # end item; 1-7 of them required + [0-9a-f]{1,4} $ # final hex number at end of string + (?(1)|.) # check that there was an empty component + /xi + a123::a123 + 0: a123::a123 + 1: + a123:b342::abcd + 0: a123:b342::abcd + 1: + a123:b342::324e:abcd + 0: a123:b342::324e:abcd + 1: + a123:ddde:b342::324e:abcd + 0: a123:ddde:b342::324e:abcd + 1: + a123:ddde:b342::324e:dcba:abcd + 0: a123:ddde:b342::324e:dcba:abcd + 1: + a123:ddde:9999:b342::324e:dcba:abcd + 0: a123:ddde:9999:b342::324e:dcba:abcd + 1: + *** Failers +No match + 1:2:3:4:5:6:7:8 +No match + a123:bce:ddde:9999:b342::324e:dcba:abcd +No match + a123::9999:b342::324e:dcba:abcd +No match + abcde:2:3:4:5:6:7:8 +No match + ::1 +No match + abcd:fee0:123:: +No match + :1 +No match + 1: +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 + +/ab cd (?x) de fg/ + ab cd defg + 0: ab cd defg + +/ab cd(?x) de fg/ + ab cddefg + 0: ab cddefg + ** Failers +No match + abcddefg +No match + +/(? + 2: + D + 0: D + 1: + 2: + +/(a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 1: + +/(?>a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?:a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/\Z/g + abc\n + 0: + 0: + +/^(?s)(?>.*)(? + 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: + +/(?>.*?a)(?<=ba)/ + aba + 0: ba + +/(?:.*?a)(?<=ba)/ + aba + 0: aba + +/.*?a(*PRUNE)b/ + aab + 0: ab + +/.*?a(*PRUNE)b/s + aab + 0: ab + +/^a(*PRUNE)b/s + aab +No match + +/.*?a(*SKIP)b/ + aab + 0: ab + +/(?>.*?a)b/s + aab + 0: ab + +/(?>.*?a)b/ + aab + 0: ab + +/(?>^a)b/s + aab +No match + +/(?>.*?)(?<=(abcd)|(wxyz))/ + alphabetabcd + 0: + 1: abcd + endingwxyz + 0: + 1: + 2: wxyz + +/(?>.*)(?<=(abcd)|(wxyz))/ + alphabetabcd + 0: alphabetabcd + 1: abcd + endingwxyz + 0: endingwxyz + 1: + 2: wxyz + +"(?>.*)foo" + abcdfooxyz +No match + +"(?>.*?)foo" + abcdfooxyz + 0: foo + +/-- End of testinput1 --/ diff --git a/tools/pcre/testdata/testoutput10 b/tools/pcre/testdata/testoutput10 new file mode 100644 index 00000000..049d4463 --- /dev/null +++ b/tools/pcre/testdata/testoutput10 @@ -0,0 +1,2726 @@ +/-- 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} + 0: \x{300}\x{301}\x{302} + +/\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: \x{300}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 + 0: \x{300}abc + +/\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: \x{300}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 + 0: \x{300}abc + +/^\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 + +/-- These are tests for extended grapheme clusters --/ + +/^\X/8+ + G\x{34e}\x{34e}X + 0: G\x{34e}\x{34e} + 0+ X + \x{34e}\x{34e}X + 0: \x{34e}\x{34e} + 0+ X + \x04X + 0: \x{04} + 0+ X + \x{1100}X + 0: \x{1100} + 0+ X + \x{1100}\x{34e}X + 0: \x{1100}\x{34e} + 0+ X + \x{1b04}\x{1b04}X + 0: \x{1b04}\x{1b04} + 0+ X + *These match up to the roman letters + 0: * + 0+ These match up to the roman letters + \x{1111}\x{1111}L,L + 0: \x{1111}\x{1111} + 0+ L,L + \x{1111}\x{1111}\x{1169}L,L,V + 0: \x{1111}\x{1111}\x{1169} + 0+ L,L,V + \x{1111}\x{ae4c}L, LV + 0: \x{1111}\x{ae4c} + 0+ L, LV + \x{1111}\x{ad89}L, LVT + 0: \x{1111}\x{ad89} + 0+ L, LVT + \x{1111}\x{ae4c}\x{1169}L, LV, V + 0: \x{1111}\x{ae4c}\x{1169} + 0+ L, LV, V + \x{1111}\x{ae4c}\x{1169}\x{1169}L, LV, V, V + 0: \x{1111}\x{ae4c}\x{1169}\x{1169} + 0+ L, LV, V, V + \x{1111}\x{ae4c}\x{1169}\x{11fe}L, LV, V, T + 0: \x{1111}\x{ae4c}\x{1169}\x{11fe} + 0+ L, LV, V, T + \x{1111}\x{ad89}\x{11fe}L, LVT, T + 0: \x{1111}\x{ad89}\x{11fe} + 0+ L, LVT, T + \x{1111}\x{ad89}\x{11fe}\x{11fe}L, LVT, T, T + 0: \x{1111}\x{ad89}\x{11fe}\x{11fe} + 0+ L, LVT, T, T + \x{ad89}\x{11fe}\x{11fe}LVT, T, T + 0: \x{ad89}\x{11fe}\x{11fe} + 0+ LVT, T, T + *These match just the first codepoint (invalid sequence) + 0: * + 0+ These match just the first codepoint (invalid sequence) + \x{1111}\x{11fe}L, T + 0: \x{1111} + 0+ \x{11fe}L, T + \x{ae4c}\x{1111}LV, L + 0: \x{ae4c} + 0+ \x{1111}LV, L + \x{ae4c}\x{ae4c}LV, LV + 0: \x{ae4c} + 0+ \x{ae4c}LV, LV + \x{ae4c}\x{ad89}LV, LVT + 0: \x{ae4c} + 0+ \x{ad89}LV, LVT + \x{1169}\x{1111}V, L + 0: \x{1169} + 0+ \x{1111}V, L + \x{1169}\x{ae4c}V, LV + 0: \x{1169} + 0+ \x{ae4c}V, LV + \x{1169}\x{ad89}V, LVT + 0: \x{1169} + 0+ \x{ad89}V, LVT + \x{ad89}\x{1111}LVT, L + 0: \x{ad89} + 0+ \x{1111}LVT, L + \x{ad89}\x{1169}LVT, V + 0: \x{ad89} + 0+ \x{1169}LVT, V + \x{ad89}\x{ae4c}LVT, LV + 0: \x{ad89} + 0+ \x{ae4c}LVT, LV + \x{ad89}\x{ad89}LVT, LVT + 0: \x{ad89} + 0+ \x{ad89}LVT, LVT + \x{11fe}\x{1111}T, L + 0: \x{11fe} + 0+ \x{1111}T, L + \x{11fe}\x{1169}T, V + 0: \x{11fe} + 0+ \x{1169}T, V + \x{11fe}\x{ae4c}T, LV + 0: \x{11fe} + 0+ \x{ae4c}T, LV + \x{11fe}\x{ad89}T, LVT + 0: \x{11fe} + 0+ \x{ad89}T, LVT + *Test extend and spacing mark + 0: * + 0+ Test extend and spacing mark + \x{1111}\x{ae4c}\x{0711}L, LV, extend + 0: \x{1111}\x{ae4c}\x{711} + 0+ L, LV, extend + \x{1111}\x{ae4c}\x{1b04}L, LV, spacing mark + 0: \x{1111}\x{ae4c}\x{1b04} + 0+ L, LV, spacing mark + \x{1111}\x{ae4c}\x{1b04}\x{0711}\x{1b04}L, LV, spacing mark, extend, spacing mark + 0: \x{1111}\x{ae4c}\x{1b04}\x{711}\x{1b04} + 0+ L, LV, spacing mark, extend, spacing mark + *Test CR, LF, and control + 0: * + 0+ Test CR, LF, and control + \x0d\x{0711}CR, extend + 0: \x{0d} + 0+ \x{711}CR, extend + \x0d\x{1b04}CR, spacingmark + 0: \x{0d} + 0+ \x{1b04}CR, spacingmark + \x0a\x{0711}LF, extend + 0: \x{0a} + 0+ \x{711}LF, extend + \x0a\x{1b04}LF, spacingmark + 0: \x{0a} + 0+ \x{1b04}LF, spacingmark + \x0b\x{0711}Control, extend + 0: \x{0b} + 0+ \x{711}Control, extend + \x09\x{1b04}Control, spacingmark + 0: \x{09} + 0+ \x{1b04}Control, spacingmark + *There are no Prepend characters, so we can't test Prepend, CR + 0: * + 0+ There are no Prepend characters, so we can't test Prepend, CR + +/^(?>\X{2})X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + +/^\X{2,4}X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + +/^\X{2,4}?X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + +/-- --/ + +/\x{1e9e}+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + 1: \x{1e9e} + +/[z\x{1e9e}]+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + 1: \x{1e9e} + +/\x{00df}+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + 1: \x{1e9e} + +/[z\x{00df}]+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + 1: \x{1e9e} + +/\x{1f88}+/8i + \x{1f88}\x{1f80} + 0: \x{1f88}\x{1f80} + 1: \x{1f88} + +/[z\x{1f88}]+/8i + \x{1f88}\x{1f80} + 0: \x{1f88}\x{1f80} + 1: \x{1f88} + +/-- Perl matches these --/ + +/\x{00b5}+/8i + \x{00b5}\x{039c}\x{03bc} + 0: \x{b5}\x{39c}\x{3bc} + 1: \x{b5}\x{39c} + 2: \x{b5} + +/\x{039c}+/8i + \x{00b5}\x{039c}\x{03bc} + 0: \x{b5}\x{39c}\x{3bc} + 1: \x{b5}\x{39c} + 2: \x{b5} + +/\x{03bc}+/8i + \x{00b5}\x{039c}\x{03bc} + 0: \x{b5}\x{39c}\x{3bc} + 1: \x{b5}\x{39c} + 2: \x{b5} + + +/\x{00c5}+/8i + \x{00c5}\x{00e5}\x{212b} + 0: \x{c5}\x{e5}\x{212b} + 1: \x{c5}\x{e5} + 2: \x{c5} + +/\x{00e5}+/8i + \x{00c5}\x{00e5}\x{212b} + 0: \x{c5}\x{e5}\x{212b} + 1: \x{c5}\x{e5} + 2: \x{c5} + +/\x{212b}+/8i + \x{00c5}\x{00e5}\x{212b} + 0: \x{c5}\x{e5}\x{212b} + 1: \x{c5}\x{e5} + 2: \x{c5} + + +/\x{01c4}+/8i + \x{01c4}\x{01c5}\x{01c6} + 0: \x{1c4}\x{1c5}\x{1c6} + 1: \x{1c4}\x{1c5} + 2: \x{1c4} + +/\x{01c5}+/8i + \x{01c4}\x{01c5}\x{01c6} + 0: \x{1c4}\x{1c5}\x{1c6} + 1: \x{1c4}\x{1c5} + 2: \x{1c4} + +/\x{01c6}+/8i + \x{01c4}\x{01c5}\x{01c6} + 0: \x{1c4}\x{1c5}\x{1c6} + 1: \x{1c4}\x{1c5} + 2: \x{1c4} + + +/\x{01c7}+/8i + \x{01c7}\x{01c8}\x{01c9} + 0: \x{1c7}\x{1c8}\x{1c9} + 1: \x{1c7}\x{1c8} + 2: \x{1c7} + +/\x{01c8}+/8i + \x{01c7}\x{01c8}\x{01c9} + 0: \x{1c7}\x{1c8}\x{1c9} + 1: \x{1c7}\x{1c8} + 2: \x{1c7} + +/\x{01c9}+/8i + \x{01c7}\x{01c8}\x{01c9} + 0: \x{1c7}\x{1c8}\x{1c9} + 1: \x{1c7}\x{1c8} + 2: \x{1c7} + + +/\x{01ca}+/8i + \x{01ca}\x{01cb}\x{01cc} + 0: \x{1ca}\x{1cb}\x{1cc} + 1: \x{1ca}\x{1cb} + 2: \x{1ca} + +/\x{01cb}+/8i + \x{01ca}\x{01cb}\x{01cc} + 0: \x{1ca}\x{1cb}\x{1cc} + 1: \x{1ca}\x{1cb} + 2: \x{1ca} + +/\x{01cc}+/8i + \x{01ca}\x{01cb}\x{01cc} + 0: \x{1ca}\x{1cb}\x{1cc} + 1: \x{1ca}\x{1cb} + 2: \x{1ca} + + +/\x{01f1}+/8i + \x{01f1}\x{01f2}\x{01f3} + 0: \x{1f1}\x{1f2}\x{1f3} + 1: \x{1f1}\x{1f2} + 2: \x{1f1} + +/\x{01f2}+/8i + \x{01f1}\x{01f2}\x{01f3} + 0: \x{1f1}\x{1f2}\x{1f3} + 1: \x{1f1}\x{1f2} + 2: \x{1f1} + +/\x{01f3}+/8i + \x{01f1}\x{01f2}\x{01f3} + 0: \x{1f1}\x{1f2}\x{1f3} + 1: \x{1f1}\x{1f2} + 2: \x{1f1} + + +/\x{0345}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + 1: \x{345}\x{399}\x{3b9} + 2: \x{345}\x{399} + 3: \x{345} + +/\x{0399}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + 1: \x{345}\x{399}\x{3b9} + 2: \x{345}\x{399} + 3: \x{345} + +/\x{03b9}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + 1: \x{345}\x{399}\x{3b9} + 2: \x{345}\x{399} + 3: \x{345} + +/\x{1fbe}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + 1: \x{345}\x{399}\x{3b9} + 2: \x{345}\x{399} + 3: \x{345} + + +/\x{0392}+/8i + \x{0392}\x{03b2}\x{03d0} + 0: \x{392}\x{3b2}\x{3d0} + 1: \x{392}\x{3b2} + 2: \x{392} + +/\x{03b2}+/8i + \x{0392}\x{03b2}\x{03d0} + 0: \x{392}\x{3b2}\x{3d0} + 1: \x{392}\x{3b2} + 2: \x{392} + +/\x{03d0}+/8i + \x{0392}\x{03b2}\x{03d0} + 0: \x{392}\x{3b2}\x{3d0} + 1: \x{392}\x{3b2} + 2: \x{392} + + +/\x{0395}+/8i + \x{0395}\x{03b5}\x{03f5} + 0: \x{395}\x{3b5}\x{3f5} + 1: \x{395}\x{3b5} + 2: \x{395} + +/\x{03b5}+/8i + \x{0395}\x{03b5}\x{03f5} + 0: \x{395}\x{3b5}\x{3f5} + 1: \x{395}\x{3b5} + 2: \x{395} + +/\x{03f5}+/8i + \x{0395}\x{03b5}\x{03f5} + 0: \x{395}\x{3b5}\x{3f5} + 1: \x{395}\x{3b5} + 2: \x{395} + + +/\x{0398}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + 1: \x{398}\x{3b8}\x{3d1} + 2: \x{398}\x{3b8} + 3: \x{398} + +/\x{03b8}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + 1: \x{398}\x{3b8}\x{3d1} + 2: \x{398}\x{3b8} + 3: \x{398} + +/\x{03d1}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + 1: \x{398}\x{3b8}\x{3d1} + 2: \x{398}\x{3b8} + 3: \x{398} + +/\x{03f4}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + 1: \x{398}\x{3b8}\x{3d1} + 2: \x{398}\x{3b8} + 3: \x{398} + + +/\x{039a}+/8i + \x{039a}\x{03ba}\x{03f0} + 0: \x{39a}\x{3ba}\x{3f0} + 1: \x{39a}\x{3ba} + 2: \x{39a} + +/\x{03ba}+/8i + \x{039a}\x{03ba}\x{03f0} + 0: \x{39a}\x{3ba}\x{3f0} + 1: \x{39a}\x{3ba} + 2: \x{39a} + +/\x{03f0}+/8i + \x{039a}\x{03ba}\x{03f0} + 0: \x{39a}\x{3ba}\x{3f0} + 1: \x{39a}\x{3ba} + 2: \x{39a} + + +/\x{03a0}+/8i + \x{03a0}\x{03c0}\x{03d6} + 0: \x{3a0}\x{3c0}\x{3d6} + 1: \x{3a0}\x{3c0} + 2: \x{3a0} + +/\x{03c0}+/8i + \x{03a0}\x{03c0}\x{03d6} + 0: \x{3a0}\x{3c0}\x{3d6} + 1: \x{3a0}\x{3c0} + 2: \x{3a0} + +/\x{03d6}+/8i + \x{03a0}\x{03c0}\x{03d6} + 0: \x{3a0}\x{3c0}\x{3d6} + 1: \x{3a0}\x{3c0} + 2: \x{3a0} + + +/\x{03a1}+/8i + \x{03a1}\x{03c1}\x{03f1} + 0: \x{3a1}\x{3c1}\x{3f1} + 1: \x{3a1}\x{3c1} + 2: \x{3a1} + +/\x{03c1}+/8i + \x{03a1}\x{03c1}\x{03f1} + 0: \x{3a1}\x{3c1}\x{3f1} + 1: \x{3a1}\x{3c1} + 2: \x{3a1} + +/\x{03f1}+/8i + \x{03a1}\x{03c1}\x{03f1} + 0: \x{3a1}\x{3c1}\x{3f1} + 1: \x{3a1}\x{3c1} + 2: \x{3a1} + + +/\x{03a3}+/8i + \x{03A3}\x{03C2}\x{03C3} + 0: \x{3a3}\x{3c2}\x{3c3} + 1: \x{3a3}\x{3c2} + 2: \x{3a3} + +/\x{03c2}+/8i + \x{03A3}\x{03C2}\x{03C3} + 0: \x{3a3}\x{3c2}\x{3c3} + 1: \x{3a3}\x{3c2} + 2: \x{3a3} + +/\x{03c3}+/8i + \x{03A3}\x{03C2}\x{03C3} + 0: \x{3a3}\x{3c2}\x{3c3} + 1: \x{3a3}\x{3c2} + 2: \x{3a3} + + +/\x{03a6}+/8i + \x{03a6}\x{03c6}\x{03d5} + 0: \x{3a6}\x{3c6}\x{3d5} + 1: \x{3a6}\x{3c6} + 2: \x{3a6} + +/\x{03c6}+/8i + \x{03a6}\x{03c6}\x{03d5} + 0: \x{3a6}\x{3c6}\x{3d5} + 1: \x{3a6}\x{3c6} + 2: \x{3a6} + +/\x{03d5}+/8i + \x{03a6}\x{03c6}\x{03d5} + 0: \x{3a6}\x{3c6}\x{3d5} + 1: \x{3a6}\x{3c6} + 2: \x{3a6} + + +/\x{03c9}+/8i + \x{03c9}\x{03a9}\x{2126} + 0: \x{3c9}\x{3a9}\x{2126} + 1: \x{3c9}\x{3a9} + 2: \x{3c9} + +/\x{03a9}+/8i + \x{03c9}\x{03a9}\x{2126} + 0: \x{3c9}\x{3a9}\x{2126} + 1: \x{3c9}\x{3a9} + 2: \x{3c9} + +/\x{2126}+/8i + \x{03c9}\x{03a9}\x{2126} + 0: \x{3c9}\x{3a9}\x{2126} + 1: \x{3c9}\x{3a9} + 2: \x{3c9} + + +/\x{1e60}+/8i + \x{1e60}\x{1e61}\x{1e9b} + 0: \x{1e60}\x{1e61}\x{1e9b} + 1: \x{1e60}\x{1e61} + 2: \x{1e60} + +/\x{1e61}+/8i + \x{1e60}\x{1e61}\x{1e9b} + 0: \x{1e60}\x{1e61}\x{1e9b} + 1: \x{1e60}\x{1e61} + 2: \x{1e60} + +/\x{1e9b}+/8i + \x{1e60}\x{1e61}\x{1e9b} + 0: \x{1e60}\x{1e61}\x{1e9b} + 1: \x{1e60}\x{1e61} + 2: \x{1e60} + + +/\x{1e9e}+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + 1: \x{1e9e} + +/\x{00df}+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + 1: \x{1e9e} + + +/\x{1f88}+/8i + \x{1f88}\x{1f80} + 0: \x{1f88}\x{1f80} + 1: \x{1f88} + +/\x{1f80}+/8i + \x{1f88}\x{1f80} + 0: \x{1f88}\x{1f80} + 1: \x{1f88} + +/\x{004b}+/8i + \x{004b}\x{006b}\x{212a} + 0: Kk\x{212a} + 1: Kk + 2: K + +/\x{006b}+/8i + \x{004b}\x{006b}\x{212a} + 0: Kk\x{212a} + 1: Kk + 2: K + +/\x{212a}+/8i + \x{004b}\x{006b}\x{212a} + 0: Kk\x{212a} + 1: Kk + 2: K + + +/\x{0053}+/8i + \x{0053}\x{0073}\x{017f} + 0: Ss\x{17f} + 1: Ss + 2: S + +/\x{0073}+/8i + \x{0053}\x{0073}\x{017f} + 0: Ss\x{17f} + 1: Ss + 2: S + +/\x{017f}+/8i + \x{0053}\x{0073}\x{017f} + 0: Ss\x{17f} + 1: Ss + 2: S + +/ist/8i + ikt +No match + +/is+t/8i + iSs\x{17f}t + 0: iSs\x{17f}t + ikt +No match + +/is+?t/8i + ikt +No match + +/is?t/8i + ikt +No match + +/is{2}t/8i + iskt +No match + +/-- End of testinput10 --/ diff --git a/tools/pcre/testdata/testoutput11-16 b/tools/pcre/testdata/testoutput11-16 new file mode 100644 index 00000000..dff72b94 --- /dev/null +++ b/tools/pcre/testdata/testoutput11-16 @@ -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 \x{ff} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[\x{100}]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{100} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x80/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x80 + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\xff/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{ff} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x{0041}\x{2262}\x{0391}\x{002e}/D8M +Memory allocation (code space): 26 +------------------------------------------------------------------ + 0 10 Bra + 2 A\x{2262}\x{391}. + 10 10 Ket + 12 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = '.' + +/\x{D55c}\x{ad6d}\x{C5B4}/D8M +Memory allocation (code space): 22 +------------------------------------------------------------------ + 0 8 Bra + 2 \x{d55c}\x{ad6d}\x{c5b4} + 8 8 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d55c} +Need char = \x{c5b4} + +/\x{65e5}\x{672c}\x{8a9e}/D8M +Memory allocation (code space): 22 +------------------------------------------------------------------ + 0 8 Bra + 2 \x{65e5}\x{672c}\x{8a9e} + 8 8 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{65e5} +Need char = \x{8a9e} + +/[\x{100}]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{100} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[Z\x{100}]/8BM +Memory allocation (code space): 54 +------------------------------------------------------------------ + 0 24 Bra + 2 [Z\x{100}] + 24 24 Ket + 26 End +------------------------------------------------------------------ + +/^[\x{100}\E-\Q\E\x{150}]/B8M +Memory allocation (code space): 26 +------------------------------------------------------------------ + 0 10 Bra + 2 ^ + 3 [\x{100}-\x{150}] + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/^[\QÄ€\E-\QÅ\E]/B8M +Memory allocation (code space): 26 +------------------------------------------------------------------ + 0 10 Bra + 2 ^ + 3 [\x{100}-\x{150}] + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/^[\QÄ€\E-\QÅ\E/B8M +Failed: missing terminating ] for character class at offset 13 + +/[\p{L}]/BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\p{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\p{^L}]/BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\P{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\P{L}]/BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\P{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\P{^L}]/BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\p{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[abc\p{L}\x{0660}]/8BM +Memory allocation (code space): 60 +------------------------------------------------------------------ + 0 27 Bra + 2 [a-c\p{L}\x{660}] + 27 27 Ket + 29 End +------------------------------------------------------------------ + +/[\p{Nd}]/8BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\p{Nd}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\p{Nd}+-]+/8BM +Memory allocation (code space): 58 +------------------------------------------------------------------ + 0 26 Bra + 2 [+\-\p{Nd}]+ + 26 26 Ket + 28 End +------------------------------------------------------------------ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM +Memory allocation (code space): 32 +------------------------------------------------------------------ + 0 13 Bra + 2 /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} + 13 13 Ket + 15 End +------------------------------------------------------------------ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM +Memory allocation (code space): 32 +------------------------------------------------------------------ + 0 13 Bra + 2 A\x{391}\x{10427}\x{ff3a}\x{1fb0} + 13 13 Ket + 15 End +------------------------------------------------------------------ + +/[\x{105}-\x{109}]/8iBM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\x{104}-\x{109}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/( ( (?(1)0|) )* )/xBM +Memory allocation (code space): 52 +------------------------------------------------------------------ + 0 23 Bra + 2 19 CBra 1 + 5 Brazero + 6 13 SCBra 2 + 9 6 Cond + 11 1 Cond ref + 13 0 + 15 2 Alt + 17 8 Ket + 19 13 KetRmax + 21 19 Ket + 23 23 Ket + 25 End +------------------------------------------------------------------ + +/( (?(1)0|)* )/xBM +Memory allocation (code space): 42 +------------------------------------------------------------------ + 0 18 Bra + 2 14 CBra 1 + 5 Brazero + 6 6 SCond + 8 1 Cond ref + 10 0 + 12 2 Alt + 14 8 KetRmax + 16 14 Ket + 18 18 Ket + 20 End +------------------------------------------------------------------ + +/[a]/BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 a + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[a]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 a + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[\xaa]/BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{aa} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[\xaa]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{aa} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^a]/BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 [^a] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^a]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 [^a] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^\xaa]/BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 [^\x{aa}] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^\xaa]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 [^\x{aa}] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^\d]/8WB +------------------------------------------------------------------ + 0 9 Bra + 2 [^\p{Nd}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[[:^alpha:][:^cntrl:]]+/8WB +------------------------------------------------------------------ + 0 26 Bra + 2 [ -~\x80-\xff\P{L}]+ + 26 26 Ket + 28 End +------------------------------------------------------------------ + +/[[:^cntrl:][:^alpha:]]+/8WB +------------------------------------------------------------------ + 0 26 Bra + 2 [ -~\x80-\xff\P{L}]+ + 26 26 Ket + 28 End +------------------------------------------------------------------ + +/[[:alpha:]]+/8WB +------------------------------------------------------------------ + 0 10 Bra + 2 [\p{L}]+ + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/[[:^alpha:]\S]+/8WB +------------------------------------------------------------------ + 0 13 Bra + 2 [\P{L}\P{Xsp}]+ + 13 13 Ket + 15 End +------------------------------------------------------------------ + +/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B +------------------------------------------------------------------ + 0 60 Bra + 2 abc + 8 5 CBra 1 + 11 d + 13 4 Alt + 15 e + 17 9 Ket + 19 *THEN + 20 x + 22 12 CBra 2 + 25 123 + 31 *THEN + 32 4 + 34 24 Alt + 36 567 + 42 5 CBra 3 + 45 b + 47 4 Alt + 49 q + 51 9 Ket + 53 *THEN + 54 xx + 58 36 Ket + 60 60 Ket + 62 End +------------------------------------------------------------------ + +/-- End of testinput11 --/ diff --git a/tools/pcre/testdata/testoutput11-32 b/tools/pcre/testdata/testoutput11-32 new file mode 100644 index 00000000..8335fb82 --- /dev/null +++ b/tools/pcre/testdata/testoutput11-32 @@ -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): 48 +------------------------------------------------------------------ + 0 9 Bra + 2 5 CBra 1 + 5 /i b + 7 5 Ket + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/(?s)(.*X|^B)/BM +Memory allocation (code space): 76 +------------------------------------------------------------------ + 0 16 Bra + 2 7 CBra 1 + 5 AllAny* + 7 X + 9 5 Alt + 11 ^ + 12 B + 14 12 Ket + 16 16 Ket + 18 End +------------------------------------------------------------------ + +/(?s:.*X|^B)/BM +Memory allocation (code space): 72 +------------------------------------------------------------------ + 0 15 Bra + 2 6 Bra + 4 AllAny* + 6 X + 8 5 Alt + 10 ^ + 11 B + 13 11 Ket + 15 15 Ket + 17 End +------------------------------------------------------------------ + +/^[[:alnum:]]/BM +Memory allocation (code space): 60 +------------------------------------------------------------------ + 0 12 Bra + 2 ^ + 3 [0-9A-Za-z] + 12 12 Ket + 14 End +------------------------------------------------------------------ + +/#/IxMD +Memory allocation (code space): 20 +------------------------------------------------------------------ + 0 2 Bra + 2 2 Ket + 4 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: extended +No first char +No need char + +/a#/IxMD +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 a + 4 4 Ket + 6 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: extended +First char = 'a' +No need char + +/x?+/BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 x?+ + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/x++/BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 x++ + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/x{1,3}+/BM +Memory allocation (code space): 56 +------------------------------------------------------------------ + 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): 52 +------------------------------------------------------------------ + 0 10 Bra + 2 Braposzero + 3 5 CBraPos 1 + 6 x + 8 5 KetRpos + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM +Memory allocation (code space): 220 +------------------------------------------------------------------ + 0 52 Bra + 2 ^ + 3 47 CBra 1 + 6 5 CBra 2 + 9 a+ + 11 5 Ket + 13 13 CBra 3 + 16 [ab]+? + 26 13 Ket + 28 13 CBra 4 + 31 [bc]+ + 41 13 Ket + 43 5 CBra 5 + 46 \w* + 48 5 Ket + 50 47 Ket + 52 52 Ket + 54 End +------------------------------------------------------------------ + +|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM +Memory allocation (code space): 3296 +------------------------------------------------------------------ + 0 821 Bra + 2 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[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): 3256 +------------------------------------------------------------------ + 0 811 Bra + 2 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[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): 64 +------------------------------------------------------------------ + 0 13 Bra + 2 9 CBra 1 + 5 a + 7 2 Recurse + 9 b + 11 9 Ket + 13 13 Ket + 15 End +------------------------------------------------------------------ + +/(a(?1)+b)/BM +Memory allocation (code space): 80 +------------------------------------------------------------------ + 0 17 Bra + 2 13 CBra 1 + 5 a + 7 4 Once + 9 2 Recurse + 11 4 KetRmax + 13 b + 15 13 Ket + 17 17 Ket + 19 End +------------------------------------------------------------------ + +/a(?Pb|c)d(?Pe)/BM +Memory allocation (code space): 186 +------------------------------------------------------------------ + 0 24 Bra + 2 a + 4 5 CBra 1 + 7 b + 9 4 Alt + 11 c + 13 9 Ket + 15 d + 17 5 CBra 2 + 20 e + 22 5 Ket + 24 24 Ket + 26 End +------------------------------------------------------------------ + +/(?:a(?Pc(?Pd)))(?Pa)/BM +Memory allocation (code space): 155 +------------------------------------------------------------------ + 0 29 Bra + 2 18 Bra + 4 a + 6 12 CBra 1 + 9 c + 11 5 CBra 2 + 14 d + 16 5 Ket + 18 12 Ket + 20 18 Ket + 22 5 CBra 3 + 25 a + 27 5 Ket + 29 29 Ket + 31 End +------------------------------------------------------------------ + +/(?Pa)...(?P=a)bbb(?P>a)d/BM +Memory allocation (code space): 117 +------------------------------------------------------------------ + 0 24 Bra + 2 5 CBra 1 + 5 a + 7 5 Ket + 9 Any + 10 Any + 11 Any + 12 \1 + 14 bbb + 20 2 Recurse + 22 d + 24 24 Ket + 26 End +------------------------------------------------------------------ + +/abc(?C255)de(?C)f/BM +Memory allocation (code space): 100 +------------------------------------------------------------------ + 0 22 Bra + 2 abc + 8 Callout 255 10 1 + 12 de + 16 Callout 0 16 1 + 20 f + 22 22 Ket + 24 End +------------------------------------------------------------------ + +/abcde/CBM +Memory allocation (code space): 156 +------------------------------------------------------------------ + 0 36 Bra + 2 Callout 255 0 1 + 6 a + 8 Callout 255 1 1 + 12 b + 14 Callout 255 2 1 + 18 c + 20 Callout 255 3 1 + 24 d + 26 Callout 255 4 1 + 30 e + 32 Callout 255 5 0 + 36 36 Ket + 38 End +------------------------------------------------------------------ + +/\x{100}/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{100} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x{1000}/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{1000} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x{10000}/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{10000} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x{100000}/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{100000} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x{10ffff}/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{10ffff} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x{110000}/8BM +Failed: character value in \x{...} sequence is too large at offset 9 + +/[\x{ff}]/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{ff} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[\x{100}]/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{100} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x80/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x80 + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\xff/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{ff} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x{0041}\x{2262}\x{0391}\x{002e}/D8M +Memory allocation (code space): 52 +------------------------------------------------------------------ + 0 10 Bra + 2 A\x{2262}\x{391}. + 10 10 Ket + 12 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = '.' + +/\x{D55c}\x{ad6d}\x{C5B4}/D8M +Memory allocation (code space): 44 +------------------------------------------------------------------ + 0 8 Bra + 2 \x{d55c}\x{ad6d}\x{c5b4} + 8 8 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d55c} +Need char = \x{c5b4} + +/\x{65e5}\x{672c}\x{8a9e}/D8M +Memory allocation (code space): 44 +------------------------------------------------------------------ + 0 8 Bra + 2 \x{65e5}\x{672c}\x{8a9e} + 8 8 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{65e5} +Need char = \x{8a9e} + +/[\x{100}]/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{100} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[Z\x{100}]/8BM +Memory allocation (code space): 76 +------------------------------------------------------------------ + 0 16 Bra + 2 [Z\x{100}] + 16 16 Ket + 18 End +------------------------------------------------------------------ + +/^[\x{100}\E-\Q\E\x{150}]/B8M +Memory allocation (code space): 52 +------------------------------------------------------------------ + 0 10 Bra + 2 ^ + 3 [\x{100}-\x{150}] + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/^[\QÄ€\E-\QÅ\E]/B8M +Memory allocation (code space): 52 +------------------------------------------------------------------ + 0 10 Bra + 2 ^ + 3 [\x{100}-\x{150}] + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/^[\QÄ€\E-\QÅ\E/B8M +Failed: missing terminating ] for character class at offset 13 + +/[\p{L}]/BM +Memory allocation (code space): 48 +------------------------------------------------------------------ + 0 9 Bra + 2 [\p{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\p{^L}]/BM +Memory allocation (code space): 48 +------------------------------------------------------------------ + 0 9 Bra + 2 [\P{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\P{L}]/BM +Memory allocation (code space): 48 +------------------------------------------------------------------ + 0 9 Bra + 2 [\P{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\P{^L}]/BM +Memory allocation (code space): 48 +------------------------------------------------------------------ + 0 9 Bra + 2 [\p{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[abc\p{L}\x{0660}]/8BM +Memory allocation (code space): 88 +------------------------------------------------------------------ + 0 19 Bra + 2 [a-c\p{L}\x{660}] + 19 19 Ket + 21 End +------------------------------------------------------------------ + +/[\p{Nd}]/8BM +Memory allocation (code space): 48 +------------------------------------------------------------------ + 0 9 Bra + 2 [\p{Nd}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\p{Nd}+-]+/8BM +Memory allocation (code space): 84 +------------------------------------------------------------------ + 0 18 Bra + 2 [+\-\p{Nd}]+ + 18 18 Ket + 20 End +------------------------------------------------------------------ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM +Memory allocation (code space): 60 +------------------------------------------------------------------ + 0 12 Bra + 2 /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} + 12 12 Ket + 14 End +------------------------------------------------------------------ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM +Memory allocation (code space): 60 +------------------------------------------------------------------ + 0 12 Bra + 2 A\x{391}\x{10427}\x{ff3a}\x{1fb0} + 12 12 Ket + 14 End +------------------------------------------------------------------ + +/[\x{105}-\x{109}]/8iBM +Memory allocation (code space): 48 +------------------------------------------------------------------ + 0 9 Bra + 2 [\x{104}-\x{109}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/( ( (?(1)0|) )* )/xBM +Memory allocation (code space): 104 +------------------------------------------------------------------ + 0 23 Bra + 2 19 CBra 1 + 5 Brazero + 6 13 SCBra 2 + 9 6 Cond + 11 1 Cond ref + 13 0 + 15 2 Alt + 17 8 Ket + 19 13 KetRmax + 21 19 Ket + 23 23 Ket + 25 End +------------------------------------------------------------------ + +/( (?(1)0|)* )/xBM +Memory allocation (code space): 84 +------------------------------------------------------------------ + 0 18 Bra + 2 14 CBra 1 + 5 Brazero + 6 6 SCond + 8 1 Cond ref + 10 0 + 12 2 Alt + 14 8 KetRmax + 16 14 Ket + 18 18 Ket + 20 End +------------------------------------------------------------------ + +/[a]/BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 a + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[a]/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 a + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[\xaa]/BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{aa} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[\xaa]/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{aa} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^a]/BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 [^a] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^a]/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 [^a] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^\xaa]/BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 [^\x{aa}] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^\xaa]/8BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 4 Bra + 2 [^\x{aa}] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^\d]/8WB +------------------------------------------------------------------ + 0 9 Bra + 2 [^\p{Nd}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[[:^alpha:][:^cntrl:]]+/8WB +------------------------------------------------------------------ + 0 18 Bra + 2 [ -~\x80-\xff\P{L}]+ + 18 18 Ket + 20 End +------------------------------------------------------------------ + +/[[:^cntrl:][:^alpha:]]+/8WB +------------------------------------------------------------------ + 0 18 Bra + 2 [ -~\x80-\xff\P{L}]+ + 18 18 Ket + 20 End +------------------------------------------------------------------ + +/[[:alpha:]]+/8WB +------------------------------------------------------------------ + 0 10 Bra + 2 [\p{L}]+ + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/[[:^alpha:]\S]+/8WB +------------------------------------------------------------------ + 0 13 Bra + 2 [\P{L}\P{Xsp}]+ + 13 13 Ket + 15 End +------------------------------------------------------------------ + +/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B +------------------------------------------------------------------ + 0 60 Bra + 2 abc + 8 5 CBra 1 + 11 d + 13 4 Alt + 15 e + 17 9 Ket + 19 *THEN + 20 x + 22 12 CBra 2 + 25 123 + 31 *THEN + 32 4 + 34 24 Alt + 36 567 + 42 5 CBra 3 + 45 b + 47 4 Alt + 49 q + 51 9 Ket + 53 *THEN + 54 xx + 58 36 Ket + 60 60 Ket + 62 End +------------------------------------------------------------------ + +/-- End of testinput11 --/ diff --git a/tools/pcre/testdata/testoutput11-8 b/tools/pcre/testdata/testoutput11-8 new file mode 100644 index 00000000..c1c85f9a --- /dev/null +++ b/tools/pcre/testdata/testoutput11-8 @@ -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 \x{aa} + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/[\xaa]/8BM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra + 3 \x{aa} + 6 6 Ket + 9 End +------------------------------------------------------------------ + +/[^a]/BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 [^a] + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/[^a]/8BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 [^a] + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/[^\xaa]/BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 [^\x{aa}] + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/[^\xaa]/8BM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra + 3 [^\x{aa}] + 6 6 Ket + 9 End +------------------------------------------------------------------ + +/[^\d]/8WB +------------------------------------------------------------------ + 0 11 Bra + 3 [^\p{Nd}] + 11 11 Ket + 14 End +------------------------------------------------------------------ + +/[[:^alpha:][:^cntrl:]]+/8WB +------------------------------------------------------------------ + 0 44 Bra + 3 [ -~\x80-\xff\P{L}]+ + 44 44 Ket + 47 End +------------------------------------------------------------------ + +/[[:^cntrl:][:^alpha:]]+/8WB +------------------------------------------------------------------ + 0 44 Bra + 3 [ -~\x80-\xff\P{L}]+ + 44 44 Ket + 47 End +------------------------------------------------------------------ + +/[[:alpha:]]+/8WB +------------------------------------------------------------------ + 0 12 Bra + 3 [\p{L}]+ + 12 12 Ket + 15 End +------------------------------------------------------------------ + +/[[:^alpha:]\S]+/8WB +------------------------------------------------------------------ + 0 15 Bra + 3 [\P{L}\P{Xsp}]+ + 15 15 Ket + 18 End +------------------------------------------------------------------ + +/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B +------------------------------------------------------------------ + 0 73 Bra + 3 abc + 9 7 CBra 1 + 14 d + 16 5 Alt + 19 e + 21 12 Ket + 24 *THEN + 25 x + 27 14 CBra 2 + 32 123 + 38 *THEN + 39 4 + 41 29 Alt + 44 567 + 50 7 CBra 3 + 55 b + 57 5 Alt + 60 q + 62 12 Ket + 65 *THEN + 66 xx + 70 43 Ket + 73 73 Ket + 76 End +------------------------------------------------------------------ + +/-- End of testinput11 --/ diff --git a/tools/pcre/testdata/testoutput12 b/tools/pcre/testdata/testoutput12 new file mode 100644 index 00000000..559f48d3 --- /dev/null +++ b/tools/pcre/testdata/testoutput12 @@ -0,0 +1,181 @@ +/-- This test is run only when JIT support is available. It checks for a +successful and an unsuccessful JIT compile and save and restore behaviour, +and a couple of things that are different with JIT. --/ + +/abc/S+I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' +Subject length lower bound = 3 +No set of starting bytes +JIT study was successful + +/ab(*THEN)/S+I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' +Subject length lower bound = 2 +No set of starting bytes +JIT study was not successful + +/abc/S+I>testsavedregex +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' +Subject length lower bound = 3 +No set of starting bytes +JIT study was successful +Compiled pattern written to testsavedregex +Study data written to testsavedregex + +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 --git a/tools/pcre/testdata/testoutput15 b/tools/pcre/testdata/testoutput15 new file mode 100644 index 00000000..d6b7d094 --- /dev/null +++ b/tools/pcre/testdata/testoutput15 @@ -0,0 +1,1269 @@ +/-- 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' + +/badutf/8 + \xdf +Error -10 (bad UTF-8 string) offset=0 reason=1 + \xef +Error -10 (bad UTF-8 string) offset=0 reason=2 + \xef\x80 +Error -10 (bad UTF-8 string) offset=0 reason=1 + \xf7 +Error -10 (bad UTF-8 string) offset=0 reason=3 + \xf7\x80 +Error -10 (bad UTF-8 string) offset=0 reason=2 + \xf7\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=1 + \xfb +Error -10 (bad UTF-8 string) offset=0 reason=4 + \xfb\x80 +Error -10 (bad UTF-8 string) offset=0 reason=3 + \xfb\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=2 + \xfb\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=1 + \xfd +Error -10 (bad UTF-8 string) offset=0 reason=5 + \xfd\x80 +Error -10 (bad UTF-8 string) offset=0 reason=4 + \xfd\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=3 + \xfd\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=2 + \xfd\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=1 + \xdf\x7f +Error -10 (bad UTF-8 string) offset=0 reason=6 + \xef\x7f\x80 +Error -10 (bad UTF-8 string) offset=0 reason=6 + \xef\x80\x7f +Error -10 (bad UTF-8 string) offset=0 reason=7 + \xf7\x7f\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=6 + \xf7\x80\x7f\x80 +Error -10 (bad UTF-8 string) offset=0 reason=7 + \xf7\x80\x80\x7f +Error -10 (bad UTF-8 string) offset=0 reason=8 + \xfb\x7f\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=6 + \xfb\x80\x7f\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=7 + \xfb\x80\x80\x7f\x80 +Error -10 (bad UTF-8 string) offset=0 reason=8 + \xfb\x80\x80\x80\x7f +Error -10 (bad UTF-8 string) offset=0 reason=9 + \xfd\x7f\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=6 + \xfd\x80\x7f\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=7 + \xfd\x80\x80\x7f\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=8 + \xfd\x80\x80\x80\x7f\x80 +Error -10 (bad UTF-8 string) offset=0 reason=9 + \xfd\x80\x80\x80\x80\x7f +Error -10 (bad UTF-8 string) offset=0 reason=10 + \xed\xa0\x80 +Error -10 (bad UTF-8 string) offset=0 reason=14 + \xc0\x8f +Error -10 (bad UTF-8 string) offset=0 reason=15 + \xe0\x80\x8f +Error -10 (bad UTF-8 string) offset=0 reason=16 + \xf0\x80\x80\x8f +Error -10 (bad UTF-8 string) offset=0 reason=17 + \xf8\x80\x80\x80\x8f +Error -10 (bad UTF-8 string) offset=0 reason=18 + \xfc\x80\x80\x80\x80\x8f +Error -10 (bad UTF-8 string) offset=0 reason=19 + \x80 +Error -10 (bad UTF-8 string) offset=0 reason=20 + \xfe +Error -10 (bad UTF-8 string) offset=0 reason=21 + \xff +Error -10 (bad UTF-8 string) offset=0 reason=21 + \xef\xb7\x90 +Error -10 (bad UTF-8 string) offset=0 reason=22 + +/badutf/8 + \xfb\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=11 + \xfd\x80\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=12 + \xf7\xbf\xbf\xbf +Error -10 (bad UTF-8 string) offset=0 reason=13 + +/shortutf/8 + \P\P\xdf +Error -25 (short UTF-8 string) offset=0 reason=1 + \P\P\xef +Error -25 (short UTF-8 string) offset=0 reason=2 + \P\P\xef\x80 +Error -25 (short UTF-8 string) offset=0 reason=1 + \P\P\xf7 +Error -25 (short UTF-8 string) offset=0 reason=3 + \P\P\xf7\x80 +Error -25 (short UTF-8 string) offset=0 reason=2 + \P\P\xf7\x80\x80 +Error -25 (short UTF-8 string) offset=0 reason=1 + \P\P\xfb +Error -25 (short UTF-8 string) offset=0 reason=4 + \P\P\xfb\x80 +Error -25 (short UTF-8 string) offset=0 reason=3 + \P\P\xfb\x80\x80 +Error -25 (short UTF-8 string) offset=0 reason=2 + \P\P\xfb\x80\x80\x80 +Error -25 (short UTF-8 string) offset=0 reason=1 + \P\P\xfd +Error -25 (short UTF-8 string) offset=0 reason=5 + \P\P\xfd\x80 +Error -25 (short UTF-8 string) offset=0 reason=4 + \P\P\xfd\x80\x80 +Error -25 (short UTF-8 string) offset=0 reason=3 + \P\P\xfd\x80\x80\x80 +Error -25 (short UTF-8 string) offset=0 reason=2 + \P\P\xfd\x80\x80\x80\x80 +Error -25 (short UTF-8 string) offset=0 reason=1 + +/anything/8 + \xc0\x80 +Error -10 (bad UTF-8 string) offset=0 reason=15 + \xc1\x8f +Error -10 (bad UTF-8 string) offset=0 reason=15 + \xe0\x9f\x80 +Error -10 (bad UTF-8 string) offset=0 reason=16 + \xf0\x8f\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=17 + \xf8\x87\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=18 + \xfc\x83\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=19 + \xfe\x80\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=21 + \xff\x80\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=21 + \xc3\x8f +No match + \xe0\xaf\x80 +No match + \xe1\x80\x80 +No match + \xf0\x9f\x80\x80 +No match + \xf1\x8f\x80\x80 +No match + \xf8\x88\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=11 + \xf9\x87\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=11 + \xfc\x84\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=12 + \xfd\x83\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=12 + \?\xf8\x88\x80\x80\x80 +No match + \?\xf9\x87\x80\x80\x80 +No match + \?\xfc\x84\x80\x80\x80\x80 +No match + \?\xfd\x83\x80\x80\x80\x80 +No match + +/noncharacter/8 + \x{fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{1fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{1ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{2fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{2ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{3fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{3ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{4fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{4ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{5fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{5ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{6fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{6ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{7fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{7ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{8fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{8ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{9fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{9ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{afffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{affff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{bfffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{bffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{cfffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{cffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{dfffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{dffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{efffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{effff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{ffffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{10fffe} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{10ffff} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdd0} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdd1} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdd2} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdd3} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdd4} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdd5} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdd6} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdd7} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdd8} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdd9} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdda} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fddb} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fddc} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fddd} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdde} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fddf} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fde0} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fde1} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fde2} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fde3} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fde4} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fde5} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fde6} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fde7} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fde8} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fde9} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdea} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdeb} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdec} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fded} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdee} +Error -10 (bad UTF-8 string) offset=0 reason=22 + \x{fdef} +Error -10 (bad UTF-8 string) offset=0 reason=22 + +/\x{100}/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} + +/\x{1000}/8DZ +------------------------------------------------------------------ + Bra + \x{1000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{e1} +Need char = \x{80} + +/\x{10000}/8DZ +------------------------------------------------------------------ + Bra + \x{10000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{f0} +Need char = \x{80} + +/\x{100000}/8DZ +------------------------------------------------------------------ + Bra + \x{100000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{f4} +Need char = \x{80} + +/\x{10ffff}/8DZ +------------------------------------------------------------------ + Bra + \x{10ffff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{f4} +Need char = \x{bf} + +/[\x{ff}]/8DZ +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c3} +Need char = \x{bf} + +/[\x{100}]/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} + +/\x80/8DZ +------------------------------------------------------------------ + Bra + \x{80} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c2} +Need char = \x{80} + +/\xff/8DZ +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c3} +Need char = \x{bf} + +/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 +------------------------------------------------------------------ + Bra + \x{d55c}\x{ad6d}\x{c5b4} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ed} +Need char = \x{b4} + \x{D55c}\x{ad6d}\x{C5B4} + 0: \x{d55c}\x{ad6d}\x{c5b4} + +/\x{65e5}\x{672c}\x{8a9e}/DZ8 +------------------------------------------------------------------ + Bra + \x{65e5}\x{672c}\x{8a9e} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{e6} +Need char = \x{9e} + \x{65e5}\x{672c}\x{8a9e} + 0: \x{65e5}\x{672c}\x{8a9e} + +/\x{80}/DZ8 +------------------------------------------------------------------ + Bra + \x{80} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c2} +Need char = \x{80} + +/\x{084}/DZ8 +------------------------------------------------------------------ + Bra + \x{84} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c2} +Need char = \x{84} + +/\x{104}/DZ8 +------------------------------------------------------------------ + Bra + \x{104} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{84} + +/\x{861}/DZ8 +------------------------------------------------------------------ + Bra + \x{861} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{e0} +Need char = \x{a1} + +/\x{212ab}/DZ8 +------------------------------------------------------------------ + Bra + \x{212ab} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{f0} +Need char = \x{ab} + +/-- This one is here not because it's different to Perl, but because the way +the captured single-byte is displayed. (In Perl it becomes a character, and you +can't tell the difference.) --/ + +/X(\C)(.*)/8 + X\x{1234} + 0: X\x{1234} + 1: \x{e1} + 2: \x{88}\x{b4} + X\nabc + 0: X\x{0a}abc + 1: \x{0a} + 2: abc + +/-- This one is here because Perl gives out a grumbly error message (quite +correctly, but that messes up comparisons). --/ + +/a\Cb/8 + *** Failers +No match + a\x{100}b +No match + +/[^ab\xC0-\xF0]/8SDZ +------------------------------------------------------------------ + Bra + [\x00-`c-\xbf\xf1-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a + \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 + \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 + 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y + Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f + \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 + \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf + \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee + \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd + \xfe \xff + \x{f1} + 0: \x{f1} + \x{bf} + 0: \x{bf} + \x{100} + 0: \x{100} + \x{1000} + 0: \x{1000} + *** Failers + 0: * + \x{c0} +No match + \x{f0} +No match + +/Ä€{3,4}/8SDZ +------------------------------------------------------------------ + Bra + \x{100}{3} + \x{100}? + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} +Subject length lower bound = 3 +No set of starting bytes + \x{100}\x{100}\x{100}\x{100\x{100} + 0: \x{100}\x{100}\x{100} + +/(\x{100}+|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}+ + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x \xc4 + +/(\x{100}*a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}*+ + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a x \xc4 + +/(\x{100}{0,2}a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}{0,2} + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a x \xc4 + +/(\x{100}{1,2}a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100} + \x{100}{0,1} + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x \xc4 + +/\x{100}/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} + +/a\x{100}\x{101}*/8DZ +------------------------------------------------------------------ + Bra + a\x{100} + \x{101}* + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = \x{80} + +/a\x{100}\x{101}+/8DZ +------------------------------------------------------------------ + Bra + a\x{100} + \x{101}+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = \x{81} + +/[^\x{c4}]/DZ +------------------------------------------------------------------ + Bra + [^\x{c4}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[\x{100}]/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} + \x{100} + 0: \x{100} + Z\x{100} + 0: \x{100} + \x{100}Z + 0: \x{100} + *** Failers +No match + +/[\xff]/DZ8 +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c3} +Need char = \x{bf} + >\x{ff}< + 0: \x{ff} + +/[^\xff]/8DZ +------------------------------------------------------------------ + Bra + [^\x{ff}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/\x{100}abc(xyz(?1))/8DZ +------------------------------------------------------------------ + Bra + \x{100}abc + CBra 1 + xyz + Recurse + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +First char = \x{c4} +Need char = 'z' + +/a\x{1234}b/P8 + a\x{1234}b + 0: a\x{1234}b + +/\777/8I +Capturing subpattern count = 0 +Options: utf +First char = \x{c7} +Need char = \x{bf} + \x{1ff} + 0: \x{1ff} + \777 + 0: \x{1ff} + +/\x{100}+\x{200}/8DZ +------------------------------------------------------------------ + Bra + \x{100}++ + \x{200} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} + +/\x{100}+X/8DZ +------------------------------------------------------------------ + Bra + \x{100}++ + X + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = 'X' + +/^[\QÄ€\E-\QÅ\E/BZ8 +Failed: missing terminating ] for character class at offset 15 + +/-- This tests the stricter UTF-8 check according to RFC 3629. --/ + +/X/8 + \x{0}\x{d7ff}\x{e000}\x{10ffff} +Error -10 (bad UTF-8 string) offset=7 reason=22 + \x{d800} +Error -10 (bad UTF-8 string) offset=0 reason=14 + \x{d800}\? +No match + \x{da00} +Error -10 (bad UTF-8 string) offset=0 reason=14 + \x{da00}\? +No match + \x{dfff} +Error -10 (bad UTF-8 string) offset=0 reason=14 + \x{dfff}\? +No match + \x{110000} +Error -10 (bad UTF-8 string) offset=0 reason=13 + \x{110000}\? +No match + \x{2000000} +Error -10 (bad UTF-8 string) offset=0 reason=11 + \x{2000000}\? +No match + \x{7fffffff} +Error -10 (bad UTF-8 string) offset=0 reason=12 + \x{7fffffff}\? +No match + +/(*UTF8)\x{1234}/ + abcd\x{1234}pqr + 0: \x{1234} + +/(*CRLF)(*UTF)(*BSR_UNICODE)a\Rb/I +Capturing subpattern count = 0 +Options: bsr_unicode utf +Forced newline sequence: CRLF +First char = 'a' +Need char = 'b' + +/\h/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x20 \xc2 \xe1 \xe2 \xe3 + ABC\x{09} + 0: \x{09} + ABC\x{20} + 0: + ABC\x{a0} + 0: \x{a0} + ABC\x{1680} + 0: \x{1680} + ABC\x{180e} + 0: \x{180e} + ABC\x{2000} + 0: \x{2000} + ABC\x{202f} + 0: \x{202f} + ABC\x{205f} + 0: \x{205f} + ABC\x{3000} + 0: \x{3000} + +/\v/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 + ABC\x{0a} + 0: \x{0a} + ABC\x{0b} + 0: \x{0b} + ABC\x{0c} + 0: \x{0c} + ABC\x{0d} + 0: \x{0d} + ABC\x{85} + 0: \x{85} + ABC\x{2028} + 0: \x{2028} + +/\h*A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 1 +Starting byte set: \x09 \x20 A \xc2 \xe1 \xe2 \xe3 + CDBABC + 0: A + +/\v+A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 2 +Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 + +/\s?xxx\s/8SI +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'x' +Subject length lower bound = 4 +Starting byte set: \x09 \x0a \x0c \x0d \x20 x + +/\sxxx\s/I8ST1 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'x' +Subject length lower bound = 5 +Starting byte set: \x09 \x0a \x0c \x0d \x20 \xc2 + AB\x{85}xxx\x{a0}XYZ + 0: \x{85}xxx\x{a0} + AB\x{a0}xxx\x{85}XYZ + 0: \x{a0}xxx\x{85} + +/\S \S/I8ST1 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = ' ' +Subject length lower bound = 3 +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e + \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d + \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ + A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e + f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xc0 \xc1 \xc2 \xc3 + \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 + \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 + \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 + \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff + \x{a2} \x{84} + 0: \x{a2} \x{84} + A Z + 0: A Z + +/a+/8 + a\x{123}aa\>1 + 0: aa + a\x{123}aa\>2 +Error -11 (bad UTF-8 offset) + a\x{123}aa\>3 + 0: aa + a\x{123}aa\>4 + 0: a + a\x{123}aa\>5 +No match + a\x{123}aa\>6 +Error -24 (bad offset value) + +/\x{1234}+/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \xe1 + +/\x{1234}+?/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \xe1 + +/\x{1234}++/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \xe1 + +/\x{1234}{2}/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 2 +Starting byte set: \xe1 + +/[^\x{c4}]/8DZ +------------------------------------------------------------------ + Bra + [^\x{c4}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/X+\x{200}/8DZ +------------------------------------------------------------------ + Bra + X++ + \x{200} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'X' +Need char = \x{80} + +/\R/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 + +/\777/8DZ +------------------------------------------------------------------ + Bra + \x{1ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c7} +Need char = \x{bf} + +/\w+\x{C4}/8BZ +------------------------------------------------------------------ + Bra + \w++ + \x{c4} + Ket + End +------------------------------------------------------------------ + a\x{C4}\x{C4} + 0: a\x{c4} + +/\w+\x{C4}/8BZT1 +------------------------------------------------------------------ + Bra + \w+ + \x{c4} + Ket + End +------------------------------------------------------------------ + a\x{C4}\x{C4} + 0: a\x{c4}\x{c4} + +/\W+\x{C4}/8BZ +------------------------------------------------------------------ + Bra + \W+ + \x{c4} + Ket + End +------------------------------------------------------------------ + !\x{C4} + 0: !\x{c4} + +/\W+\x{C4}/8BZT1 +------------------------------------------------------------------ + Bra + \W++ + \x{c4} + Ket + End +------------------------------------------------------------------ + !\x{C4} + 0: !\x{c4} + +/\W+\x{A1}/8BZ +------------------------------------------------------------------ + Bra + \W+ + \x{a1} + Ket + End +------------------------------------------------------------------ + !\x{A1} + 0: !\x{a1} + +/\W+\x{A1}/8BZT1 +------------------------------------------------------------------ + Bra + \W+ + \x{a1} + Ket + End +------------------------------------------------------------------ + !\x{A1} + 0: !\x{a1} + +/X\s+\x{A0}/8BZ +------------------------------------------------------------------ + Bra + X + \s++ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x20\x{A0}\x{A0} + 0: X \x{a0} + +/X\s+\x{A0}/8BZT1 +------------------------------------------------------------------ + Bra + X + \s+ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x20\x{A0}\x{A0} + 0: X \x{a0}\x{a0} + +/\S+\x{A0}/8BZ +------------------------------------------------------------------ + Bra + \S+ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x{A0}\x{A0} + 0: X\x{a0}\x{a0} + +/\S+\x{A0}/8BZT1 +------------------------------------------------------------------ + Bra + \S++ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x{A0}\x{A0} + 0: X\x{a0} + +/\x{a0}+\s!/8BZ +------------------------------------------------------------------ + Bra + \x{a0}++ + \s + ! + Ket + End +------------------------------------------------------------------ + \x{a0}\x20! + 0: \x{a0} ! + +/\x{a0}+\s!/8BZT1 +------------------------------------------------------------------ + Bra + \x{a0}+ + \s + ! + Ket + End +------------------------------------------------------------------ + \x{a0}\x20! + 0: \x{a0} ! + +/A/8 + \x{ff000041} +** Character \x{ff000041} is greater than 0x7fffffff and so cannot be converted to UTF-8 + \x{7f000041} +Error -10 (bad UTF-8 string) offset=0 reason=12 + +/-- End of testinput15 --/ diff --git a/tools/pcre/testdata/testoutput16 b/tools/pcre/testdata/testoutput16 new file mode 100644 index 00000000..1d5f31d9 --- /dev/null +++ b/tools/pcre/testdata/testoutput16 @@ -0,0 +1,121 @@ +/-- This set of tests is run only with the 8-bit library when Unicode property + support is available. It starts with tests of the POSIX interface, because + that is supported only with the 8-bit library. --/ + +/\w/P + +++\x{c2} +No match: POSIX code 17: match failed + +/\w/WP + +++\x{c2} + 0: \xc2 + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ +------------------------------------------------------------------ + Bra + /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +First char = 'A' (caseless) +No need char + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ +------------------------------------------------------------------ + Bra + A\x{391}\x{10427}\x{ff3a}\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = \x{b0} + +/AB\x{1fb0}/8DZ +------------------------------------------------------------------ + Bra + AB\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = \x{b0} + +/AB\x{1fb0}/8DZi +------------------------------------------------------------------ + Bra + /i AB\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +First char = 'A' (caseless) +Need char = 'B' (caseless) + +/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 17 +Starting byte set: \xd0 \xd1 + \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + 0: \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + 0: \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + +/[â±¥]/8iBZ +------------------------------------------------------------------ + Bra + /i \x{2c65} + Ket + End +------------------------------------------------------------------ + +/[^â±¥]/8iBZ +------------------------------------------------------------------ + Bra + /i [^\x{2c65}] + Ket + End +------------------------------------------------------------------ + +/\h/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x20 \xa0 + +/\v/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 + +/\R/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 + +/[[:blank:]]/WBZ +------------------------------------------------------------------ + Bra + [\x09 \xa0] + Ket + End +------------------------------------------------------------------ + +/-- End of testinput16 --/ diff --git a/tools/pcre/testdata/testoutput17 b/tools/pcre/testdata/testoutput17 new file mode 100644 index 00000000..ef82dc9d --- /dev/null +++ b/tools/pcre/testdata/testoutput17 @@ -0,0 +1,505 @@ +/-- This set of tests is for the 16- and 32-bit library's basic (non-UTF-16 + or -32) features that are not compatible with the 8-bit library, or which + give different output in 16- or 32-bit mode. --/ + +/a\Cb/ + aXb + 0: aXb + a\nb + 0: a\x0ab + +/[^\x{c4}]/DZ +------------------------------------------------------------------ + Bra + [^\x{c4}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/\x{100}/I +Capturing subpattern count = 0 +No options +First char = \x{100} +No need char + +/ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional leading comment +(?: (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # one word, optionally followed by.... +(?: +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... +\( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) | # comments, or... + +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +# quoted strings +)* +< (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # leading < +(?: @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* + +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* , (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +)* # further okay, if led by comma +: # closing colon +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* )? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address spec +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* > # trailing > +# name and address +) (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional trailing comment +/xSI +Capturing subpattern count = 0 +Contains explicit CR or LF match +Options: extended +No first char +No need char +Subject length lower bound = 3 +Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8 + 9 = ? A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ^ _ ` a b c d e + f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xff + +/[\h]/BZ +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] + Ket + End +------------------------------------------------------------------ + >\x09< + 0: \x09 + +/[\h]+/BZ +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]+ + Ket + End +------------------------------------------------------------------ + >\x09\x20\xa0< + 0: \x09 \xa0 + +/[\v]/BZ +------------------------------------------------------------------ + Bra + [\x0a-\x0d\x85\x{2028}-\x{2029}] + Ket + End +------------------------------------------------------------------ + +/[^\h]/BZ +------------------------------------------------------------------ + Bra + [^\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] + Ket + End +------------------------------------------------------------------ + +/\h+/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x20 \xa0 \xff + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + 0: \x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\xa0\x{2000} + 0: \x{200a}\xa0\x{2000} + +/[\h\x{dc00}]+/BZSI +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{dc00}]+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + 0: \x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\xa0\x{2000} + 0: \x{200a}\xa0\x{2000} + +/\H+/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + 0: \x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + 0: \x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + 0: \x{202e}\x{2030}\x{205e}\x{2060} + \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} + 0: \x9f\xa1\x{2fff}\x{3001} + +/[\H\x{d800}]+/ + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + 0: \x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + 0: \x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + 0: \x{202e}\x{2030}\x{205e}\x{2060} + \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} + 0: \x9f\xa1\x{2fff}\x{3001} + +/\v+/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + 0: \x85\x0a\x0b\x0c\x0d + +/[\v\x{dc00}]+/BZSI +------------------------------------------------------------------ + Bra + [\x0a-\x0d\x85\x{2028}-\x{2029}\x{dc00}]+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + 0: \x85\x0a\x0b\x0c\x0d + +/\V+/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + \x{2028}\x{2029}\x{2027}\x{2030} + 0: \x{2027}\x{2030} + \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 + 0: \x09\x0e\x84\x86 + +/[\V\x{d800}]+/ + \x{2028}\x{2029}\x{2027}\x{2030} + 0: \x{2027}\x{2030} + \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 + 0: \x09\x0e\x84\x86 + +/\R+/SI +Capturing subpattern count = 0 +Options: bsr_unicode +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + 0: \x85\x0a\x0b\x0c\x0d + +/\x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00}/I +Capturing subpattern count = 0 +No options +First char = \x{d800} +Need char = \x{dd00} + \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00} + 0: \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00} + +/[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZ +------------------------------------------------------------------ + Bra + [^\x80] + [^\x{ff}] + [^\x{100}] + [^\x{1000}] + [^\x{ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZi +------------------------------------------------------------------ + Bra + /i [^\x80] + /i [^\x{ff}] + /i [^\x{100}] + /i [^\x{1000}] + /i [^\x{ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZ +------------------------------------------------------------------ + Bra + [^\x{100}]* + [^\x{1000}]+ + [^\x{ffff}]?? + [^\x{8000}]{4} + [^\x{8000}]* + [^\x{7fff}]{2} + [^\x{7fff}]{0,7}? + [^\x{100}]{5} + [^\x{100}]?+ + Ket + End +------------------------------------------------------------------ + +/[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZi +------------------------------------------------------------------ + Bra + /i [^\x{100}]* + /i [^\x{1000}]+ + /i [^\x{ffff}]?? + /i [^\x{8000}]{4} + /i [^\x{8000}]* + /i [^\x{7fff}]{2} + /i [^\x{7fff}]{0,7}? + 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 +------------------------------------------------------------------ + +/^\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 testinput17 --/ diff --git a/tools/pcre/testdata/testoutput18-16 b/tools/pcre/testdata/testoutput18-16 new file mode 100644 index 00000000..50a8301d --- /dev/null +++ b/tools/pcre/testdata/testoutput18-16 @@ -0,0 +1,1022 @@ +/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to the + 16- and 32-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 used as input in UTF mode + +/X(\C{3})/8 + X\x{11234}Y + 0: X\x{11234}Y + 1: \x{11234}Y + X\x{11234}YZ + 0: X\x{11234}Y + 1: \x{11234}Y + +/X(\C{4})/8 + X\x{11234}YZ + 0: X\x{11234}YZ + 1: \x{11234}YZ + X\x{11234}YZW + 0: X\x{11234}YZ + 1: \x{11234}YZ + +/X\C*/8 + XYZabcdce + 0: XYZabcdce + +/X\C*?/8 + XYZabcde + 0: X + +/X\C{3,5}/8 + Xabcdefg + 0: Xabcde + X\x{11234}Y + 0: X\x{11234}Y + X\x{11234}YZ + 0: X\x{11234}YZ + X\x{11234}\x{512} + 0: X\x{11234}\x{512} + X\x{11234}\x{512}YZ + 0: X\x{11234}\x{512}YZ + X\x{11234}\x{512}\x{11234}Z + 0: X\x{11234}\x{512}\x{11234} + +/X\C{3,5}?/8 + Xabcdefg + 0: Xabc + X\x{11234}Y + 0: X\x{11234}Y + X\x{11234}YZ + 0: X\x{11234}Y + X\x{11234}\x{512}YZ + 0: X\x{11234}\x{512} + *** Failers +No match + X\x{11234} +No match + +/a\Cb/8 + aXb + 0: aXb + a\nb + 0: a\x{0a}b + +/a\C\Cb/8 + a\x{12257}b + 0: a\x{12257}b + a\x{12257}\x{11234}b +No match + ** Failers +No match + a\x{100}b +No match + +/ab\Cde/8 + abXde + 0: abXde + +/-- Check maximum character size --/ + +/\x{ffff}/8DZ +------------------------------------------------------------------ + Bra + \x{ffff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ffff} +No need char + +/\x{10000}/8DZ +------------------------------------------------------------------ + Bra + \x{10000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d800} +Need char = \x{dc00} + +/\x{100}/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + +/\x{1000}/8DZ +------------------------------------------------------------------ + Bra + \x{1000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{1000} +No need char + +/\x{10000}/8DZ +------------------------------------------------------------------ + Bra + \x{10000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d800} +Need char = \x{dc00} + +/\x{100000}/8DZ +------------------------------------------------------------------ + Bra + \x{100000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{dbc0} +Need char = \x{dc00} + +/\x{10ffff}/8DZ +------------------------------------------------------------------ + Bra + \x{10ffff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{dbff} +Need char = \x{dfff} + +/[\x{ff}]/8DZ +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ff} +No need char + +/[\x{100}]/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + +/\x80/8DZ +------------------------------------------------------------------ + Bra + \x80 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{80} +No need char + +/\xff/8DZ +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ff} +No need char + +/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 +------------------------------------------------------------------ + Bra + \x{d55c}\x{ad6d}\x{c5b4} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d55c} +Need char = \x{c5b4} + \x{D55c}\x{ad6d}\x{C5B4} + 0: \x{d55c}\x{ad6d}\x{c5b4} + +/\x{65e5}\x{672c}\x{8a9e}/DZ8 +------------------------------------------------------------------ + Bra + \x{65e5}\x{672c}\x{8a9e} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{65e5} +Need char = \x{8a9e} + \x{65e5}\x{672c}\x{8a9e} + 0: \x{65e5}\x{672c}\x{8a9e} + +/\x{80}/DZ8 +------------------------------------------------------------------ + Bra + \x80 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{80} +No need char + +/\x{084}/DZ8 +------------------------------------------------------------------ + Bra + \x{84} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{84} +No need char + +/\x{104}/DZ8 +------------------------------------------------------------------ + Bra + \x{104} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{104} +No need char + +/\x{861}/DZ8 +------------------------------------------------------------------ + Bra + \x{861} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{861} +No need char + +/\x{212ab}/DZ8 +------------------------------------------------------------------ + Bra + \x{212ab} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d844} +Need char = \x{deab} + +/-- This one is here not because it's different to Perl, but because the way +the captured single-byte is displayed. (In Perl it becomes a character, and you +can't tell the difference.) --/ + +/X(\C)(.*)/8 + X\x{1234} + 0: X\x{1234} + 1: \x{1234} + 2: + X\nabc + 0: X\x{0a}abc + 1: \x{0a} + 2: abc + +/-- This one is here because Perl gives out a grumbly error message (quite +correctly, but that messes up comparisons). --/ + +/a\Cb/8 + *** Failers +No match + a\x{100}b + 0: a\x{100}b + +/[^ab\xC0-\xF0]/8SDZ +------------------------------------------------------------------ + Bra + [\x00-`c-\xbf\xf1-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a + \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 + \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 + 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y + Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f + \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e + \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d + \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac + \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb + \xbc \xbd \xbe \xbf \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb + \xfc \xfd \xfe \xff + \x{f1} + 0: \x{f1} + \x{bf} + 0: \x{bf} + \x{100} + 0: \x{100} + \x{1000} + 0: \x{1000} + *** Failers + 0: * + \x{c0} +No match + \x{f0} +No match + +/Ä€{3,4}/8SDZ +------------------------------------------------------------------ + Bra + \x{100}{3} + \x{100}? + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +Need char = \x{100} +Subject length lower bound = 3 +No set of starting bytes + \x{100}\x{100}\x{100}\x{100\x{100} + 0: \x{100}\x{100}\x{100} + +/(\x{100}+|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}+ + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x \xff + +/(\x{100}*a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}*+ + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a x \xff + +/(\x{100}{0,2}a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}{0,2} + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a x \xff + +/(\x{100}{1,2}a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100} + \x{100}{0,1} + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x \xff + +/\x{100}/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + +/a\x{100}\x{101}*/8DZ +------------------------------------------------------------------ + Bra + a\x{100} + \x{101}* + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = \x{100} + +/a\x{100}\x{101}+/8DZ +------------------------------------------------------------------ + Bra + a\x{100} + \x{101}+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = \x{101} + +/[^\x{c4}]/DZ +------------------------------------------------------------------ + Bra + [^\x{c4}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[\x{100}]/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + \x{100} + 0: \x{100} + Z\x{100} + 0: \x{100} + \x{100}Z + 0: \x{100} + *** Failers +No match + +/[\xff]/DZ8 +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ff} +No need char + >\x{ff}< + 0: \x{ff} + +/[^\xff]/8DZ +------------------------------------------------------------------ + Bra + [^\x{ff}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/\x{100}abc(xyz(?1))/8DZ +------------------------------------------------------------------ + Bra + \x{100}abc + CBra 1 + xyz + Recurse + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +First char = \x{100} +Need char = 'z' + +/\777/8I +Capturing subpattern count = 0 +Options: utf +First char = \x{1ff} +No need char + \x{1ff} + 0: \x{1ff} + \777 + 0: \x{1ff} + +/\x{100}+\x{200}/8DZ +------------------------------------------------------------------ + Bra + \x{100}++ + \x{200} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +Need char = \x{200} + +/\x{100}+X/8DZ +------------------------------------------------------------------ + Bra + \x{100}++ + X + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +Need char = 'X' + +/^[\QÄ€\E-\QÅ\E/BZ8 +Failed: missing terminating ] for character class at offset 13 + +/X/8 + \x{0}\x{d7ff}\x{e000}\x{10ffff} +Error -10 (bad UTF-16 string) offset=4 reason=4 + \x{d800} +Error -10 (bad UTF-16 string) offset=0 reason=1 + \x{d800}\? +No match + \x{da00} +Error -10 (bad UTF-16 string) offset=0 reason=1 + \x{da00}\? +No match + \x{dc00} +Error -10 (bad UTF-16 string) offset=0 reason=3 + \x{dc00}\? +No match + \x{de00} +Error -10 (bad UTF-16 string) offset=0 reason=3 + \x{de00}\? +No match + \x{dfff} +Error -10 (bad UTF-16 string) offset=0 reason=3 + \x{dfff}\? +No match + \x{110000} +** Failed: character \x{110000} is greater than 0x10ffff and so cannot be converted to UTF-16 + \x{d800}\x{1234} +Error -10 (bad UTF-16 string) offset=1 reason=2 + \x{fffe} +Error -10 (bad UTF-16 string) offset=0 reason=4 + +/(*UTF16)\x{11234}/ + abcd\x{11234}pqr + 0: \x{11234} + +/(*UTF)\x{11234}/I +Capturing subpattern count = 0 +Options: utf +First char = \x{d804} +Need char = \x{de34} + abcd\x{11234}pqr + 0: \x{11234} + +/(*UTF-32)\x{11234}/ +Failed: (*VERB) not recognized at offset 5 + +/(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I +Capturing subpattern count = 0 +Options: bsr_unicode utf +Forced newline sequence: CRLF +First char = 'a' +Need char = 'b' + +/(*CRLF)(*UTF32)(*BSR_UNICODE)a\Rb/I +Failed: (*VERB) not recognized at offset 12 + +/\h/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x20 \xa0 \xff + ABC\x{09} + 0: \x{09} + ABC\x{20} + 0: + ABC\x{a0} + 0: \x{a0} + ABC\x{1680} + 0: \x{1680} + ABC\x{180e} + 0: \x{180e} + ABC\x{2000} + 0: \x{2000} + ABC\x{202f} + 0: \x{202f} + ABC\x{205f} + 0: \x{205f} + ABC\x{3000} + 0: \x{3000} + +/\v/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + ABC\x{0a} + 0: \x{0a} + ABC\x{0b} + 0: \x{0b} + ABC\x{0c} + 0: \x{0c} + ABC\x{0d} + 0: \x{0d} + ABC\x{85} + 0: \x{85} + ABC\x{2028} + 0: \x{2028} + +/\h*A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 1 +Starting byte set: \x09 \x20 A \xa0 \xff + CDBABC + 0: A + \x{2000}ABC + 0: \x{2000}A + +/\R*A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d A \x85 \xff + CDBABC + 0: A + \x{2028}A + 0: \x{2028}A + +/\v+A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 2 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + +/\s?xxx\s/8SI +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'x' +Subject length lower bound = 4 +Starting byte set: \x09 \x0a \x0c \x0d \x20 x + +/\sxxx\s/I8ST1 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'x' +Subject length lower bound = 5 +Starting byte set: \x09 \x0a \x0c \x0d \x20 \x85 \xa0 + AB\x{85}xxx\x{a0}XYZ + 0: \x{85}xxx\x{a0} + AB\x{a0}xxx\x{85}XYZ + 0: \x{a0}xxx\x{85} + +/\S \S/I8ST1 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = ' ' +Subject length lower bound = 3 +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e + \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d + \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ + A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e + f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83 + \x84 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 + \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa1 \xa2 \xa3 + \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2 + \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 \xc1 + \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 + \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf + \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee + \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd + \xfe \xff + \x{a2} \x{84} + 0: \x{a2} \x{84} + A Z + 0: A Z + +/a+/8 + a\x{123}aa\>1 + 0: aa + a\x{123}aa\>2 + 0: aa + a\x{123}aa\>3 + 0: a + a\x{123}aa\>4 +No match + a\x{123}aa\>5 +Error -24 (bad offset value) + a\x{123}aa\>6 +Error -24 (bad offset value) + +/\x{1234}+/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +No need char +Subject length lower bound = 1 +No set of starting bytes + +/\x{1234}+?/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +No need char +Subject length lower bound = 1 +No set of starting bytes + +/\x{1234}++/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +No need char +Subject length lower bound = 1 +No set of starting bytes + +/\x{1234}{2}/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +Need char = \x{1234} +Subject length lower bound = 2 +No set of starting bytes + +/[^\x{c4}]/8DZ +------------------------------------------------------------------ + Bra + [^\x{c4}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/X+\x{200}/8DZ +------------------------------------------------------------------ + Bra + X++ + \x{200} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'X' +Need char = \x{200} + +/\R/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + +/-- Check bad offset --/ + +/a/8 + \x{10000}\>1 +Error -11 (bad UTF-16 offset) + \x{10000}ab\>1 +Error -11 (bad UTF-16 offset) + \x{10000}ab\>2 + 0: a + \x{10000}ab\>3 +No match + \x{10000}ab\>4 +No match + \x{10000}ab\>5 +Error -24 (bad offset value) + +/í¼€/8 +Failed: invalid UTF-16 string at offset 0 + +/\w+\x{C4}/8BZ +------------------------------------------------------------------ + Bra + \w++ + \x{c4} + Ket + End +------------------------------------------------------------------ + a\x{C4}\x{C4} + 0: a\x{c4} + +/\w+\x{C4}/8BZT1 +------------------------------------------------------------------ + Bra + \w+ + \x{c4} + Ket + End +------------------------------------------------------------------ + a\x{C4}\x{C4} + 0: a\x{c4}\x{c4} + +/\W+\x{C4}/8BZ +------------------------------------------------------------------ + Bra + \W+ + \x{c4} + Ket + End +------------------------------------------------------------------ + !\x{C4} + 0: !\x{c4} + +/\W+\x{C4}/8BZT1 +------------------------------------------------------------------ + Bra + \W++ + \x{c4} + Ket + End +------------------------------------------------------------------ + !\x{C4} + 0: !\x{c4} + +/\W+\x{A1}/8BZ +------------------------------------------------------------------ + Bra + \W+ + \x{a1} + Ket + End +------------------------------------------------------------------ + !\x{A1} + 0: !\x{a1} + +/\W+\x{A1}/8BZT1 +------------------------------------------------------------------ + Bra + \W+ + \x{a1} + Ket + End +------------------------------------------------------------------ + !\x{A1} + 0: !\x{a1} + +/X\s+\x{A0}/8BZ +------------------------------------------------------------------ + Bra + X + \s++ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x20\x{A0}\x{A0} + 0: X \x{a0} + +/X\s+\x{A0}/8BZT1 +------------------------------------------------------------------ + Bra + X + \s+ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x20\x{A0}\x{A0} + 0: X \x{a0}\x{a0} + +/\S+\x{A0}/8BZ +------------------------------------------------------------------ + Bra + \S+ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x{A0}\x{A0} + 0: X\x{a0}\x{a0} + +/\S+\x{A0}/8BZT1 +------------------------------------------------------------------ + Bra + \S++ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x{A0}\x{A0} + 0: X\x{a0} + +/\x{a0}+\s!/8BZ +------------------------------------------------------------------ + Bra + \x{a0}++ + \s + ! + Ket + End +------------------------------------------------------------------ + \x{a0}\x20! + 0: \x{a0} ! + +/\x{a0}+\s!/8BZT1 +------------------------------------------------------------------ + Bra + \x{a0}+ + \s + ! + Ket + End +------------------------------------------------------------------ + \x{a0}\x20! + 0: \x{a0} ! + +/-- End of testinput18 --/ diff --git a/tools/pcre/testdata/testoutput18-32 b/tools/pcre/testdata/testoutput18-32 new file mode 100644 index 00000000..334fae0c --- /dev/null +++ b/tools/pcre/testdata/testoutput18-32 @@ -0,0 +1,1019 @@ +/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to the + 16- and 32-bit library. --/ + +/ÃÃÃxxx/8?DZSS +**Failed: invalid UTF-8 string cannot be converted to UTF-32 + +/abc/8 + Ã] +**Failed: invalid UTF-8 string cannot be used as input in UTF mode + +/X(\C{3})/8 + X\x{11234}Y +No match + X\x{11234}YZ + 0: X\x{11234}YZ + 1: \x{11234}YZ + +/X(\C{4})/8 + X\x{11234}YZ +No match + X\x{11234}YZW + 0: X\x{11234}YZW + 1: \x{11234}YZW + +/X\C*/8 + XYZabcdce + 0: XYZabcdce + +/X\C*?/8 + XYZabcde + 0: X + +/X\C{3,5}/8 + Xabcdefg + 0: Xabcde + X\x{11234}Y +No match + X\x{11234}YZ + 0: X\x{11234}YZ + X\x{11234}\x{512} +No match + X\x{11234}\x{512}YZ + 0: X\x{11234}\x{512}YZ + X\x{11234}\x{512}\x{11234}Z + 0: X\x{11234}\x{512}\x{11234}Z + +/X\C{3,5}?/8 + Xabcdefg + 0: Xabc + X\x{11234}Y +No match + X\x{11234}YZ + 0: X\x{11234}YZ + X\x{11234}\x{512}YZ + 0: X\x{11234}\x{512}Y + *** Failers +No match + X\x{11234} +No match + +/a\Cb/8 + aXb + 0: aXb + a\nb + 0: a\x{0a}b + +/a\C\Cb/8 + a\x{12257}b +No match + a\x{12257}\x{11234}b + 0: a\x{12257}\x{11234}b + ** Failers +No match + a\x{100}b +No match + +/ab\Cde/8 + abXde + 0: abXde + +/-- Check maximum character size --/ + +/\x{ffff}/8DZ +------------------------------------------------------------------ + Bra + \x{ffff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ffff} +No need char + +/\x{10000}/8DZ +------------------------------------------------------------------ + Bra + \x{10000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{10000} +No need char + +/\x{100}/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + +/\x{1000}/8DZ +------------------------------------------------------------------ + Bra + \x{1000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{1000} +No need char + +/\x{10000}/8DZ +------------------------------------------------------------------ + Bra + \x{10000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{10000} +No need char + +/\x{100000}/8DZ +------------------------------------------------------------------ + Bra + \x{100000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100000} +No need char + +/\x{10ffff}/8DZ +------------------------------------------------------------------ + Bra + \x{10ffff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{10ffff} +No need char + +/[\x{ff}]/8DZ +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ff} +No need char + +/[\x{100}]/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + +/\x80/8DZ +------------------------------------------------------------------ + Bra + \x80 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{80} +No need char + +/\xff/8DZ +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ff} +No need char + +/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 +------------------------------------------------------------------ + Bra + \x{d55c}\x{ad6d}\x{c5b4} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d55c} +Need char = \x{c5b4} + \x{D55c}\x{ad6d}\x{C5B4} + 0: \x{d55c}\x{ad6d}\x{c5b4} + +/\x{65e5}\x{672c}\x{8a9e}/DZ8 +------------------------------------------------------------------ + Bra + \x{65e5}\x{672c}\x{8a9e} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{65e5} +Need char = \x{8a9e} + \x{65e5}\x{672c}\x{8a9e} + 0: \x{65e5}\x{672c}\x{8a9e} + +/\x{80}/DZ8 +------------------------------------------------------------------ + Bra + \x80 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{80} +No need char + +/\x{084}/DZ8 +------------------------------------------------------------------ + Bra + \x{84} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{84} +No need char + +/\x{104}/DZ8 +------------------------------------------------------------------ + Bra + \x{104} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{104} +No need char + +/\x{861}/DZ8 +------------------------------------------------------------------ + Bra + \x{861} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{861} +No need char + +/\x{212ab}/DZ8 +------------------------------------------------------------------ + Bra + \x{212ab} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{212ab} +No need char + +/-- This one is here not because it's different to Perl, but because the way +the captured single-byte is displayed. (In Perl it becomes a character, and you +can't tell the difference.) --/ + +/X(\C)(.*)/8 + X\x{1234} + 0: X\x{1234} + 1: \x{1234} + 2: + X\nabc + 0: X\x{0a}abc + 1: \x{0a} + 2: abc + +/-- This one is here because Perl gives out a grumbly error message (quite +correctly, but that messes up comparisons). --/ + +/a\Cb/8 + *** Failers +No match + a\x{100}b + 0: a\x{100}b + +/[^ab\xC0-\xF0]/8SDZ +------------------------------------------------------------------ + Bra + [\x00-`c-\xbf\xf1-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a + \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 + \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 + 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y + Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f + \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e + \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d + \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac + \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb + \xbc \xbd \xbe \xbf \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb + \xfc \xfd \xfe \xff + \x{f1} + 0: \x{f1} + \x{bf} + 0: \x{bf} + \x{100} + 0: \x{100} + \x{1000} + 0: \x{1000} + *** Failers + 0: * + \x{c0} +No match + \x{f0} +No match + +/Ä€{3,4}/8SDZ +------------------------------------------------------------------ + Bra + \x{100}{3} + \x{100}? + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +Need char = \x{100} +Subject length lower bound = 3 +No set of starting bytes + \x{100}\x{100}\x{100}\x{100\x{100} + 0: \x{100}\x{100}\x{100} + +/(\x{100}+|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}+ + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x \xff + +/(\x{100}*a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}*+ + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a x \xff + +/(\x{100}{0,2}a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}{0,2} + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a x \xff + +/(\x{100}{1,2}a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100} + \x{100}{0,1} + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x \xff + +/\x{100}/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + +/a\x{100}\x{101}*/8DZ +------------------------------------------------------------------ + Bra + a\x{100} + \x{101}* + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = \x{100} + +/a\x{100}\x{101}+/8DZ +------------------------------------------------------------------ + Bra + a\x{100} + \x{101}+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = \x{101} + +/[^\x{c4}]/DZ +------------------------------------------------------------------ + Bra + [^\x{c4}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[\x{100}]/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + \x{100} + 0: \x{100} + Z\x{100} + 0: \x{100} + \x{100}Z + 0: \x{100} + *** Failers +No match + +/[\xff]/DZ8 +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ff} +No need char + >\x{ff}< + 0: \x{ff} + +/[^\xff]/8DZ +------------------------------------------------------------------ + Bra + [^\x{ff}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/\x{100}abc(xyz(?1))/8DZ +------------------------------------------------------------------ + Bra + \x{100}abc + CBra 1 + xyz + Recurse + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +First char = \x{100} +Need char = 'z' + +/\777/8I +Capturing subpattern count = 0 +Options: utf +First char = \x{1ff} +No need char + \x{1ff} + 0: \x{1ff} + \777 + 0: \x{1ff} + +/\x{100}+\x{200}/8DZ +------------------------------------------------------------------ + Bra + \x{100}++ + \x{200} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +Need char = \x{200} + +/\x{100}+X/8DZ +------------------------------------------------------------------ + Bra + \x{100}++ + X + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +Need char = 'X' + +/^[\QÄ€\E-\QÅ\E/BZ8 +Failed: missing terminating ] for character class at offset 13 + +/X/8 + \x{0}\x{d7ff}\x{e000}\x{10ffff} +Error -10 (bad UTF-32 string) offset=3 reason=2 + \x{d800} +Error -10 (bad UTF-32 string) offset=0 reason=1 + \x{d800}\? +No match + \x{da00} +Error -10 (bad UTF-32 string) offset=0 reason=1 + \x{da00}\? +No match + \x{dc00} +Error -10 (bad UTF-32 string) offset=0 reason=1 + \x{dc00}\? +No match + \x{de00} +Error -10 (bad UTF-32 string) offset=0 reason=1 + \x{de00}\? +No match + \x{dfff} +Error -10 (bad UTF-32 string) offset=0 reason=1 + \x{dfff}\? +No match + \x{110000} +Error -10 (bad UTF-32 string) offset=0 reason=3 + \x{d800}\x{1234} +Error -10 (bad UTF-32 string) offset=0 reason=1 + \x{fffe} +Error -10 (bad UTF-32 string) offset=0 reason=2 + +/(*UTF16)\x{11234}/ +Failed: (*VERB) not recognized at offset 5 + +/(*UTF)\x{11234}/I +Capturing subpattern count = 0 +Options: utf +First char = \x{11234} +No need char + abcd\x{11234}pqr + 0: \x{11234} + +/(*UTF-32)\x{11234}/ +Failed: (*VERB) not recognized at offset 5 + +/(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I +Failed: (*VERB) not recognized at offset 12 + +/(*CRLF)(*UTF32)(*BSR_UNICODE)a\Rb/I +Capturing subpattern count = 0 +Options: bsr_unicode utf +Forced newline sequence: CRLF +First char = 'a' +Need char = 'b' + +/\h/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x20 \xa0 \xff + ABC\x{09} + 0: \x{09} + ABC\x{20} + 0: + ABC\x{a0} + 0: \x{a0} + ABC\x{1680} + 0: \x{1680} + ABC\x{180e} + 0: \x{180e} + ABC\x{2000} + 0: \x{2000} + ABC\x{202f} + 0: \x{202f} + ABC\x{205f} + 0: \x{205f} + ABC\x{3000} + 0: \x{3000} + +/\v/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + ABC\x{0a} + 0: \x{0a} + ABC\x{0b} + 0: \x{0b} + ABC\x{0c} + 0: \x{0c} + ABC\x{0d} + 0: \x{0d} + ABC\x{85} + 0: \x{85} + ABC\x{2028} + 0: \x{2028} + +/\h*A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 1 +Starting byte set: \x09 \x20 A \xa0 \xff + CDBABC + 0: A + \x{2000}ABC + 0: \x{2000}A + +/\R*A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d A \x85 \xff + CDBABC + 0: A + \x{2028}A + 0: \x{2028}A + +/\v+A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 2 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + +/\s?xxx\s/8SI +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'x' +Subject length lower bound = 4 +Starting byte set: \x09 \x0a \x0c \x0d \x20 x + +/\sxxx\s/I8ST1 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'x' +Subject length lower bound = 5 +Starting byte set: \x09 \x0a \x0c \x0d \x20 \x85 \xa0 + AB\x{85}xxx\x{a0}XYZ + 0: \x{85}xxx\x{a0} + AB\x{a0}xxx\x{85}XYZ + 0: \x{a0}xxx\x{85} + +/\S \S/I8ST1 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = ' ' +Subject length lower bound = 3 +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e + \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d + \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ + A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e + f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83 + \x84 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 + \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa1 \xa2 \xa3 + \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2 + \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 \xc1 + \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 + \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf + \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee + \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd + \xfe \xff + \x{a2} \x{84} + 0: \x{a2} \x{84} + A Z + 0: A Z + +/a+/8 + a\x{123}aa\>1 + 0: aa + a\x{123}aa\>2 + 0: aa + a\x{123}aa\>3 + 0: a + a\x{123}aa\>4 +No match + a\x{123}aa\>5 +Error -24 (bad offset value) + a\x{123}aa\>6 +Error -24 (bad offset value) + +/\x{1234}+/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +No need char +Subject length lower bound = 1 +No set of starting bytes + +/\x{1234}+?/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +No need char +Subject length lower bound = 1 +No set of starting bytes + +/\x{1234}++/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +No need char +Subject length lower bound = 1 +No set of starting bytes + +/\x{1234}{2}/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +Need char = \x{1234} +Subject length lower bound = 2 +No set of starting bytes + +/[^\x{c4}]/8DZ +------------------------------------------------------------------ + Bra + [^\x{c4}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/X+\x{200}/8DZ +------------------------------------------------------------------ + Bra + X++ + \x{200} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'X' +Need char = \x{200} + +/\R/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + +/-- Check bad offset --/ + +/a/8 + \x{10000}\>1 +No match + \x{10000}ab\>1 + 0: a + \x{10000}ab\>2 +No match + \x{10000}ab\>3 +No match + \x{10000}ab\>4 +Error -24 (bad offset value) + \x{10000}ab\>5 +Error -24 (bad offset value) + +/í¼€/8 +**Failed: character value is ill-formed UTF-32 + +/\w+\x{C4}/8BZ +------------------------------------------------------------------ + Bra + \w++ + \x{c4} + Ket + End +------------------------------------------------------------------ + a\x{C4}\x{C4} + 0: a\x{c4} + +/\w+\x{C4}/8BZT1 +------------------------------------------------------------------ + Bra + \w+ + \x{c4} + Ket + End +------------------------------------------------------------------ + a\x{C4}\x{C4} + 0: a\x{c4}\x{c4} + +/\W+\x{C4}/8BZ +------------------------------------------------------------------ + Bra + \W+ + \x{c4} + Ket + End +------------------------------------------------------------------ + !\x{C4} + 0: !\x{c4} + +/\W+\x{C4}/8BZT1 +------------------------------------------------------------------ + Bra + \W++ + \x{c4} + Ket + End +------------------------------------------------------------------ + !\x{C4} + 0: !\x{c4} + +/\W+\x{A1}/8BZ +------------------------------------------------------------------ + Bra + \W+ + \x{a1} + Ket + End +------------------------------------------------------------------ + !\x{A1} + 0: !\x{a1} + +/\W+\x{A1}/8BZT1 +------------------------------------------------------------------ + Bra + \W+ + \x{a1} + Ket + End +------------------------------------------------------------------ + !\x{A1} + 0: !\x{a1} + +/X\s+\x{A0}/8BZ +------------------------------------------------------------------ + Bra + X + \s++ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x20\x{A0}\x{A0} + 0: X \x{a0} + +/X\s+\x{A0}/8BZT1 +------------------------------------------------------------------ + Bra + X + \s+ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x20\x{A0}\x{A0} + 0: X \x{a0}\x{a0} + +/\S+\x{A0}/8BZ +------------------------------------------------------------------ + Bra + \S+ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x{A0}\x{A0} + 0: X\x{a0}\x{a0} + +/\S+\x{A0}/8BZT1 +------------------------------------------------------------------ + Bra + \S++ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x{A0}\x{A0} + 0: X\x{a0} + +/\x{a0}+\s!/8BZ +------------------------------------------------------------------ + Bra + \x{a0}++ + \s + ! + Ket + End +------------------------------------------------------------------ + \x{a0}\x20! + 0: \x{a0} ! + +/\x{a0}+\s!/8BZT1 +------------------------------------------------------------------ + Bra + \x{a0}+ + \s + ! + Ket + End +------------------------------------------------------------------ + \x{a0}\x20! + 0: \x{a0} ! + +/-- End of testinput18 --/ diff --git a/tools/pcre/testdata/testoutput19 b/tools/pcre/testdata/testoutput19 new file mode 100644 index 00000000..ccc198cc --- /dev/null +++ b/tools/pcre/testdata/testoutput19 @@ -0,0 +1,88 @@ +/-- This set of tests is for Unicode property support, relevant only to the + 16- and 32-bit library. --/ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ +------------------------------------------------------------------ + Bra + /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +First char = 'A' (caseless) +Need char = \x{1fb0} (caseless) + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ +------------------------------------------------------------------ + Bra + A\x{391}\x{10427}\x{ff3a}\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = \x{1fb0} + +/AB\x{1fb0}/8DZ +------------------------------------------------------------------ + Bra + AB\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = \x{1fb0} + +/AB\x{1fb0}/8DZi +------------------------------------------------------------------ + Bra + /i AB\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +First char = 'A' (caseless) +Need char = \x{1fb0} (caseless) + +/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{401} (caseless) +Need char = \x{42f} (caseless) +Subject length lower bound = 17 +No set of starting bytes + \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + 0: \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + 0: \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + +/[â±¥]/8iBZ +------------------------------------------------------------------ + Bra + /i \x{2c65} + Ket + End +------------------------------------------------------------------ + +/[^â±¥]/8iBZ +------------------------------------------------------------------ + Bra + /i [^\x{2c65}] + Ket + End +------------------------------------------------------------------ + +/[[:blank:]]/WBZ +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] + Ket + End +------------------------------------------------------------------ + +/-- End of testinput19 --/ diff --git a/tools/pcre/testdata/testoutput2 b/tools/pcre/testdata/testoutput2 new file mode 100644 index 00000000..e9cddf80 --- /dev/null +++ b/tools/pcre/testdata/testoutput2 @@ -0,0 +1,12484 @@ +/-- This set of tests is not Perl-compatible. It checks on special features + of PCRE's API, error diagnostics, and the compiled code of some patterns. + 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. + + 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. --/ + +/(a)b|/I +Capturing subpattern count = 1 +No options +No first char +No need char + +/abc/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + abc + 0: abc + defabc + 0: abc + \Aabc + 0: abc + *** Failers +No match + \Adefabc +No match + ABC +No match + +/^abc/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + abc + 0: abc + \Aabc + 0: abc + *** Failers +No match + defabc +No match + \Adefabc +No match + +/a+bc/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + +/a*bc/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'c' + +/a{3}bc/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + +/(abc|a+z)/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/^abc$/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + abc + 0: abc + *** Failers +No match + def\nabc +No match + +/ab\idef/X +Failed: unrecognized character follows \ at offset 3 + +/(?X)ab\idef/X +Failed: unrecognized character follows \ at offset 7 + +/x{5,4}/ +Failed: numbers out of order in {} quantifier at offset 5 + +/z{65536}/ +Failed: number too big in {} quantifier at offset 7 + +/[abcd/ +Failed: missing terminating ] for character class at offset 5 + +/(?X)[\B]/ +Failed: invalid escape sequence in character class at offset 6 + +/(?X)[\R]/ +Failed: invalid escape sequence in character class at offset 6 + +/(?X)[\X]/ +Failed: invalid escape sequence in character class at offset 6 + +/[\B]/BZ +------------------------------------------------------------------ + Bra + B + Ket + End +------------------------------------------------------------------ + +/[\R]/BZ +------------------------------------------------------------------ + Bra + R + Ket + End +------------------------------------------------------------------ + +/[\X]/BZ +------------------------------------------------------------------ + Bra + X + Ket + End +------------------------------------------------------------------ + +/[z-a]/ +Failed: range out of order in character class at offset 3 + +/^*/ +Failed: nothing to repeat at offset 1 + +/(abc/ +Failed: missing ) at offset 4 + +/(?# abc/ +Failed: missing ) after comment at offset 7 + +/(?z)abc/ +Failed: unrecognized character after (? or (?- at offset 2 + +/.*b/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +Need char = 'b' + +/.*?b/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +Need char = 'b' + +/cat|dog|elephant/I +Capturing subpattern count = 0 +No options +No first char +No need char + this sentence eventually mentions a cat + 0: cat + this sentences rambles on and on for a while and then reaches elephant + 0: elephant + +/cat|dog|elephant/IS +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 3 +Starting byte set: c d e + this sentence eventually mentions a cat + 0: cat + this sentences rambles on and on for a while and then reaches elephant + 0: elephant + +/cat|dog|elephant/IiS +Capturing subpattern count = 0 +Options: caseless +No first char +No need char +Subject length lower bound = 3 +Starting byte set: C D E c d e + this sentence eventually mentions a CAT cat + 0: CAT + this sentences rambles on and on for a while to elephant ElePhant + 0: elephant + +/a|[bcd]/IS +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a b c d + +/(a|[^\dZ])/IS +Capturing subpattern count = 1 +No options +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 ! " # $ % & ' ( ) * + , - . / : ; < = > + ? @ 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 [ \ ] ^ _ ` 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 \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 + +/(a|b)*[\s]/IS +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x0a \x0c \x0d \x20 a b + +/(ab\2)/ +Failed: reference to non-existent subpattern at offset 6 + +/{4,5}abc/ +Failed: nothing to repeat at offset 4 + +/(a)(b)(c)\2/I +Capturing subpattern count = 3 +Max back reference = 2 +No options +First char = 'a' +Need char = 'c' + abcb + 0: abcb + 1: a + 2: b + 3: c + \O0abcb +Matched, but too many substrings + \O3abcb +Matched, but too many substrings + 0: abcb + \O6abcb +Matched, but too many substrings + 0: abcb + 1: a + \O9abcb +Matched, but too many substrings + 0: abcb + 1: a + 2: b + \O12abcb + 0: abcb + 1: a + 2: b + 3: c + +/(a)bc|(a)(b)\2/I +Capturing subpattern count = 3 +Max back reference = 2 +No options +First char = 'a' +No need char + abc + 0: abc + 1: a + \O0abc +Matched, but too many substrings + \O3abc +Matched, but too many substrings + 0: abc + \O6abc + 0: abc + 1: a + aba + 0: aba + 1: + 2: a + 3: b + \O0aba +Matched, but too many substrings + \O3aba +Matched, but too many substrings + 0: aba + \O6aba +Matched, but too many substrings + 0: aba + 1: + \O9aba +Matched, but too many substrings + 0: aba + 1: + 2: a + \O12aba + 0: aba + 1: + 2: a + 3: b + +/abc$/IE +Capturing subpattern count = 0 +Options: dollar_endonly +First char = 'a' +Need char = 'c' + abc + 0: abc + *** Failers +No match + abc\n +No match + abc\ndef +No match + +/(a)(b)(c)(d)(e)\6/ +Failed: reference to non-existent subpattern at offset 17 + +/the quick brown fox/I +Capturing subpattern count = 0 +No options +First char = 't' +Need char = 'x' + the quick brown fox + 0: the quick brown fox + this is a line with the quick brown fox + 0: the quick brown fox + +/the quick brown fox/IA +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + the quick brown fox + 0: the quick brown fox + *** Failers +No match + this is a line with the quick brown fox +No match + +/ab(?z)cd/ +Failed: unrecognized character after (? or (?- at offset 4 + +/^abc|def/I +Capturing subpattern count = 0 +No options +No first char +No need char + abcdef + 0: abc + abcdef\B + 0: def + +/.*((abc)$|(def))/I +Capturing subpattern count = 3 +No options +First char at start or follows newline +No need char + defabc + 0: defabc + 1: abc + 2: abc + \Zdefabc + 0: def + 1: def + 2: + 3: def + +/)/ +Failed: unmatched parentheses at offset 0 + +/a[]b/ +Failed: missing terminating ] for character class at offset 4 + +/[^aeiou ]{3,}/I +Capturing subpattern count = 0 +No options +No first char +No need char + co-processors, and for + 0: -pr + +/<.*>/I +Capturing subpattern count = 0 +No options +First char = '<' +Need char = '>' + abcghinop + 0: ghi + +/<.*?>/I +Capturing subpattern count = 0 +No options +First char = '<' +Need char = '>' + abcghinop + 0: + +/<.*>/IU +Capturing subpattern count = 0 +Options: ungreedy +First char = '<' +Need char = '>' + abcghinop + 0: + +/(?U)<.*>/I +Capturing subpattern count = 0 +Options: ungreedy +First char = '<' +Need char = '>' + abcghinop + 0: + +/<.*?>/IU +Capturing subpattern count = 0 +Options: ungreedy +First char = '<' +Need char = '>' + abcghinop + 0: ghi + +/={3,}/IU +Capturing subpattern count = 0 +Options: ungreedy +First char = '=' +Need char = '=' + abc========def + 0: === + +/(?U)={3,}?/I +Capturing subpattern count = 0 +Options: ungreedy +First char = '=' +Need char = '=' + abc========def + 0: ======== + +/(?^abc)/Im +Capturing subpattern count = 0 +Options: multiline +First char at start or follows newline +Need char = 'c' + abc + 0: abc + def\nabc + 0: abc + *** Failers +No match + defabc +No match + +/(?<=ab(c+)d)ef/ +Failed: lookbehind assertion is not fixed length at offset 11 + +/(?<=ab(?<=c+)d)ef/ +Failed: lookbehind assertion is not fixed length at offset 12 + +/(?<=ab(c|de)f)g/ +Failed: lookbehind assertion is not fixed length at offset 13 + +/The next three are in testinput2 because they have variable length branches/ + +/(?<=bullock|donkey)-cart/I +Capturing subpattern count = 0 +No options +First char = '-' +Need char = 't' +Max lookbehind = 7 + the bullock-cart + 0: -cart + a donkey-cart race + 0: -cart + *** Failers +No match + cart +No match + horse-and-cart +No match + +/(?<=ab(?i)x|y|z)/I +Capturing subpattern count = 0 +No options +No first char +No need char +Max lookbehind = 3 + +/(?>.*)(?<=(abcd)|(xyz))/I +Capturing subpattern count = 2 +No options +No first char +No need char +Max lookbehind = 4 + alphabetabcd + 0: alphabetabcd + 1: abcd + endingxyz + 0: endingxyz + 1: + 2: xyz + +/(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/I +Capturing subpattern count = 0 +No options +First char = 'Z' +Need char = 'Z' +Max lookbehind = 4 + abxyZZ + 0: ZZ + abXyZZ + 0: ZZ + ZZZ + 0: ZZ + zZZ + 0: ZZ + bZZ + 0: ZZ + BZZ + 0: ZZ + *** Failers +No match + ZZ +No match + abXYZZ +No match + zzz +No match + bzz +No match + +/(? + 3: f + 1G a (1) + 2G (0) + 3G f (1) +get substring 4 failed -7 + 0L adef + 1L a + 2L + 3L f + bcdef\G1\G2\G3\G4\L + 0: bcdef + 1: bc + 2: bc + 3: f + 1G bc (2) + 2G bc (2) + 3G f (1) +get substring 4 failed -7 + 0L bcdef + 1L bc + 2L bc + 3L f + adefghijk\C0 + 0: adef + 1: a + 2: + 3: f + 0C adef (4) + +/^abc\00def/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + abc\00def\L\C0 + 0: abc\x00def + 0C abc\x00def (7) + 0L abc + +/word ((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ +)((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ +)?)?)?)?)?)?)?)?)?otherword/I +Capturing subpattern count = 8 +Contains explicit CR or LF match +No options +First char = 'w' +Need char = 'd' + +/.*X/IDZ +------------------------------------------------------------------ + Bra + Any* + X + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char at start or follows newline +Need char = 'X' + +/.*X/IDZs +------------------------------------------------------------------ + Bra + AllAny* + X + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored dotall +No first char +Need char = 'X' + +/(.*X|^B)/IDZ +------------------------------------------------------------------ + Bra + CBra 1 + Any* + X + Alt + ^ + B + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +First char at start or follows newline +No need char + +/(.*X|^B)/IDZs +------------------------------------------------------------------ + Bra + CBra 1 + AllAny* + X + Alt + ^ + B + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: anchored dotall +No first char +No need char + +/(?s)(.*X|^B)/IDZ +------------------------------------------------------------------ + Bra + CBra 1 + AllAny* + X + Alt + ^ + B + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: anchored dotall +No first char +No need char + +/(?s:.*X|^B)/IDZ +------------------------------------------------------------------ + Bra + Bra + AllAny* + X + Alt + ^ + B + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/\Biss\B/I+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' +Max lookbehind = 1 + Mississippi + 0: iss + 0+ issippi + +/iss/IG+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' + Mississippi + 0: iss + 0+ issippi + 0: iss + 0+ ippi + +/\Biss\B/IG+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' +Max lookbehind = 1 + Mississippi + 0: iss + 0+ issippi + +/\Biss\B/Ig+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' +Max lookbehind = 1 + Mississippi + 0: iss + 0+ issippi + 0: iss + 0+ ippi + *** Failers +No match + Mississippi\A +No match + +/(?<=[Ms])iss/Ig+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' +Max lookbehind = 1 + Mississippi + 0: iss + 0+ issippi + 0: iss + 0+ ippi + +/(?<=[Ms])iss/IG+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' +Max lookbehind = 1 + Mississippi + 0: iss + 0+ issippi + +/^iss/Ig+ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + ississippi + 0: iss + 0+ issippi + +/.*iss/Ig+ +Capturing subpattern count = 0 +No options +First char at start or follows newline +Need char = 's' + abciss\nxyzisspqr + 0: abciss + 0+ \x0axyzisspqr + 0: xyziss + 0+ pqr + +/.i./I+g +Capturing subpattern count = 0 +No options +No first char +Need char = 'i' + Mississippi + 0: Mis + 0+ sissippi + 0: sis + 0+ sippi + 0: sip + 0+ pi + Mississippi\A + 0: Mis + 0+ sissippi + 0: sis + 0+ sippi + 0: sip + 0+ pi + Missouri river + 0: Mis + 0+ souri river + 0: ri + 0+ river + 0: riv + 0+ er + Missouri river\A + 0: Mis + 0+ souri river + +/^.is/I+g +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + Mississippi + 0: Mis + 0+ sissippi + +/^ab\n/Ig+ +Capturing subpattern count = 0 +Contains explicit CR or LF match +Options: anchored +No first char +No need char + ab\nab\ncd + 0: ab\x0a + 0+ ab\x0acd + +/^ab\n/Img+ +Capturing subpattern count = 0 +Contains explicit CR or LF match +Options: multiline +First char at start or follows newline +Need char = \x0a + ab\nab\ncd + 0: ab\x0a + 0+ ab\x0acd + 0: ab\x0a + 0+ cd + +/abc/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + +/abc|bac/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'c' + +/(abc|bac)/I +Capturing subpattern count = 1 +No options +No first char +Need char = 'c' + +/(abc|(c|dc))/I +Capturing subpattern count = 2 +No options +No first char +Need char = 'c' + +/(abc|(d|de)c)/I +Capturing subpattern count = 2 +No options +No first char +Need char = 'c' + +/a*/I +Capturing subpattern count = 0 +No options +No first char +No need char + +/a+/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/(baa|a+)/I +Capturing subpattern count = 1 +No options +No first char +Need char = 'a' + +/a{0,3}/I +Capturing subpattern count = 0 +No options +No first char +No need char + +/baa{3,}/I +Capturing subpattern count = 0 +No options +First char = 'b' +Need char = 'a' + +/"([^\\"]+|\\.)*"/I +Capturing subpattern count = 1 +No options +First char = '"' +Need char = '"' + +/(abc|ab[cd])/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/(a|.)/I +Capturing subpattern count = 1 +No options +No first char +No need char + +/a|ba|\w/I +Capturing subpattern count = 0 +No options +No first char +No need char + +/abc(?=pqr)/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'r' + +/...(?<=abc)/I +Capturing subpattern count = 0 +No options +No first char +No need char +Max lookbehind = 3 + +/abc(?!pqr)/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + +/ab./I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/ab[xyz]/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/abc*/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/ab.c*/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/a.c*/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/.c*/I +Capturing subpattern count = 0 +No options +No first char +No need char + +/ac*/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/(a.c*|b.c*)/I +Capturing subpattern count = 1 +No options +No first char +No need char + +/a.c*|aba/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/.+a/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'a' + +/(?=abcda)a.*/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'a' + +/(?=a)a.*/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/a(b)*/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/a\d*/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/ab\d*/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/a(\d)*/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/abcde{0,0}/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'd' + +/ab\d+/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/a(?(1)b)(.)/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/a(?(1)bag|big)(.)/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'g' + +/a(?(1)bag|big)*(.)/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/a(?(1)bag|big)+(.)/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'g' + +/a(?(1)b..|b..)(.)/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'b' + +/ab\d{0}e/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'e' + +/a?b?/I +Capturing subpattern count = 0 +No options +No first char +No need char + a + 0: a + b + 0: b + ab + 0: ab + \ + 0: + *** Failers + 0: + \N +No match + +/|-/I +Capturing subpattern count = 0 +No options +No first char +No need char + abcd + 0: + -abc + 0: + \Nab-c + 0: - + *** Failers + 0: + \Nabc +No match + +/^.?abcd/IS +Capturing subpattern count = 0 +Options: anchored +No first char +Need char = 'd' +Subject length lower bound = 4 +No set of starting bytes + +/\( # ( at start + (?: # Non-capturing bracket + (?>[^()]+) # Either a sequence of non-brackets (no backtracking) + | # Or + (?R) # Recurse - i.e. nested bracketed string + )* # Zero or more contents + \) # Closing ) + /Ix +Capturing subpattern count = 0 +Options: extended +First char = '(' +Need char = ')' + (abcd) + 0: (abcd) + (abcd)xyz + 0: (abcd) + xyz(abcd) + 0: (abcd) + (ab(xy)cd)pqr + 0: (ab(xy)cd) + (ab(xycd)pqr + 0: (xycd) + () abc () + 0: () + 12(abcde(fsh)xyz(foo(bar))lmno)89 + 0: (abcde(fsh)xyz(foo(bar))lmno) + *** Failers +No match + abcd +No match + abcd) +No match + (abcd +No match + +/\( ( (?>[^()]+) | (?R) )* \) /Ixg +Capturing subpattern count = 1 +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd)pqr + 0: (ab(xy)cd) + 1: cd + 1(abcd)(x(y)z)pqr + 0: (abcd) + 1: abcd + 0: (x(y)z) + 1: z + +/\( (?: (?>[^()]+) | (?R) ) \) /Ix +Capturing subpattern count = 0 +Options: extended +First char = '(' +Need char = ')' + (abcd) + 0: (abcd) + (ab(xy)cd) + 0: (xy) + (a(b(c)d)e) + 0: (c) + ((ab)) + 0: ((ab)) + *** Failers +No match + () +No match + +/\( (?: (?>[^()]+) | (?R) )? \) /Ix +Capturing subpattern count = 0 +Options: extended +First char = '(' +Need char = ')' + () + 0: () + 12(abcde(fsh)xyz(foo(bar))lmno)89 + 0: (fsh) + +/\( ( (?>[^()]+) | (?R) )* \) /Ix +Capturing subpattern count = 1 +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd) + 0: (ab(xy)cd) + 1: cd + +/\( ( ( (?>[^()]+) | (?R) )* ) \) /Ix +Capturing subpattern count = 2 +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd) + 0: (ab(xy)cd) + 1: ab(xy)cd + 2: cd + +/\( (123)? ( ( (?>[^()]+) | (?R) )* ) \) /Ix +Capturing subpattern count = 3 +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd) + 0: (ab(xy)cd) + 1: + 2: ab(xy)cd + 3: cd + (123ab(xy)cd) + 0: (123ab(xy)cd) + 1: 123 + 2: ab(xy)cd + 3: cd + +/\( ( (123)? ( (?>[^()]+) | (?R) )* ) \) /Ix +Capturing subpattern count = 3 +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd) + 0: (ab(xy)cd) + 1: ab(xy)cd + 2: + 3: cd + (123ab(xy)cd) + 0: (123ab(xy)cd) + 1: 123ab(xy)cd + 2: 123 + 3: cd + +/\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \) /Ix +Capturing subpattern count = 11 +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd) + 0: (ab(xy)cd) + 1: ab(xy)cd + 2: ab(xy)cd + 3: ab(xy)cd + 4: ab(xy)cd + 5: ab(xy)cd + 6: ab(xy)cd + 7: ab(xy)cd + 8: ab(xy)cd + 9: ab(xy)cd +10: ab(xy)cd +11: cd + +/\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \) /Ix +Capturing subpattern count = 3 +Options: extended +First char = '(' +Need char = ')' + (abcd(xyz

qrs)123) + 0: (abcd(xyz

qrs)123) + 1: abcd(xyz

qrs)123 + 2: 123 + +/\( ( ( (?>[^()]+) | ((?R)) )* ) \) /Ix +Capturing subpattern count = 3 +Options: extended +First char = '(' +Need char = ')' + (ab(cd)ef) + 0: (ab(cd)ef) + 1: ab(cd)ef + 2: ef + 3: (cd) + (ab(cd(ef)gh)ij) + 0: (ab(cd(ef)gh)ij) + 1: ab(cd(ef)gh)ij + 2: ij + 3: (cd(ef)gh) + +/^[[:alnum:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [0-9A-Za-z] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^alnum:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [\x00-/:-@[-`{-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:alpha:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [A-Za-z] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^alpha:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [\x00-@[-`{-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/[_[:alpha:]]/IS +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: 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 + +/^[[:ascii:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [\x00-\x7f] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^ascii:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [\x80-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:blank:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [\x09 ] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^blank:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [\x00-\x08\x0a-\x1f!-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/[\n\x0b\x0c\x0d[:blank:]]/IS +Capturing subpattern count = 0 +Contains explicit CR or LF match +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 + +/^[[:cntrl:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [\x00-\x1f\x7f] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:digit:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [0-9] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:graph:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [!-~] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:lower:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [a-z] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:print:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [ -~] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:punct:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [!-/:-@[-`{-~] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:space:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [\x09-\x0d ] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:upper:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [A-Z] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:xdigit:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [0-9A-Fa-f] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:word:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [0-9A-Z_a-z] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^cntrl:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [ -~\x80-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[12[:^digit:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [\x00-/12:-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^blank:]]/DZ +------------------------------------------------------------------ + Bra + ^ + [\x00-\x08\x0a-\x1f!-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/[01[:alpha:]%]/DZ +------------------------------------------------------------------ + Bra + [%01A-Za-z] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[[.ch.]]/I +Failed: POSIX collating elements are not supported at offset 1 + +/[[=ch=]]/I +Failed: POSIX collating elements are not supported at offset 1 + +/[[:rhubarb:]]/I +Failed: unknown POSIX class name at offset 3 + +/[[:upper:]]/Ii +Capturing subpattern count = 0 +Options: caseless +No first char +No need char + A + 0: A + a + 0: a + +/[[:lower:]]/Ii +Capturing subpattern count = 0 +Options: caseless +No first char +No need char + A + 0: A + a + 0: a + +/((?-i)[[:lower:]])[[:lower:]]/Ii +Capturing subpattern count = 1 +Options: caseless +No first char +No need char + ab + 0: ab + 1: a + aB + 0: aB + 1: a + *** Failers + 0: ai + 1: a + Ab +No match + AB +No match + +/[\200-\110]/I +Failed: range out of order in character class at offset 9 + +/^(?(0)f|b)oo/I +Failed: invalid condition (?(0) at offset 6 + +/This one's here because of the large output vector needed/I +Capturing subpattern count = 0 +No options +First char = 'T' +Need char = 'd' + +/(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\w+)\s+(\270)/I +Capturing subpattern count = 271 +Max back reference = 270 +No options +No first char +No need char + \O900 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC + 0: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC + 1: 1 + 2: 2 + 3: 3 + 4: 4 + 5: 5 + 6: 6 + 7: 7 + 8: 8 + 9: 9 +10: 10 +11: 11 +12: 12 +13: 13 +14: 14 +15: 15 +16: 16 +17: 17 +18: 18 +19: 19 +20: 20 +21: 21 +22: 22 +23: 23 +24: 24 +25: 25 +26: 26 +27: 27 +28: 28 +29: 29 +30: 30 +31: 31 +32: 32 +33: 33 +34: 34 +35: 35 +36: 36 +37: 37 +38: 38 +39: 39 +40: 40 +41: 41 +42: 42 +43: 43 +44: 44 +45: 45 +46: 46 +47: 47 +48: 48 +49: 49 +50: 50 +51: 51 +52: 52 +53: 53 +54: 54 +55: 55 +56: 56 +57: 57 +58: 58 +59: 59 +60: 60 +61: 61 +62: 62 +63: 63 +64: 64 +65: 65 +66: 66 +67: 67 +68: 68 +69: 69 +70: 70 +71: 71 +72: 72 +73: 73 +74: 74 +75: 75 +76: 76 +77: 77 +78: 78 +79: 79 +80: 80 +81: 81 +82: 82 +83: 83 +84: 84 +85: 85 +86: 86 +87: 87 +88: 88 +89: 89 +90: 90 +91: 91 +92: 92 +93: 93 +94: 94 +95: 95 +96: 96 +97: 97 +98: 98 +99: 99 +100: 100 +101: 101 +102: 102 +103: 103 +104: 104 +105: 105 +106: 106 +107: 107 +108: 108 +109: 109 +110: 110 +111: 111 +112: 112 +113: 113 +114: 114 +115: 115 +116: 116 +117: 117 +118: 118 +119: 119 +120: 120 +121: 121 +122: 122 +123: 123 +124: 124 +125: 125 +126: 126 +127: 127 +128: 128 +129: 129 +130: 130 +131: 131 +132: 132 +133: 133 +134: 134 +135: 135 +136: 136 +137: 137 +138: 138 +139: 139 +140: 140 +141: 141 +142: 142 +143: 143 +144: 144 +145: 145 +146: 146 +147: 147 +148: 148 +149: 149 +150: 150 +151: 151 +152: 152 +153: 153 +154: 154 +155: 155 +156: 156 +157: 157 +158: 158 +159: 159 +160: 160 +161: 161 +162: 162 +163: 163 +164: 164 +165: 165 +166: 166 +167: 167 +168: 168 +169: 169 +170: 170 +171: 171 +172: 172 +173: 173 +174: 174 +175: 175 +176: 176 +177: 177 +178: 178 +179: 179 +180: 180 +181: 181 +182: 182 +183: 183 +184: 184 +185: 185 +186: 186 +187: 187 +188: 188 +189: 189 +190: 190 +191: 191 +192: 192 +193: 193 +194: 194 +195: 195 +196: 196 +197: 197 +198: 198 +199: 199 +200: 200 +201: 201 +202: 202 +203: 203 +204: 204 +205: 205 +206: 206 +207: 207 +208: 208 +209: 209 +210: 210 +211: 211 +212: 212 +213: 213 +214: 214 +215: 215 +216: 216 +217: 217 +218: 218 +219: 219 +220: 220 +221: 221 +222: 222 +223: 223 +224: 224 +225: 225 +226: 226 +227: 227 +228: 228 +229: 229 +230: 230 +231: 231 +232: 232 +233: 233 +234: 234 +235: 235 +236: 236 +237: 237 +238: 238 +239: 239 +240: 240 +241: 241 +242: 242 +243: 243 +244: 244 +245: 245 +246: 246 +247: 247 +248: 248 +249: 249 +250: 250 +251: 251 +252: 252 +253: 253 +254: 254 +255: 255 +256: 256 +257: 257 +258: 258 +259: 259 +260: 260 +261: 261 +262: 262 +263: 263 +264: 264 +265: 265 +266: 266 +267: 267 +268: 268 +269: 269 +270: ABC +271: ABC + +/This one's here because Perl does this differently and PCRE can't at present/I +Capturing subpattern count = 0 +No options +First char = 'T' +Need char = 't' + +/(main(O)?)+/I +Capturing subpattern count = 2 +No options +First char = 'm' +Need char = 'n' + mainmain + 0: mainmain + 1: main + mainOmain + 0: mainOmain + 1: main + 2: O + +/These are all cases where Perl does it differently (nested captures)/I +Capturing subpattern count = 1 +No options +First char = 'T' +Need char = 's' + +/^(a(b)?)+$/I +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + aba + 0: aba + 1: a + 2: b + +/^(aa(bb)?)+$/I +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: aa + 2: bb + +/^(aa|aa(bb))+$/I +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: aa + 2: bb + +/^(aa(bb)??)+$/I +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: aa + 2: bb + +/^(?:aa(bb)?)+$/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: bb + +/^(aa(b(b))?)+$/I +Capturing subpattern count = 3 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: aa + 2: bb + 3: b + +/^(?:aa(b(b))?)+$/I +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: bb + 2: b + +/^(?:aa(b(?:b))?)+$/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: bb + +/^(?:aa(bb(?:b))?)+$/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbbaa + 0: aabbbaa + 1: bbb + +/^(?:aa(b(?:bb))?)+$/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbbaa + 0: aabbbaa + 1: bbb + +/^(?:aa(?:b(b))?)+$/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: b + +/^(?:aa(?:b(bb))?)+$/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbbaa + 0: aabbbaa + 1: bb + +/^(aa(b(bb))?)+$/I +Capturing subpattern count = 3 +Options: anchored +No first char +No need char + aabbbaa + 0: aabbbaa + 1: aa + 2: bbb + 3: bb + +/^(aa(bb(bb))?)+$/I +Capturing subpattern count = 3 +Options: anchored +No first char +No need char + aabbbbaa + 0: aabbbbaa + 1: aa + 2: bbbb + 3: bb + +/--------------------------------------------------------------------/I +Capturing subpattern count = 0 +No options +First char = '-' +Need char = '-' + +/#/IxDZ +------------------------------------------------------------------ + Bra + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: extended +No first char +No need char + +/a#/IxDZ +------------------------------------------------------------------ + Bra + a + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: extended +First char = 'a' +No need char + +/[\s]/DZ +------------------------------------------------------------------ + Bra + [\x09\x0a\x0c\x0d ] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[\S]/DZ +------------------------------------------------------------------ + Bra + [\x00-\x08\x0b\x0e-\x1f!-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/a(?i)b/DZ +------------------------------------------------------------------ + Bra + a + /i b + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' (caseless) + ab + 0: ab + aB + 0: aB + *** Failers +No match + AB +No match + +/(a(?i)b)/DZ +------------------------------------------------------------------ + Bra + CBra 1 + a + /i b + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'b' (caseless) + ab + 0: ab + 1: ab + aB + 0: aB + 1: aB + *** Failers +No match + AB +No match + +/ (?i)abc/IxDZ +------------------------------------------------------------------ + Bra + /i abc + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless extended +First char = 'a' (caseless) +Need char = 'c' (caseless) + +/#this is a comment + (?i)abc/IxDZ +------------------------------------------------------------------ + Bra + /i abc + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless extended +First char = 'a' (caseless) +Need char = 'c' (caseless) + +/123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/DZ +------------------------------------------------------------------ + Bra + 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = '1' +Need char = '0' + +/\Q123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/DZ +------------------------------------------------------------------ + Bra + 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = '1' +Need char = '0' + +/\Q\E/DZ +------------------------------------------------------------------ + Bra + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + \ + 0: + +/\Q\Ex/DZ +------------------------------------------------------------------ + Bra + x + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'x' +No need char + +/ \Q\E/DZ +------------------------------------------------------------------ + Bra + + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = ' ' +No need char + +/a\Q\E/DZ +------------------------------------------------------------------ + Bra + a + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + abc + 0: a + bca + 0: a + bac + 0: a + +/a\Q\Eb/DZ +------------------------------------------------------------------ + Bra + ab + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + abc + 0: ab + +/\Q\Eabc/DZ +------------------------------------------------------------------ + Bra + abc + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + +/x*+\w/DZ +------------------------------------------------------------------ + Bra + x*+ + \w + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + *** Failers + 0: F + xxxxx +No match + +/x?+/DZ +------------------------------------------------------------------ + Bra + x?+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/x++/DZ +------------------------------------------------------------------ + Bra + x++ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'x' +No need char + +/x{1,3}+/DZ +------------------------------------------------------------------ + Bra + Once + x + x{0,2} + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'x' +No need char + +/(x)*+/DZ +------------------------------------------------------------------ + Bra + Braposzero + CBraPos 1 + x + KetRpos + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +No first char +No need char + +/^(\w++|\s++)*$/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + 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)/I +Capturing subpattern count = 2 +No options +No first char +No need char + 12345a + 0: 12345a + 1: 12345 + 2: a + *** Failers +No match + 12345+ +No match + +/a++b/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + aaab + 0: aaab + +/(a++b)/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'b' + aaab + 0: aaab + 1: aaab + +/(a++)b/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'b' + aaab + 0: aaab + 1: aaa + +/([^()]++|\([^()]*\))+/I +Capturing subpattern count = 1 +No options +No first char +No need char + ((abc(ade)ufh()()x + 0: abc(ade)ufh()()x + 1: x + +/\(([^()]++|\([^()]+\))+\)/I +Capturing subpattern count = 1 +No options +First char = '(' +Need char = ')' + (abc) + 0: (abc) + 1: abc + (abc(def)xyz) + 0: (abc(def)xyz) + 1: xyz + *** Failers +No match + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/(abc){1,3}+/DZ +------------------------------------------------------------------ + Bra + Once + CBra 1 + abc + Ket + Brazero + Bra + CBra 1 + abc + Ket + Brazero + CBra 1 + abc + Ket + Ket + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'c' + +/a+?+/I +Failed: nothing to repeat at offset 3 + +/a{2,3}?+b/I +Failed: nothing to repeat at offset 7 + +/(?U)a+?+/I +Failed: nothing to repeat at offset 7 + +/a{2,3}?+b/IU +Failed: nothing to repeat at offset 7 + +/x(?U)a++b/DZ +------------------------------------------------------------------ + Bra + x + a++ + b + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'x' +Need char = 'b' + xaaaab + 0: xaaaab + +/(?U)xa++b/DZ +------------------------------------------------------------------ + Bra + x + a++ + b + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: ungreedy +First char = 'x' +Need char = 'b' + xaaaab + 0: xaaaab + +/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/DZ +------------------------------------------------------------------ + Bra + ^ + CBra 1 + CBra 2 + a+ + Ket + CBra 3 + [ab]+? + Ket + CBra 4 + [bc]+ + Ket + CBra 5 + \w* + Ket + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 5 +Options: anchored +No first char +No need char + +/^x(?U)a+b/DZ +------------------------------------------------------------------ + Bra + ^ + x + a++ + b + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +Need char = 'b' + +/^x(?U)(a+)b/DZ +------------------------------------------------------------------ + Bra + ^ + x + CBra 1 + a+? + Ket + b + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: anchored +No first char +Need char = 'b' + +/[.x.]/I +Failed: POSIX collating elements are not supported at offset 0 + +/[=x=]/I +Failed: POSIX collating elements are not supported at offset 0 + +/[:x:]/I +Failed: POSIX named classes are supported only within a class at offset 0 + +/\l/I +Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1 + +/\L/I +Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1 + +/\N{name}/I +Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1 + +/\u/I +Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1 + +/\U/I +Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1 + +/[/I +Failed: missing terminating ] for character class at offset 1 + +/[a-/I +Failed: missing terminating ] for character class at offset 3 + +/[[:space:]/I +Failed: missing terminating ] for character class at offset 10 + +/[\s]/IDZ +------------------------------------------------------------------ + Bra + [\x09\x0a\x0c\x0d ] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[[:space:]]/IDZ +------------------------------------------------------------------ + Bra + [\x09-\x0d ] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[[:space:]abcde]/IDZ +------------------------------------------------------------------ + Bra + [\x09-\x0d a-e] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/Ix +Capturing subpattern count = 0 +Options: extended +First char = '<' +Need char = '>' + <> + 0: <> + + 0: + hij> + 0: hij> + hij> + 0: + def> + 0: def> + + 0: <> + *** Failers +No match + 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 +------------------------------------------------------------------ + Bra + 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 + \b + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = '8' +Need char = 'X' +Max lookbehind = 1 + +|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|IDZ +------------------------------------------------------------------ + Bra + $<.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 + \b + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = '$' +Need char = 'X' +Max lookbehind = 1 + +/(.*)\d+\1/I +Capturing subpattern count = 1 +Max back reference = 1 +No options +No first char +No need char + +/(.*)\d+/I +Capturing subpattern count = 1 +No options +First char at start or follows newline +No need char + +/(.*)\d+\1/Is +Capturing subpattern count = 1 +Max back reference = 1 +Options: dotall +No first char +No need char + +/(.*)\d+/Is +Capturing subpattern count = 1 +Options: anchored dotall +No first char +No need char + +/(.*(xyz))\d+\2/I +Capturing subpattern count = 2 +Max back reference = 2 +No options +First char at start or follows newline +Need char = 'z' + +/((.*))\d+\1/I +Capturing subpattern count = 2 +Max back reference = 1 +No options +No first char +No need char + abc123bc + 0: bc123bc + 1: bc + 2: bc + +/a[b]/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/(?=a).*/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/(?=abc).xyz/IiI +Capturing subpattern count = 0 +Options: caseless +First char = 'a' (caseless) +Need char = 'z' (caseless) + +/(?=abc)(?i).xyz/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'z' (caseless) + +/(?=a)(?=b)/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/(?=.)a/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/((?=abcda)a)/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'a' + +/((?=abcda)ab)/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'b' + +/()a/I +Capturing subpattern count = 1 +No options +No first char +Need char = 'a' + +/(?(1)ab|ac)(.)/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/(?(1)abz|acz)(.)/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'z' + +/(?(1)abz)(.)/I +Capturing subpattern count = 1 +No options +No first char +No need char + +/(?(1)abz)(1)23/I +Capturing subpattern count = 1 +No options +No first char +Need char = '3' + +/(a)+/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/(a){2,3}/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'a' + +/(a)*/I +Capturing subpattern count = 1 +No options +No first char +No need char + +/[a]/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/[ab]/I +Capturing subpattern count = 0 +No options +No first char +No need char + +/[ab]/IS +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a b + +/[^a]/I +Capturing subpattern count = 0 +No options +No first char +No need char + +/\d456/I +Capturing subpattern count = 0 +No options +No first char +Need char = '6' + +/\d456/IS +Capturing subpattern count = 0 +No options +No first char +Need char = '6' +Subject length lower bound = 4 +Starting byte set: 0 1 2 3 4 5 6 7 8 9 + +/a^b/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/^a/Im +Capturing subpattern count = 0 +Options: multiline +First char at start or follows newline +Need char = 'a' + abcde + 0: a + xy\nabc + 0: a + *** Failers +No match + xyabc +No match + +/c|abc/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'c' + +/(?i)[ab]/IS +Capturing subpattern count = 0 +Options: caseless +No first char +No need char +Subject length lower bound = 1 +Starting byte set: A B a b + +/[ab](?i)cd/IS +Capturing subpattern count = 0 +No options +No first char +Need char = 'd' (caseless) +Subject length lower bound = 3 +Starting byte set: a b + +/abc(?C)def/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'f' + abcdef +--->abcdef + 0 ^ ^ d + 0: abcdef + 1234abcdef +--->1234abcdef + 0 ^ ^ d + 0: abcdef + *** Failers +No match + abcxyz +No match + abcxyzf +--->abcxyzf + 0 ^ ^ d +No match + +/abc(?C)de(?C1)f/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'f' + 123abcdef +--->123abcdef + 0 ^ ^ d + 1 ^ ^ f + 0: abcdef + +/(?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 +Need char = 'f' + 1234abcdef +--->1234abcdef + 1 ^ \d + 1 ^ \d + 1 ^ \d + 1 ^ \d + 2 ^ ^ d + 0: 4abcdef + *** Failers +No match + abcdef +--->abcdef + 1 ^ \d + 1 ^ \d + 1 ^ \d + 1 ^ \d + 1 ^ \d + 1 ^ \d +No match + +/(?C255)ab/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/(?C256)ab/I +Failed: number after (?C is > 255 at offset 6 + +/(?Cab)xx/I +Failed: closing ) for (?C expected at offset 3 + +/(?C12vr)x/I +Failed: closing ) for (?C expected at offset 5 + +/abc(?C)def/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'f' + *** Failers +No match + \x83\x0\x61bcdef +--->\x83\x00abcdef + 0 ^ ^ d + 0: abcdef + +/(abc)(?C)de(?C1)f/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'f' + 123abcdef +--->123abcdef + 0 ^ ^ d + 1 ^ ^ f + 0: abcdef + 1: abc + 123abcdef\C+ +Callout 0: last capture = 1 + 0: + 1: abc +--->123abcdef + ^ ^ d +Callout 1: last capture = 1 + 0: + 1: abc +--->123abcdef + ^ ^ f + 0: abcdef + 1: abc + 123abcdef\C- + 0: abcdef + 1: abc + *** Failers +No match + 123abcdef\C!1 +--->123abcdef + 0 ^ ^ d + 1 ^ ^ f +No match + +/(?C0)(abc(?C1))*/I +Capturing subpattern count = 1 +No options +No first char +No need char + abcabcabc +--->abcabcabc + 0 ^ (abc(?C1))* + 1 ^ ^ ) + 1 ^ ^ ) + 1 ^ ^ ) + 0: abcabcabc + 1: abc + abcabc\C!1!3 +--->abcabc + 0 ^ (abc(?C1))* + 1 ^ ^ ) + 1 ^ ^ ) + 0: abcabc + 1: abc + *** Failers +--->*** Failers + 0 ^ (abc(?C1))* + 0: + abcabcabc\C!1!3 +--->abcabcabc + 0 ^ (abc(?C1))* + 1 ^ ^ ) + 1 ^ ^ ) + 1 ^ ^ ) + 0: abcabc + 1: abc + +/(\d{3}(?C))*/I +Capturing subpattern count = 1 +No options +No first char +No need char + 123\C+ +Callout 0: last capture = -1 + 0: +--->123 + ^ ^ ) + 0: 123 + 1: 123 + 123456\C+ +Callout 0: last capture = -1 + 0: +--->123456 + ^ ^ ) +Callout 0: last capture = 1 + 0: + 1: 123 +--->123456 + ^ ^ ) + 0: 123456 + 1: 456 + 123456789\C+ +Callout 0: last capture = -1 + 0: +--->123456789 + ^ ^ ) +Callout 0: last capture = 1 + 0: + 1: 123 +--->123456789 + ^ ^ ) +Callout 0: last capture = 1 + 0: + 1: 456 +--->123456789 + ^ ^ ) + 0: 123456789 + 1: 789 + +/((xyz)(?C)p|(?C1)xyzabc)/I +Capturing subpattern count = 2 +No options +First char = 'x' +No need char + xyzabc\C+ +Callout 0: last capture = 2 + 0: + 1: + 2: xyz +--->xyzabc + ^ ^ p +Callout 1: last capture = -1 + 0: +--->xyzabc + ^ x + 0: xyzabc + 1: xyzabc + +/(X)((xyz)(?C)p|(?C1)xyzabc)/I +Capturing subpattern count = 3 +No options +First char = 'X' +Need char = 'x' + Xxyzabc\C+ +Callout 0: last capture = 3 + 0: + 1: X + 2: + 3: xyz +--->Xxyzabc + ^ ^ p +Callout 1: last capture = 1 + 0: + 1: X +--->Xxyzabc + ^^ x + 0: Xxyzabc + 1: X + 2: xyzabc + +/(?=(abc))(?C)abcdef/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'f' + abcdef\C+ +Callout 0: last capture = 1 + 0: + 1: abc +--->abcdef + ^ a + 0: abcdef + 1: abc + +/(?!(abc)(?C1)d)(?C2)abcxyz/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'z' + abcxyz\C+ +Callout 1: last capture = 1 + 0: + 1: abc +--->abcxyz + ^ ^ d +Callout 2: last capture = -1 + 0: +--->abcxyz + ^ a + 0: abcxyz + +/(?<=(abc)(?C))xyz/I +Capturing subpattern count = 1 +No options +First char = 'x' +Need char = 'z' +Max lookbehind = 3 + abcxyz\C+ +Callout 0: last capture = 1 + 0: + 1: abc +--->abcxyz + ^ ) + 0: xyz + 1: abc + +/a(b+)(c*)(?C1)/I +Capturing subpattern count = 2 +No options +First char = 'a' +Need char = 'b' + abbbbbccc\C*1 +--->abbbbbccc + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 +No match + +/a(b+?)(c*?)(?C1)/I +Capturing subpattern count = 2 +No options +First char = 'a' +Need char = 'b' + abbbbbccc\C*1 +--->abbbbbccc + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 + 1 ^ ^ +Callout data = 1 +No match + +/(?C)abc/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + +/(?C)^abc/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/(?C)a|b/IS +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a b + +/(?R)/I +Failed: recursive call could loop indefinitely at offset 3 + +/(a|(?R))/I +Failed: recursive call could loop indefinitely at offset 6 + +/(ab|(bc|(de|(?R))))/I +Failed: recursive call could loop indefinitely at offset 15 + +/x(ab|(bc|(de|(?R))))/I +Capturing subpattern count = 3 +No options +First char = 'x' +No need char + xab + 0: xab + 1: ab + xbc + 0: xbc + 1: bc + 2: bc + xde + 0: xde + 1: de + 2: de + 3: de + xxab + 0: xxab + 1: xab + 2: xab + 3: xab + xxxab + 0: xxxab + 1: xxab + 2: xxab + 3: xxab + *** Failers +No match + xyab +No match + +/(ab|(bc|(de|(?1))))/I +Failed: recursive call could loop indefinitely at offset 15 + +/x(ab|(bc|(de|(?1)x)x)x)/I +Failed: recursive call could loop indefinitely at offset 16 + +/^([^()]|\((?1)*\))*$/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + 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)) * >))/Ix +Capturing subpattern count = 2 +Options: extended +First char = '<' +Need char = '>' + <> + 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 + b|c)d(?Pe)/DZ +------------------------------------------------------------------ + Bra + a + CBra 1 + b + Alt + c + Ket + d + CBra 2 + e + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Named capturing subpatterns: + longername2 2 + name1 1 +No options +First char = 'a' +Need char = 'e' + abde + 0: abde + 1: b + 2: e + acde + 0: acde + 1: c + 2: e + +/(?:a(?Pc(?Pd)))(?Pa)/DZ +------------------------------------------------------------------ + Bra + Bra + a + CBra 1 + c + CBra 2 + d + Ket + Ket + Ket + CBra 3 + a + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 3 +Named capturing subpatterns: + a 3 + c 1 + d 2 +No options +First char = 'a' +Need char = 'a' + +/(?Pa)...(?P=a)bbb(?P>a)d/DZ +------------------------------------------------------------------ + Bra + CBra 1 + a + Ket + Any + Any + Any + \1 + bbb + Recurse + d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Max back reference = 1 +Named capturing subpatterns: + a 1 +No options +First char = 'a' +Need char = 'd' + +/^\W*(?:(?P(?P.)\W*(?P>one)\W*(?P=two)|)|(?P(?P.)\W*(?P>three)\W*(?P=four)|\W*.\W*))\W*$/Ii +Capturing subpattern count = 4 +Max back reference = 4 +Named capturing subpatterns: + four 4 + one 1 + three 3 + two 2 +Options: anchored caseless +No first char +No need char + 1221 + 0: 1221 + 1: 1221 + 2: 1 + Satan, oscillate my metallic sonatas! + 0: Satan, oscillate my metallic sonatas! + 1: + 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 + +/((?(R)a|b))\1(?1)?/I +Capturing subpattern count = 1 +Max back reference = 1 +No options +No first char +No need char + bb + 0: bb + 1: b + bbaa + 0: bba + 1: b + +/(.*)a/Is +Capturing subpattern count = 1 +Options: anchored dotall +No first char +Need char = 'a' + +/(.*)a\1/Is +Capturing subpattern count = 1 +Max back reference = 1 +Options: dotall +No first char +Need char = 'a' + +/(.*)a(b)\2/Is +Capturing subpattern count = 2 +Max back reference = 2 +Options: anchored dotall +No first char +Need char = 'b' + +/((.*)a|(.*)b)z/Is +Capturing subpattern count = 3 +Options: anchored dotall +No first char +Need char = 'z' + +/((.*)a|(.*)b)z\1/Is +Capturing subpattern count = 3 +Max back reference = 1 +Options: dotall +No first char +Need char = 'z' + +/((.*)a|(.*)b)z\2/Is +Capturing subpattern count = 3 +Max back reference = 2 +Options: dotall +No first char +Need char = 'z' + +/((.*)a|(.*)b)z\3/Is +Capturing subpattern count = 3 +Max back reference = 3 +Options: dotall +No first char +Need char = 'z' + +/((.*)a|^(.*)b)z\3/Is +Capturing subpattern count = 3 +Max back reference = 3 +Options: anchored dotall +No first char +Need char = 'z' + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/Is +Capturing subpattern count = 31 +Options: anchored dotall +No first char +No need char + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/Is +Capturing subpattern count = 31 +Max back reference = 31 +Options: dotall +No first char +No need char + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/Is +Capturing subpattern count = 32 +Max back reference = 32 +Options: dotall +No first char +No need char + +/(a)(bc)/INDZ +------------------------------------------------------------------ + Bra + Bra + a + Ket + Bra + bc + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: no_auto_capture +First char = 'a' +Need char = 'c' + abc + 0: abc + +/(?Pa)(bc)/INDZ +------------------------------------------------------------------ + Bra + CBra 1 + a + Ket + Bra + bc + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Named capturing subpatterns: + one 1 +Options: no_auto_capture +First char = 'a' +Need char = 'c' + abc + 0: abc + 1: a + +/(a)(?Pbc)/INDZ +------------------------------------------------------------------ + Bra + Bra + a + Ket + CBra 1 + bc + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Named capturing subpatterns: + named 1 +Options: no_auto_capture +First char = 'a' +Need char = 'c' + +/(a+)*zz/I +Capturing subpattern count = 1 +No options +No first char +Need char = 'z' + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\M +Minimum match() limit = 8 +Minimum match() recursion limit = 6 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazz + 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaz\M +Minimum match() limit = 32768 +Minimum match() recursion limit = 42 +No match + +/(aaa(?C1)bbb|ab)/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'b' + aaabbb +--->aaabbb + 1 ^ ^ b + 0: aaabbb + 1: aaabbb + aaabbb\C*0 +--->aaabbb + 1 ^ ^ b + 0: aaabbb + 1: aaabbb + aaabbb\C*1 +--->aaabbb + 1 ^ ^ b +Callout data = 1 + 0: ab + 1: ab + aaabbb\C*-1 +--->aaabbb + 1 ^ ^ b +Callout data = -1 +No match + +/ab(?Pcd)ef(?Pgh)/I +Capturing subpattern count = 2 +Named capturing subpatterns: + one 1 + two 2 +No options +First char = 'a' +Need char = 'h' + abcdefgh + 0: abcdefgh + 1: cd + 2: gh + abcdefgh\C1\Gtwo + 0: abcdefgh + 1: cd + 2: gh + 1C cd (2) + G gh (2) two + abcdefgh\Cone\Ctwo + 0: abcdefgh + 1: cd + 2: gh + C cd (2) one + C gh (2) two + abcdefgh\Cthree +no parentheses with name "three" + 0: abcdefgh + 1: cd + 2: gh +copy substring three failed -7 + +/(?P)(?P)/DZ +------------------------------------------------------------------ + Bra + CBra 1 + Ket + CBra 2 + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Named capturing subpatterns: + Tes 1 + Test 2 +No options +No first char +No need char + +/(?P)(?P)/DZ +------------------------------------------------------------------ + Bra + CBra 1 + Ket + CBra 2 + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Named capturing subpatterns: + Tes 2 + Test 1 +No options +No first char +No need char + +/(?Pzz)(?Paa)/I +Capturing subpattern count = 2 +Named capturing subpatterns: + A 2 + Z 1 +No options +First char = 'z' +Need char = 'a' + zzaa\CZ + 0: zzaa + 1: zz + 2: aa + C zz (2) Z + zzaa\CA + 0: zzaa + 1: zz + 2: aa + C aa (2) A + +/(?Peks)(?Peccs)/I +Failed: two named subpatterns have the same name at offset 15 + +/(?Pabc(?Pdef)(?Pxyz))/I +Failed: two named subpatterns have the same name at offset 30 + +"\[((?P\d+)(,(?P>elem))*)\]"I +Capturing subpattern count = 3 +Named capturing subpatterns: + elem 2 +No options +First char = '[' +Need char = ']' + [10,20,30,5,5,4,4,2,43,23,4234] + 0: [10,20,30,5,5,4,4,2,43,23,4234] + 1: 10,20,30,5,5,4,4,2,43,23,4234 + 2: 10 + 3: ,4234 + *** Failers +No match + [] +No match + +"\[((?P\d+)(,(?P>elem))*)?\]"I +Capturing subpattern count = 3 +Named capturing subpatterns: + elem 2 +No options +First char = '[' +Need char = ']' + [10,20,30,5,5,4,4,2,43,23,4234] + 0: [10,20,30,5,5,4,4,2,43,23,4234] + 1: 10,20,30,5,5,4,4,2,43,23,4234 + 2: 10 + 3: ,4234 + [] + 0: [] + +/(a(b(?2)c))?/DZ +------------------------------------------------------------------ + Bra + Brazero + CBra 1 + a + CBra 2 + b + Recurse + c + Ket + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 2 +No options +No first char +No need char + +/(a(b(?2)c))*/DZ +------------------------------------------------------------------ + Bra + Brazero + CBra 1 + a + CBra 2 + b + Recurse + c + Ket + KetRmax + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 2 +No options +No first char +No need char + +/(a(b(?2)c)){0,2}/DZ +------------------------------------------------------------------ + Bra + Brazero + Bra + CBra 1 + a + CBra 2 + b + Recurse + c + Ket + Ket + Brazero + CBra 1 + a + CBra 2 + b + Recurse + c + Ket + Ket + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 2 +No options +No first char +No need char + +/[ab]{1}+/DZ +------------------------------------------------------------------ + Bra + Once + [ab]{1,1} + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/Ii +Capturing subpattern count = 3 +Options: caseless +No first char +Need char = 'g' (caseless) + Baby Bjorn Active Carrier - With free SHIPPING!! + 0: Baby Bjorn Active Carrier - With free SHIPPING!! + 1: Baby Bjorn Active Carrier - With free SHIPPING!! + +/((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/IiS +Capturing subpattern count = 3 +Options: caseless +No first char +Need char = 'g' (caseless) +Subject length lower bound = 8 +No set of starting bytes + Baby Bjorn Active Carrier - With free SHIPPING!! + 0: Baby Bjorn Active Carrier - With free SHIPPING!! + 1: Baby Bjorn Active Carrier - With free SHIPPING!! + +/a*.*b/ISDZ +------------------------------------------------------------------ + Bra + a* + Any* + b + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +Need char = 'b' +Subject length lower bound = 1 +No set of starting bytes + +/(a|b)*.?c/ISDZ +------------------------------------------------------------------ + Bra + Brazero + CBra 1 + a + Alt + b + KetRmax + Any? + c + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +No first char +Need char = 'c' +Subject length lower bound = 1 +No set of starting bytes + +/abc(?C255)de(?C)f/DZ +------------------------------------------------------------------ + Bra + abc + Callout 255 10 1 + de + Callout 0 16 1 + f + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'f' + +/abcde/ICDZ +------------------------------------------------------------------ + Bra + Callout 255 0 1 + a + Callout 255 1 1 + b + Callout 255 2 1 + c + Callout 255 3 1 + d + Callout 255 4 1 + e + Callout 255 5 0 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: +First char = 'a' +Need char = 'e' + abcde +--->abcde + +0 ^ a + +1 ^^ b + +2 ^ ^ c + +3 ^ ^ d + +4 ^ ^ e + +5 ^ ^ + 0: abcde + abcdfe +--->abcdfe + +0 ^ a + +1 ^^ b + +2 ^ ^ c + +3 ^ ^ d + +4 ^ ^ e +No match + +/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 + a*+ + Callout 255 2 1 + b + Callout 255 3 0 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: +No first char +Need char = '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 + +0 ^ a* + +2 ^ b + +3 ^^ + 0: b + +/a+b/ICDZ +------------------------------------------------------------------ + Bra + Callout 255 0 2 + a++ + Callout 255 2 1 + b + Callout 255 3 0 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: +First char = 'a' +Need char = '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 +No match + +/(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 + 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' + 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 + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +6 ^^ e + +7 ^ ^ f + +8 ^ ^ ) + +9 ^ ^ x + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d +No match + +/(ab|cd){3,4}/IC +Capturing subpattern count = 1 +Options: +No first char +No need char + ababab +--->ababab + +0 ^ (ab|cd){3,4} + +1 ^ a + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +2 ^ ^ b + +3 ^ ^ | + +1 ^ ^ a + +2 ^ ^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c ++12 ^ ^ + 0: ababab + 1: ab + abcdabcd +--->abcdabcd + +0 ^ (ab|cd){3,4} + +1 ^ a + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) + +1 ^ ^ a + +2 ^ ^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) ++12 ^ ^ + 0: abcdabcd + 1: cd + abcdcdcdcdcd +--->abcdcdcdcdcd + +0 ^ (ab|cd){3,4} + +1 ^ a + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) ++12 ^ ^ + 0: abcdcdcd + 1: cd + +/([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 + 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 + Note: that { does NOT introduce a quantifier +--->Note: that { does NOT introduce a quantifier + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x +No match + +/([ab]{1,4}c|xy){4,5}?123/ICDZ +------------------------------------------------------------------ + Bra + Callout 255 0 21 + CBra 1 + Callout 255 1 9 + [ab]{1,4} + Callout 255 10 1 + c + Callout 255 11 0 + Alt + Callout 255 12 1 + x + Callout 255 13 1 + y + Callout 255 14 0 + Ket + CBra 1 + Callout 255 1 9 + [ab]{1,4} + Callout 255 10 1 + c + Callout 255 11 0 + Alt + Callout 255 12 1 + x + Callout 255 13 1 + y + Callout 255 14 0 + Ket + CBra 1 + Callout 255 1 9 + [ab]{1,4} + Callout 255 10 1 + c + Callout 255 11 0 + Alt + Callout 255 12 1 + x + Callout 255 13 1 + y + Callout 255 14 0 + Ket + CBra 1 + Callout 255 1 9 + [ab]{1,4} + Callout 255 10 1 + c + Callout 255 11 0 + Alt + Callout 255 12 1 + x + Callout 255 13 1 + y + Callout 255 14 0 + Ket + Braminzero + CBra 1 + Callout 255 1 9 + [ab]{1,4} + Callout 255 10 1 + c + Callout 255 11 0 + Alt + Callout 255 12 1 + x + Callout 255 13 1 + y + Callout 255 14 0 + Ket + Callout 255 21 1 + 1 + Callout 255 22 1 + 2 + Callout 255 23 1 + 3 + Callout 255 24 0 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: +No first char +Need char = '3' + aacaacaacaacaac123 +--->aacaacaacaacaac123 + +0 ^ ([ab]{1,4}c|xy){4,5}? + +1 ^ [ab]{1,4} ++10 ^ ^ c ++11 ^ ^ | + +1 ^ ^ [ab]{1,4} ++10 ^ ^ c ++11 ^ ^ | + +1 ^ ^ [ab]{1,4} ++10 ^ ^ c ++11 ^ ^ | + +1 ^ ^ [ab]{1,4} ++10 ^ ^ c ++11 ^ ^ | ++21 ^ ^ 1 + +1 ^ ^ [ab]{1,4} ++10 ^ ^ c ++11 ^ ^ | ++21 ^ ^ 1 ++22 ^ ^ 2 ++23 ^ ^ 3 ++24 ^ ^ + 0: aacaacaacaacaac123 + 1: aac + +/\b.*/I +Capturing subpattern count = 0 +No options +No first char +No need char +Max lookbehind = 1 + ab cd\>1 + 0: cd + +/\b.*/Is +Capturing subpattern count = 0 +Options: dotall +No first char +No need char +Max lookbehind = 1 + ab cd\>1 + 0: cd + +/(?!.bcd).*/I +Capturing subpattern count = 0 +No options +No first char +No need char + Xbcd12345 + 0: bcd12345 + +/abcde/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'e' + ab\P +Partial match: ab + abc\P +Partial match: abc + abcd\P +Partial match: abcd + abcde\P + 0: abcde + the quick brown abc\P +Partial match: abc + ** Failers\P +No match + the quick brown abxyz fox\P +No match + +"^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/(20)?\d\d$"I +Capturing subpattern count = 3 +Options: anchored +No first char +Need char = '/' + 13/05/04\P + 0: 13/05/04 + 1: 13 + 2: 05 + 13/5/2004\P + 0: 13/5/2004 + 1: 13 + 2: 5 + 3: 20 + 02/05/09\P + 0: 02/05/09 + 1: 02 + 2: 05 + 1\P +Partial match: 1 + 1/2\P +Partial match: 1/2 + 1/2/0\P +Partial match: 1/2/0 + 1/2/04\P + 0: 1/2/04 + 1: 1 + 2: 2 + 0\P +Partial match: 0 + 02/\P +Partial match: 02/ + 02/0\P +Partial match: 02/0 + 02/1\P +Partial match: 02/1 + ** Failers\P +No match + \P +No match + 123\P +No match + 33/4/04\P +No match + 3/13/04\P +No match + 0/1/2003\P +No match + 0/\P +No match + 02/0/\P +No match + 02/13\P +No match + +/0{0,2}ABC/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'C' + +/\d{3,}ABC/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'C' + +/\d*ABC/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'C' + +/[abc]+DE/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'E' + +/[abc]?123/I +Capturing subpattern count = 0 +No options +No first char +Need char = '3' + 123\P + 0: 123 + a\P +Partial match: a + b\P +Partial match: b + c\P +Partial match: c + c12\P +Partial match: c12 + c123\P + 0: c123 + +/^(?:\d){3,5}X/I +Capturing subpattern count = 0 +Options: anchored +No first char +Need char = 'X' + 1\P +Partial match: 1 + 123\P +Partial match: 123 + 123X + 0: 123X + 1234\P +Partial match: 1234 + 1234X + 0: 1234X + 12345\P +Partial match: 12345 + 12345X + 0: 12345X + *** Failers +No match + 1X +No match + 123456\P +No match + +/abc/IS>testsavedregex +Capturing subpattern count = 0 +No options +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 = 0 +No options +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 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 +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a b +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 = '>' + \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 + 3: seite + +/^a/IF +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/line\nbreak/I +Capturing subpattern count = 0 +Contains explicit CR or LF match +No options +First char = 'l' +Need char = 'k' + this is a line\nbreak + 0: line\x0abreak + line one\nthis is a line\nbreak in the second line + 0: line\x0abreak + +/line\nbreak/If +Capturing subpattern count = 0 +Contains explicit CR or LF match +Options: firstline +First char = 'l' +Need char = 'k' + this is a line\nbreak + 0: line\x0abreak + ** Failers +No match + line one\nthis is a line\nbreak in the second line +No match + +/line\nbreak/Imf +Capturing subpattern count = 0 +Contains explicit CR or LF match +Options: multiline firstline +First char = 'l' +Need char = 'k' + this is a line\nbreak + 0: line\x0abreak + ** Failers +No match + line one\nthis is a line\nbreak in the second line +No match + +/(?i)(?-i)AbCd/I +Capturing subpattern count = 0 +No options +First char = 'A' +Need char = 'd' + AbCd + 0: AbCd + ** Failers +No match + abcd +No match + +/a{11111111111111111111}/I +Failed: number too big in {} quantifier at offset 22 + +/(){64294967295}/I +Failed: number too big in {} quantifier at offset 14 + +/(){2,4294967295}/I +Failed: number too big in {} quantifier at offset 15 + +"(?i:a)(?i:b)(?i:c)(?i:d)(?i:e)(?i:f)(?i:g)(?i:h)(?i:i)(?i:j)(k)(?i:l)A\1B"I +Capturing subpattern count = 1 +Max back reference = 1 +No options +First char = 'a' (caseless) +Need char = 'B' + abcdefghijklAkB + 0: abcdefghijklAkB + 1: k + +"(?Pa)(?Pb)(?Pc)(?Pd)(?Pe)(?Pf)(?Pg)(?Ph)(?Pi)(?Pj)(?Pk)(?Pl)A\11B"I +Capturing subpattern count = 12 +Max back reference = 11 +Named capturing subpatterns: + n0 1 + n1 2 + n10 11 + n11 12 + n2 3 + n3 4 + n4 5 + n5 6 + n6 7 + n7 8 + n8 9 + n9 10 +No options +First char = 'a' +Need char = 'B' + abcdefghijklAkB + 0: abcdefghijklAkB + 1: a + 2: b + 3: c + 4: d + 5: e + 6: f + 7: g + 8: h + 9: i +10: j +11: k +12: l + +"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)A\11B"I +Capturing subpattern count = 12 +Max back reference = 11 +No options +First char = 'a' +Need char = 'B' + abcdefghijklAkB + 0: abcdefghijklAkB + 1: a + 2: b + 3: c + 4: d + 5: e + 6: f + 7: g + 8: h + 9: i +10: j +11: k +12: l + +"(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)(?Pa)"I +Capturing subpattern count = 101 +Named capturing subpatterns: + name0 1 + name1 2 + name10 11 + name100 101 + name11 12 + name12 13 + name13 14 + name14 15 + name15 16 + name16 17 + name17 18 + name18 19 + name19 20 + name2 3 + name20 21 + name21 22 + name22 23 + name23 24 + name24 25 + name25 26 + name26 27 + name27 28 + name28 29 + name29 30 + name3 4 + name30 31 + name31 32 + name32 33 + name33 34 + name34 35 + name35 36 + name36 37 + name37 38 + name38 39 + name39 40 + name4 5 + name40 41 + name41 42 + name42 43 + name43 44 + name44 45 + name45 46 + name46 47 + name47 48 + name48 49 + name49 50 + name5 6 + name50 51 + name51 52 + name52 53 + name53 54 + name54 55 + name55 56 + name56 57 + name57 58 + name58 59 + name59 60 + name6 7 + name60 61 + name61 62 + name62 63 + name63 64 + name64 65 + name65 66 + name66 67 + name67 68 + name68 69 + name69 70 + name7 8 + name70 71 + name71 72 + name72 73 + name73 74 + name74 75 + name75 76 + name76 77 + name77 78 + name78 79 + name79 80 + name8 9 + name80 81 + name81 82 + name82 83 + name83 84 + name84 85 + name85 86 + name86 87 + name87 88 + name88 89 + name89 90 + name9 10 + name90 91 + name91 92 + name92 93 + name93 94 + name94 95 + name95 96 + name96 97 + name97 98 + name98 99 + name99 100 +No options +First char = 'a' +Need char = 'a' + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +Matched, but too many substrings + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 1: a + 2: a + 3: a + 4: a + 5: a + 6: a + 7: a + 8: a + 9: a +10: a +11: a +12: a +13: a +14: a + +"(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)"I +Capturing subpattern count = 101 +No options +First char = 'a' +Need char = 'a' + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +Matched, but too many substrings + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 1: a + 2: a + 3: a + 4: a + 5: a + 6: a + 7: a + 8: a + 9: a +10: a +11: a +12: a +13: a +14: a + +/[^()]*(?:\((?R)\)[^()]*)*/I +Capturing subpattern count = 0 +No options +No first char +No need char + (this(and)that + 0: + (this(and)that) + 0: (this(and)that) + (this(and)that)stuff + 0: (this(and)that)stuff + +/[^()]*(?:\((?>(?R))\)[^()]*)*/I +Capturing subpattern count = 0 +No options +No first char +No need char + (this(and)that + 0: + (this(and)that) + 0: (this(and)that) + +/[^()]*(?:\((?R)\))*[^()]*/I +Capturing subpattern count = 0 +No options +No first char +No need char + (this(and)that + 0: + (this(and)that) + 0: (this(and)that) + +/(?:\((?R)\))*[^()]*/I +Capturing subpattern count = 0 +No options +No first char +No need char + (this(and)that + 0: + (this(and)that) + 0: + ((this)) + 0: ((this)) + +/(?:\((?R)\))|[^()]*/I +Capturing subpattern count = 0 +No options +No first char +No need char + (this(and)that + 0: + (this(and)that) + 0: + (this) + 0: (this) + ((this)) + 0: ((this)) + +/\x{0000ff}/I +Capturing subpattern count = 0 +No options +First char = \xff +No need char + +/^((?Pa1)|(?Pa2)b)/I +Failed: two named subpatterns have the same name at offset 17 + +/^((?Pa1)|(?Pa2)b)/IJ +Capturing subpattern count = 3 +Named capturing subpatterns: + A 2 + A 3 +Options: anchored dupnames +No first char +No need char + a1b\CA + 0: a1 + 1: a1 + 2: a1 + C a1 (2) A + a2b\CA + 0: a2b + 1: a2b + 2: + 3: a2 + C a2 (2) A + ** Failers +No match + a1b\CZ\CA +no parentheses with name "Z" + 0: a1 + 1: a1 + 2: a1 +copy substring Z failed -7 + C a1 (2) A + +/^(?Pa)(?Pb)/IJ +Capturing subpattern count = 2 +Named capturing subpatterns: + A 1 + A 2 +Options: anchored dupnames +No first char +No need char + ab\CA + 0: ab + 1: a + 2: b + C a (1) A + +/^(?Pa)(?Pb)|cd/IJ +Capturing subpattern count = 2 +Named capturing subpatterns: + A 1 + A 2 +Options: dupnames +No first char +No need char + ab\CA + 0: ab + 1: a + 2: b + C a (1) A + cd\CA + 0: cd +copy substring A failed -7 + +/^(?Pa)(?Pb)|cd(?Pef)(?Pgh)/IJ +Capturing subpattern count = 4 +Named capturing subpatterns: + A 1 + A 2 + A 3 + A 4 +Options: dupnames +No first char +No need char + cdefgh\CA + 0: cdefgh + 1: + 2: + 3: ef + 4: gh + C ef (2) A + +/^((?Pa1)|(?Pa2)b)/IJ +Capturing subpattern count = 3 +Named capturing subpatterns: + A 2 + A 3 +Options: anchored dupnames +No first char +No need char + a1b\GA + 0: a1 + 1: a1 + 2: a1 + G a1 (2) A + a2b\GA + 0: a2b + 1: a2b + 2: + 3: a2 + G a2 (2) A + ** Failers +No match + a1b\GZ\GA +no parentheses with name "Z" + 0: a1 + 1: a1 + 2: a1 +get substring Z failed -7 + G a1 (2) A + +/^(?Pa)(?Pb)/IJ +Capturing subpattern count = 2 +Named capturing subpatterns: + A 1 + A 2 +Options: anchored dupnames +No first char +No need char + ab\GA + 0: ab + 1: a + 2: b + G a (1) A + +/^(?Pa)(?Pb)|cd/IJ +Capturing subpattern count = 2 +Named capturing subpatterns: + A 1 + A 2 +Options: dupnames +No first char +No need char + ab\GA + 0: ab + 1: a + 2: b + G a (1) A + cd\GA + 0: cd +get substring A failed -7 + +/^(?Pa)(?Pb)|cd(?Pef)(?Pgh)/IJ +Capturing subpattern count = 4 +Named capturing subpatterns: + A 1 + A 2 + A 3 + A 4 +Options: dupnames +No first char +No need char + cdefgh\GA + 0: cdefgh + 1: + 2: + 3: ef + 4: gh + G ef (2) A + +/(?J)^((?Pa1)|(?Pa2)b)/I +Capturing subpattern count = 3 +Named capturing subpatterns: + A 2 + A 3 +Options: anchored dupnames +Duplicate name status changes +No first char +No need char + a1b\CA + 0: a1 + 1: a1 + 2: a1 + C a1 (2) A + a2b\CA + 0: a2b + 1: a2b + 2: + 3: a2 + C a2 (2) A + +/^(?Pa) (?J:(?Pb)(?Pc)) (?Pd)/I +Failed: two named subpatterns have the same name at offset 37 + +/ In this next test, J is not set at the outer level; consequently it isn't +set in the pattern's options; consequently pcre_get_named_substring() produces +a random value. /Ix +Capturing subpattern count = 1 +Options: extended +First char = 'I' +Need char = 'e' + +/^(?Pa) (?J:(?Pb)(?Pc)) (?Pd)/I +Capturing subpattern count = 4 +Named capturing subpatterns: + A 1 + B 2 + B 3 + C 4 +Options: anchored +Duplicate name status changes +No first char +No need char + a bc d\CA\CB\CC + 0: a bc d + 1: a + 2: b + 3: c + 4: d + C a (1) A + C b (1) B + C d (1) C + +/^(?Pa)?(?(A)a|b)/I +Capturing subpattern count = 1 +Named capturing subpatterns: + A 1 +Options: anchored +No first char +No need char + aabc + 0: aa + 1: a + bc + 0: b + ** Failers +No match + abc +No match + +/(?:(?(ZZ)a|b)(?PX))+/I +Capturing subpattern count = 1 +Named capturing subpatterns: + ZZ 1 +No options +No first char +Need char = 'X' + bXaX + 0: bXaX + 1: X + +/(?:(?(2y)a|b)(X))+/I +Failed: reference to non-existent subpattern at offset 9 + +/(?:(?(ZA)a|b)(?PX))+/I +Failed: reference to non-existent subpattern at offset 9 + +/(?:(?(ZZ)a|b)(?(ZZ)a|b)(?PX))+/I +Capturing subpattern count = 1 +Named capturing subpatterns: + ZZ 1 +No options +No first char +Need char = 'X' + bbXaaX + 0: bbXaaX + 1: X + +/(?:(?(ZZ)a|\(b\))\\(?PX))+/I +Capturing subpattern count = 1 +Named capturing subpatterns: + ZZ 1 +No options +No first char +Need char = 'X' + (b)\\Xa\\X + 0: (b)\Xa\X + 1: X + +/(?PX|Y))+/I +Capturing subpattern count = 1 +Max back reference = 1 +Named capturing subpatterns: + A 1 +No options +No first char +No need char + bXXaYYaY + 0: bXXaYYaY + 1: Y + bXYaXXaX + 0: bX + 1: X + +/()()()()()()()()()(?:(?(A)(?P=A)a|b)(?PX|Y))+/I +Capturing subpattern count = 10 +Max back reference = 10 +Named capturing subpatterns: + A 10 +No options +No first char +No need char + bXXaYYaY + 0: bXXaYYaY + 1: + 2: + 3: + 4: + 5: + 6: + 7: + 8: + 9: +10: Y + +/\s*,\s*/IS +Capturing subpattern count = 0 +No options +No first char +Need char = ',' +Subject length lower bound = 1 +Starting byte set: \x09 \x0a \x0c \x0d \x20 , + \x0b,\x0b + 0: , + \x0c,\x0d + 0: \x0c,\x0d + +/^abc/Im +Capturing subpattern count = 0 +Options: multiline +First char at start or follows newline +Need char = 'c' + xyz\nabc + 0: abc + xyz\nabc\ + 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$/Im +Capturing subpattern count = 0 +Options: multiline +Forced newline sequence: LF +First char = 'a' +Need char = 'c' + 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/Im +Capturing subpattern count = 0 +Options: multiline +Forced newline sequence: CR +First char at start or follows newline +Need char = 'c' + xyz\rabcdef + 0: abc + xyz\nabcdef\ + 0: abc + ** Failers +No match + xyz\nabcdef +No match + +/^abc/Im +Capturing subpattern count = 0 +Options: multiline +Forced newline sequence: LF +First char at start or follows newline +Need char = 'c' + xyz\nabcdef + 0: abc + xyz\rabcdef\ + 0: abc + ** Failers +No match + xyz\rabcdef +No match + +/^abc/Im +Capturing subpattern count = 0 +Options: multiline +Forced newline sequence: CRLF +First char at start or follows newline +Need char = 'c' + xyz\r\nabcdef + 0: abc + xyz\rabcdef\ + 0: abc + ** Failers +No match + xyz\rabcdef +No match + +/^abc/Im +Unknown newline type at: + + +/abc/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + xyz\rabc\ +Unknown newline type at: + abc + 0: abc + +/.*/I +Capturing subpattern count = 0 +Options: +Forced newline sequence: LF +First char at start or follows newline +No need char + abc\ndef + 0: abc + abc\rdef + 0: abc\x0ddef + abc\r\ndef + 0: abc\x0d + \abc\ndef + 0: abc\x0adef + \abc\rdef + 0: abc + \abc\r\ndef + 0: abc + \abc\ndef + 0: abc\x0adef + \abc\rdef + 0: abc\x0ddef + \abc\r\ndef + 0: abc + +/\w+(.)(.)?def/Is +Capturing subpattern count = 2 +Options: dotall +No first char +Need char = 'f' + abc\ndef + 0: abc\x0adef + 1: \x0a + abc\rdef + 0: abc\x0ddef + 1: \x0d + abc\r\ndef + 0: abc\x0d\x0adef + 1: \x0d + 2: \x0a + ++((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)+I +Capturing subpattern count = 1 +No options +No first char +No need char + /* this is a C style comment */\M +Minimum match() limit = 120 +Minimum match() recursion limit = 6 + 0: /* this is a C style comment */ + 1: /* this is a C style comment */ + +/(?P25[0-5]|2[0-4]\d|[01]?\d?\d)(?:\.(?P>B)){3}/I +Capturing subpattern count = 1 +Named capturing subpatterns: + B 1 +No options +No first char +Need char = '.' + +/()()()()()()()()()()()()()()()()()()()() + ()()()()()()()()()()()()()()()()()()()() + ()()()()()()()()()()()()()()()()()()()() + ()()()()()()()()()()()()()()()()()()()() + ()()()()()()()()()()()()()()()()()()()() + (.(.))/Ix +Capturing subpattern count = 102 +Options: extended +No first char +No need char + XY\O400 + 0: XY + 1: + 2: + 3: + 4: + 5: + 6: + 7: + 8: + 9: +10: +11: +12: +13: +14: +15: +16: +17: +18: +19: +20: +21: +22: +23: +24: +25: +26: +27: +28: +29: +30: +31: +32: +33: +34: +35: +36: +37: +38: +39: +40: +41: +42: +43: +44: +45: +46: +47: +48: +49: +50: +51: +52: +53: +54: +55: +56: +57: +58: +59: +60: +61: +62: +63: +64: +65: +66: +67: +68: +69: +70: +71: +72: +73: +74: +75: +76: +77: +78: +79: +80: +81: +82: +83: +84: +85: +86: +87: +88: +89: +90: +91: +92: +93: +94: +95: +96: +97: +98: +99: +100: +101: XY +102: Y + +/(a*b|(?i:c*(?-i)d))/IS +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: C a b c d + +/()[ab]xyz/IS +Capturing subpattern count = 1 +No options +No first char +Need char = 'z' +Subject length lower bound = 4 +Starting byte set: a b + +/(|)[ab]xyz/IS +Capturing subpattern count = 1 +No options +No first char +Need char = 'z' +Subject length lower bound = 4 +Starting byte set: a b + +/(|c)[ab]xyz/IS +Capturing subpattern count = 1 +No options +No first char +Need char = 'z' +Subject length lower bound = 4 +Starting byte set: a b c + +/(|c?)[ab]xyz/IS +Capturing subpattern count = 1 +No options +No first char +Need char = 'z' +Subject length lower bound = 4 +Starting byte set: a b c + +/(d?|c?)[ab]xyz/IS +Capturing subpattern count = 1 +No options +No first char +Need char = 'z' +Subject length lower bound = 4 +Starting byte set: a b c d + +/(d?|c)[ab]xyz/IS +Capturing subpattern count = 1 +No options +No first char +Need char = 'z' +Subject length lower bound = 4 +Starting byte set: a b c d + +/^a*b\d/DZ +------------------------------------------------------------------ + Bra + ^ + a*+ + b + \d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +Need char = 'b' + +/^a*+b\d/DZ +------------------------------------------------------------------ + Bra + ^ + a*+ + b + \d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +Need char = 'b' + +/^a*?b\d/DZ +------------------------------------------------------------------ + Bra + ^ + a*+ + b + \d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +Need char = 'b' + +/^a+A\d/DZ +------------------------------------------------------------------ + Bra + ^ + a++ + A + \d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +Need char = 'A' + aaaA5 + 0: aaaA5 + ** Failers +No match + aaaa5 +No match + +/^a*A\d/IiDZ +------------------------------------------------------------------ + Bra + ^ + /i a* + /i A + \d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored caseless +No first char +Need char = 'A' (caseless) + aaaA5 + 0: aaaA5 + aaaa5 + 0: aaaa5 + +/(a*|b*)[cd]/IS +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a b c d + +/(a+|b*)[cd]/IS +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a b c d + +/(a*|b+)[cd]/IS +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a b c d + +/(a+|b+)[cd]/IS +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 2 +Starting byte set: a b + +/(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + ((( + a + )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + ))) +/Ix +Capturing subpattern count = 203 +Options: extended +First char = 'a' +No need char + large nest +Matched, but too many substrings + 0: a + 1: a + 2: a + 3: a + 4: a + 5: a + 6: a + 7: a + 8: a + 9: a +10: a +11: a +12: a +13: a +14: a + +/a*\d/BZ +------------------------------------------------------------------ + Bra + a*+ + \d + Ket + End +------------------------------------------------------------------ + +/a*\D/BZ +------------------------------------------------------------------ + Bra + a* + \D + Ket + End +------------------------------------------------------------------ + +/0*\d/BZ +------------------------------------------------------------------ + Bra + 0* + \d + Ket + End +------------------------------------------------------------------ + +/0*\D/BZ +------------------------------------------------------------------ + Bra + 0*+ + \D + Ket + End +------------------------------------------------------------------ + +/a*\s/BZ +------------------------------------------------------------------ + Bra + a*+ + \s + Ket + End +------------------------------------------------------------------ + +/a*\S/BZ +------------------------------------------------------------------ + Bra + a* + \S + Ket + End +------------------------------------------------------------------ + +/ *\s/BZ +------------------------------------------------------------------ + Bra + * + \s + Ket + End +------------------------------------------------------------------ + +/ *\S/BZ +------------------------------------------------------------------ + Bra + *+ + \S + Ket + End +------------------------------------------------------------------ + +/a*\w/BZ +------------------------------------------------------------------ + Bra + a* + \w + Ket + End +------------------------------------------------------------------ + +/a*\W/BZ +------------------------------------------------------------------ + Bra + a*+ + \W + Ket + End +------------------------------------------------------------------ + +/=*\w/BZ +------------------------------------------------------------------ + Bra + =*+ + \w + Ket + End +------------------------------------------------------------------ + +/=*\W/BZ +------------------------------------------------------------------ + Bra + =* + \W + Ket + End +------------------------------------------------------------------ + +/\d*a/BZ +------------------------------------------------------------------ + Bra + \d*+ + a + Ket + End +------------------------------------------------------------------ + +/\d*2/BZ +------------------------------------------------------------------ + Bra + \d* + 2 + Ket + End +------------------------------------------------------------------ + +/\d*\d/BZ +------------------------------------------------------------------ + Bra + \d* + \d + Ket + End +------------------------------------------------------------------ + +/\d*\D/BZ +------------------------------------------------------------------ + Bra + \d*+ + \D + Ket + End +------------------------------------------------------------------ + +/\d*\s/BZ +------------------------------------------------------------------ + Bra + \d*+ + \s + Ket + End +------------------------------------------------------------------ + +/\d*\S/BZ +------------------------------------------------------------------ + Bra + \d* + \S + Ket + End +------------------------------------------------------------------ + +/\d*\w/BZ +------------------------------------------------------------------ + Bra + \d* + \w + Ket + End +------------------------------------------------------------------ + +/\d*\W/BZ +------------------------------------------------------------------ + Bra + \d*+ + \W + Ket + End +------------------------------------------------------------------ + +/\D*a/BZ +------------------------------------------------------------------ + Bra + \D* + a + Ket + End +------------------------------------------------------------------ + +/\D*2/BZ +------------------------------------------------------------------ + Bra + \D*+ + 2 + Ket + End +------------------------------------------------------------------ + +/\D*\d/BZ +------------------------------------------------------------------ + Bra + \D*+ + \d + Ket + End +------------------------------------------------------------------ + +/\D*\D/BZ +------------------------------------------------------------------ + Bra + \D* + \D + Ket + End +------------------------------------------------------------------ + +/\D*\s/BZ +------------------------------------------------------------------ + Bra + \D* + \s + Ket + End +------------------------------------------------------------------ + +/\D*\S/BZ +------------------------------------------------------------------ + Bra + \D* + \S + Ket + End +------------------------------------------------------------------ + +/\D*\w/BZ +------------------------------------------------------------------ + Bra + \D* + \w + Ket + End +------------------------------------------------------------------ + +/\D*\W/BZ +------------------------------------------------------------------ + Bra + \D* + \W + Ket + End +------------------------------------------------------------------ + +/\s*a/BZ +------------------------------------------------------------------ + Bra + \s*+ + a + Ket + End +------------------------------------------------------------------ + +/\s*2/BZ +------------------------------------------------------------------ + Bra + \s*+ + 2 + Ket + End +------------------------------------------------------------------ + +/\s*\d/BZ +------------------------------------------------------------------ + Bra + \s*+ + \d + Ket + End +------------------------------------------------------------------ + +/\s*\D/BZ +------------------------------------------------------------------ + Bra + \s* + \D + Ket + End +------------------------------------------------------------------ + +/\s*\s/BZ +------------------------------------------------------------------ + Bra + \s* + \s + Ket + End +------------------------------------------------------------------ + +/\s*\S/BZ +------------------------------------------------------------------ + Bra + \s*+ + \S + Ket + End +------------------------------------------------------------------ + +/\s*\w/BZ +------------------------------------------------------------------ + Bra + \s*+ + \w + Ket + End +------------------------------------------------------------------ + +/\s*\W/BZ +------------------------------------------------------------------ + Bra + \s* + \W + Ket + End +------------------------------------------------------------------ + +/\S*a/BZ +------------------------------------------------------------------ + Bra + \S* + a + Ket + End +------------------------------------------------------------------ + +/\S*2/BZ +------------------------------------------------------------------ + Bra + \S* + 2 + Ket + End +------------------------------------------------------------------ + +/\S*\d/BZ +------------------------------------------------------------------ + Bra + \S* + \d + Ket + End +------------------------------------------------------------------ + +/\S*\D/BZ +------------------------------------------------------------------ + Bra + \S* + \D + Ket + End +------------------------------------------------------------------ + +/\S*\s/BZ +------------------------------------------------------------------ + Bra + \S*+ + \s + Ket + End +------------------------------------------------------------------ + +/\S*\S/BZ +------------------------------------------------------------------ + Bra + \S* + \S + Ket + End +------------------------------------------------------------------ + +/\S*\w/BZ +------------------------------------------------------------------ + Bra + \S* + \w + Ket + End +------------------------------------------------------------------ + +/\S*\W/BZ +------------------------------------------------------------------ + Bra + \S* + \W + Ket + End +------------------------------------------------------------------ + +/\w*a/BZ +------------------------------------------------------------------ + Bra + \w* + a + Ket + End +------------------------------------------------------------------ + +/\w*2/BZ +------------------------------------------------------------------ + Bra + \w* + 2 + Ket + End +------------------------------------------------------------------ + +/\w*\d/BZ +------------------------------------------------------------------ + Bra + \w* + \d + Ket + End +------------------------------------------------------------------ + +/\w*\D/BZ +------------------------------------------------------------------ + Bra + \w* + \D + Ket + End +------------------------------------------------------------------ + +/\w*\s/BZ +------------------------------------------------------------------ + Bra + \w*+ + \s + Ket + End +------------------------------------------------------------------ + +/\w*\S/BZ +------------------------------------------------------------------ + Bra + \w* + \S + Ket + End +------------------------------------------------------------------ + +/\w*\w/BZ +------------------------------------------------------------------ + Bra + \w* + \w + Ket + End +------------------------------------------------------------------ + +/\w*\W/BZ +------------------------------------------------------------------ + Bra + \w*+ + \W + Ket + End +------------------------------------------------------------------ + +/\W*a/BZ +------------------------------------------------------------------ + Bra + \W*+ + a + Ket + End +------------------------------------------------------------------ + +/\W*2/BZ +------------------------------------------------------------------ + Bra + \W*+ + 2 + Ket + End +------------------------------------------------------------------ + +/\W*\d/BZ +------------------------------------------------------------------ + Bra + \W*+ + \d + Ket + End +------------------------------------------------------------------ + +/\W*\D/BZ +------------------------------------------------------------------ + Bra + \W* + \D + Ket + End +------------------------------------------------------------------ + +/\W*\s/BZ +------------------------------------------------------------------ + Bra + \W* + \s + Ket + End +------------------------------------------------------------------ + +/\W*\S/BZ +------------------------------------------------------------------ + Bra + \W* + \S + Ket + End +------------------------------------------------------------------ + +/\W*\w/BZ +------------------------------------------------------------------ + Bra + \W*+ + \w + Ket + End +------------------------------------------------------------------ + +/\W*\W/BZ +------------------------------------------------------------------ + Bra + \W* + \W + Ket + End +------------------------------------------------------------------ + +/[^a]+a/BZ +------------------------------------------------------------------ + Bra + [^a]++ + a + Ket + End +------------------------------------------------------------------ + +/[^a]+a/BZi +------------------------------------------------------------------ + Bra + /i [^a]++ + /i a + Ket + End +------------------------------------------------------------------ + +/[^a]+A/BZi +------------------------------------------------------------------ + Bra + /i [^a]++ + /i A + Ket + End +------------------------------------------------------------------ + +/[^a]+b/BZ +------------------------------------------------------------------ + Bra + [^a]+ + b + Ket + End +------------------------------------------------------------------ + +/[^a]+\d/BZ +------------------------------------------------------------------ + Bra + [^a]+ + \d + Ket + End +------------------------------------------------------------------ + +/a*[^a]/BZ +------------------------------------------------------------------ + Bra + a* + [^a] + Ket + End +------------------------------------------------------------------ + +/(?Px)(?Py)/I +Capturing subpattern count = 2 +Named capturing subpatterns: + abc 1 + xyz 2 +No options +First char = 'x' +Need char = 'y' + xy\Cabc\Cxyz + 0: xy + 1: x + 2: y + C x (1) abc + C y (1) xyz + +/(?x)(?'xyz'y)/I +Capturing subpattern count = 2 +Named capturing subpatterns: + abc 1 + xyz 2 +No options +First char = 'x' +Need char = 'y' + xy\Cabc\Cxyz + 0: xy + 1: x + 2: y + C x (1) abc + C y (1) xyz + +/(?x)(?'xyz>y)/I +Failed: syntax error in subpattern name (missing terminator) at offset 15 + +/(?P'abc'x)(?Py)/I +Failed: unrecognized character after (?P at offset 3 + +/^(?:(?(ZZ)a|b)(?X))+/ + bXaX + 0: bXaX + 1: X + bXbX + 0: bX + 1: X + ** Failers +No match + aXaX +No match + aXbX +No match + +/^(?P>abc)(?xxx)/ +Failed: reference to non-existent subpattern at offset 8 + +/^(?P>abc)(?x|y)/ + xx + 0: xx + 1: x + xy + 0: xy + 1: y + yy + 0: yy + 1: y + yx + 0: yx + 1: x + +/^(?P>abc)(?Px|y)/ + xx + 0: xx + 1: x + xy + 0: xy + 1: y + yy + 0: yy + 1: y + yx + 0: yx + 1: x + +/^((?(abc)a|b)(?x|y))+/ + bxay + 0: bxay + 1: ay + 2: y + bxby + 0: bx + 1: bx + 2: x + ** Failers +No match + axby +No match + +/^(((?P=abc)|X)(?x|y))+/ + XxXxxx + 0: XxXxxx + 1: xx + 2: x + 3: x + XxXyyx + 0: XxXyyx + 1: yx + 2: y + 3: x + XxXyxx + 0: XxXy + 1: Xy + 2: X + 3: y + ** Failers +No match + x +No match + +/^(?1)(abc)/ + abcabc + 0: abcabc + 1: abc + +/^(?:(?:\1|X)(a|b))+/ + Xaaa + 0: Xaaa + 1: a + Xaba + 0: Xa + 1: a + +/^[\E\Qa\E-\Qz\E]+/BZ +------------------------------------------------------------------ + Bra + ^ + [a-z]+ + Ket + End +------------------------------------------------------------------ + +/^[a\Q]bc\E]/BZ +------------------------------------------------------------------ + Bra + ^ + [\]a-c] + Ket + End +------------------------------------------------------------------ + +/^[a-\Q\E]/BZ +------------------------------------------------------------------ + Bra + ^ + [\-a] + Ket + End +------------------------------------------------------------------ + +/^(?P>abc)[()](?)/BZ +------------------------------------------------------------------ + Bra + ^ + Recurse + [()] + CBra 1 + Ket + Ket + End +------------------------------------------------------------------ + +/^((?(abc)y)[()](?Px))+/BZ +------------------------------------------------------------------ + Bra + ^ + CBra 1 + Cond + 2 Cond nref + y + Ket + [()] + CBra 2 + x + Ket + KetRmax + Ket + End +------------------------------------------------------------------ + (xy)x + 0: (xy)x + 1: y)x + 2: x + +/^(?P>abc)\Q()\E(?)/BZ +------------------------------------------------------------------ + Bra + ^ + Recurse + () + CBra 1 + Ket + Ket + End +------------------------------------------------------------------ + +/^(?P>abc)[a\Q(]\E(](?)/BZ +------------------------------------------------------------------ + Bra + ^ + Recurse + [(\]a] + CBra 1 + Ket + Ket + End +------------------------------------------------------------------ + +/^(?P>abc) # this is (a comment) + (?)/BZx +------------------------------------------------------------------ + Bra + ^ + Recurse + CBra 1 + Ket + Ket + End +------------------------------------------------------------------ + +/^\W*(?:(?(?.)\W*(?&one)\W*\k|)|(?(?.)\W*(?&three)\W*\k'four'|\W*.\W*))\W*$/Ii +Capturing subpattern count = 4 +Max back reference = 4 +Named capturing subpatterns: + four 4 + one 1 + three 3 + two 2 +Options: anchored caseless +No first char +No need char + 1221 + 0: 1221 + 1: 1221 + 2: 1 + Satan, oscillate my metallic sonatas! + 0: Satan, oscillate my metallic sonatas! + 1: + 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 + +/(?=(\w+))\1:/I +Capturing subpattern count = 1 +Max back reference = 1 +No options +No first char +Need char = ':' + abcd: + 0: abcd: + 1: abcd + +/(?=(?'abc'\w+))\k:/I +Capturing subpattern count = 1 +Max back reference = 1 +Named capturing subpatterns: + abc 1 +No options +No first char +Need char = ':' + abcd: + 0: abcd: + 1: abcd + +/(?'abc'a|b)(?d|e)\k{2}/J + adaa + 0: adaa + 1: a + 2: d + ** Failers +No match + addd +No match + adbb +No match + +/(?'abc'a|b)(?d|e)(?&abc){2}/J + bdaa + 0: bdaa + 1: b + 2: d + bdab + 0: bdab + 1: b + 2: d + ** Failers +No match + bddd +No match + +/(?( (?'B' abc (?(R) (?(R&A)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x + abcabc1Xabc2XabcXabcabc + 0: abcabc1Xabc2XabcX + 1: abcabc1Xabc2XabcX + 2: abcabc1Xabc2XabcX + +/(? (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x +Failed: reference to non-existent subpattern at offset 29 + +/(?<1> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x + abcabc1Xabc2XabcXabcabc + 0: abcabc1Xabc2XabcX + 1: abcabc1Xabc2XabcX + 2: abcabc1Xabc2XabcX + +/^(?(DEFINE) abc | xyz ) /x +Failed: DEFINE group contains more than one branch at offset 22 + +/(?(DEFINE) abc) xyz/xI +Capturing subpattern count = 0 +Options: extended +First char = 'x' +Need char = 'z' + +/(a|)*\d/ + \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 +Matched, but too many substrings + +/^a.b/ + a\rb + 0: a\x0db + a\nb\ + 0: a\x0ab + a\x85b\ + 0: a\x85b + ** Failers +No match + a\nb +No match + a\nb\ +No match + a\rb\ +No match + a\rb\ +No match + a\x85b\ +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 abc7 abc9 + 0: abc1 + 0: abc2 + 0: abc3 + 0: abc4 + 0: abc5 + 0: abc6 + 0: abc9 + +/a/ + +/a/ +Failed: inconsistent NEWLINE options at offset 0 + +/^a\Rb/ + a\nb + 0: a\x0ab + a\rb + 0: a\x0db + a\r\nb + 0: a\x0d\x0ab + a\x0bb + 0: a\x0bb + a\x0cb + 0: a\x0cb + a\x85b + 0: a\x85b + ** Failers +No match + a\n\rb +No match + +/^a\R*b/ + ab + 0: ab + a\nb + 0: a\x0ab + a\rb + 0: a\x0db + a\r\nb + 0: a\x0d\x0ab + a\x0bb + 0: a\x0bb + a\x0cb + 0: a\x0cb + a\x85b + 0: a\x85b + a\n\rb + 0: a\x0a\x0db + a\n\r\x85\x0cb + 0: a\x0a\x0d\x85\x0cb + +/^a\R+b/ + a\nb + 0: a\x0ab + a\rb + 0: a\x0db + a\r\nb + 0: a\x0d\x0ab + a\x0bb + 0: a\x0bb + a\x0cb + 0: a\x0cb + a\x85b + 0: a\x85b + a\n\rb + 0: a\x0a\x0db + a\n\r\x85\x0cb + 0: a\x0a\x0d\x85\x0cb + ** Failers +No match + ab +No match + +/^a\R{1,3}b/ + a\nb + 0: a\x0ab + a\n\rb + 0: a\x0a\x0db + a\n\r\x85b + 0: a\x0a\x0d\x85b + a\r\n\r\nb + 0: a\x0d\x0a\x0d\x0ab + a\r\n\r\n\r\nb + 0: a\x0d\x0a\x0d\x0a\x0d\x0ab + a\n\r\n\rb + 0: a\x0a\x0d\x0a\x0db + a\n\n\r\nb + 0: a\x0a\x0a\x0d\x0ab + ** Failers +No match + a\n\n\n\rb +No match + a\r +No match + +/^a[\R]b/ + aRb + 0: aRb + ** Failers +No match + a\nb +No match + +/(?&abc)X(?P)/I +Capturing subpattern count = 1 +Named capturing subpatterns: + abc 1 +No options +No first char +Need char = 'P' + abcPXP123 + 0: PXP + 1: P + +/(?1)X(?P)/I +Capturing subpattern count = 1 +Named capturing subpatterns: + abc 1 +No options +No first char +Need char = 'P' + abcPXP123 + 0: PXP + 1: P + +/(?:a(?&abc)b)*(?x)/ + 123axbaxbaxbx456 + 0: axbaxbaxbx + 1: x + 123axbaxbaxb456 + 0: x + 1: x + +/(?:a(?&abc)b){1,5}(?x)/ + 123axbaxbaxbx456 + 0: axbaxbaxbx + 1: x + +/(?:a(?&abc)b){2,5}(?x)/ + 123axbaxbaxbx456 + 0: axbaxbaxbx + 1: x + +/(?:a(?&abc)b){2,}(?x)/ + 123axbaxbaxbx456 + 0: axbaxbaxbx + 1: x + +/(abc)(?i:(?1))/ + defabcabcxyz + 0: abcabc + 1: abc + DEFabcABCXYZ +No match + +/(abc)(?:(?i)(?1))/ + defabcabcxyz + 0: abcabc + 1: abc + DEFabcABCXYZ +No match + +/^(a)\g-2/ +Failed: reference to non-existent subpattern at offset 7 + +/^(a)\g/ +Failed: a numbered reference must not be zero at offset 5 + +/^(a)\g{0}/ +Failed: a numbered reference must not be zero at offset 8 + +/^(a)\g{3/ +Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 8 + +/^(a)\g{4a}/ +Failed: reference to non-existent subpattern at offset 9 + +/^a.b/ + a\rb + 0: a\x0db + *** Failers +No match + a\nb +No match + +/.+foo/ + afoo + 0: afoo + ** Failers +No match + \r\nfoo +No match + \nfoo +No match + +/.+foo/ + afoo + 0: afoo + \nfoo + 0: \x0afoo + ** Failers +No match + \r\nfoo +No match + +/.+foo/ + afoo + 0: afoo + ** Failers +No match + \nfoo +No match + \r\nfoo +No match + +/.+foo/s + afoo + 0: afoo + \r\nfoo + 0: \x0d\x0afoo + \nfoo + 0: \x0afoo + +/^$/mg + abc\r\rxyz + 0: + abc\n\rxyz + 0: + ** Failers +No match + abc\r\nxyz +No match + +/(?m)^$/g+ + abc\r\n\r\n + 0: + 0+ \x0d\x0a + +/(?m)^$|^\r\n/g+ + abc\r\n\r\n + 0: + 0+ \x0d\x0a + 0: \x0d\x0a + 0+ + +/(?m)$/g+ + abc\r\n\r\n + 0: + 0+ \x0d\x0a\x0d\x0a + 0: + 0+ \x0d\x0a + 0: + 0+ + +/abc.$/mgx + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 + 0: abc1 + 0: abc4 + 0: abc5 + 0: abc9 + +/^X/m + XABC + 0: X + ** Failers +No match + XABC\B +No match + +/(ab|c)(?-1)/BZ +------------------------------------------------------------------ + Bra + CBra 1 + ab + Alt + c + Ket + Recurse + Ket + End +------------------------------------------------------------------ + abc + 0: abc + 1: ab + +/xy(?+1)(abc)/BZ +------------------------------------------------------------------ + Bra + xy + Recurse + CBra 1 + abc + Ket + Ket + End +------------------------------------------------------------------ + xyabcabc + 0: xyabcabc + 1: abc + ** Failers +No match + xyabc +No match + +/x(?-0)y/ +Failed: a numbered reference must not be zero at offset 5 + +/x(?-1)y/ +Failed: reference to non-existent subpattern at offset 5 + +/x(?+0)y/ +Failed: a numbered reference must not be zero at offset 5 + +/x(?+1)y/ +Failed: reference to non-existent subpattern at offset 5 + +/^(abc)?(?(-1)X|Y)/BZ +------------------------------------------------------------------ + Bra + ^ + Brazero + CBra 1 + abc + Ket + Cond + 1 Cond ref + X + Alt + Y + Ket + Ket + End +------------------------------------------------------------------ + abcX + 0: abcX + 1: abc + Y + 0: Y + ** Failers +No match + abcY +No match + +/^((?(+1)X|Y)(abc))+/BZ +------------------------------------------------------------------ + Bra + ^ + CBra 1 + Cond + 2 Cond ref + X + Alt + Y + Ket + CBra 2 + abc + Ket + KetRmax + Ket + End +------------------------------------------------------------------ + YabcXabc + 0: YabcXabc + 1: Xabc + 2: abc + YabcXabcXabc + 0: YabcXabcXabc + 1: Xabc + 2: abc + ** Failers +No match + XabcXabc +No match + +/(?(-1)a)/BZ +Failed: reference to non-existent subpattern at offset 6 + +/((?(-1)a))/BZ +------------------------------------------------------------------ + Bra + CBra 1 + Cond + 1 Cond ref + a + Ket + Ket + Ket + End +------------------------------------------------------------------ + +/((?(-2)a))/BZ +Failed: reference to non-existent subpattern at offset 7 + +/^(?(+1)X|Y)(.)/BZ +------------------------------------------------------------------ + Bra + ^ + Cond + 1 Cond ref + X + Alt + Y + Ket + CBra 1 + Any + Ket + Ket + End +------------------------------------------------------------------ + Y! + 0: Y! + 1: ! + +/(?tom|bon)-\k{A}/ + tom-tom + 0: tom-tom + 1: tom + bon-bon + 0: bon-bon + 1: bon + ** Failers +No match + tom-bon +No match + +/\g{A/ +Failed: syntax error in subpattern name (missing terminator) at offset 4 + +/(?|(abc)|(xyz))/BZ +------------------------------------------------------------------ + Bra + Bra + CBra 1 + abc + Ket + Alt + CBra 1 + xyz + Ket + Ket + Ket + End +------------------------------------------------------------------ + >abc< + 0: abc + 1: abc + >xyz< + 0: xyz + 1: xyz + +/(x)(?|(abc)|(xyz))(x)/BZ +------------------------------------------------------------------ + Bra + CBra 1 + x + Ket + Bra + CBra 2 + abc + Ket + Alt + CBra 2 + xyz + Ket + Ket + CBra 3 + x + Ket + Ket + End +------------------------------------------------------------------ + xabcx + 0: xabcx + 1: x + 2: abc + 3: x + xxyzx + 0: xxyzx + 1: x + 2: xyz + 3: x + +/(x)(?|(abc)(pqr)|(xyz))(x)/BZ +------------------------------------------------------------------ + Bra + CBra 1 + x + Ket + Bra + CBra 2 + abc + Ket + CBra 3 + pqr + Ket + Alt + CBra 2 + xyz + Ket + Ket + CBra 4 + x + Ket + Ket + End +------------------------------------------------------------------ + xabcpqrx + 0: xabcpqrx + 1: x + 2: abc + 3: pqr + 4: x + xxyzx + 0: xxyzx + 1: x + 2: xyz + 3: + 4: x + +/\H++X/BZ +------------------------------------------------------------------ + Bra + \H++ + X + Ket + End +------------------------------------------------------------------ + ** Failers +No match + XXXX +No match + +/\H+\hY/BZ +------------------------------------------------------------------ + Bra + \H++ + \h + Y + Ket + End +------------------------------------------------------------------ + XXXX Y + 0: XXXX Y + +/\H+ Y/BZ +------------------------------------------------------------------ + Bra + \H++ + Y + Ket + End +------------------------------------------------------------------ + +/\h+A/BZ +------------------------------------------------------------------ + Bra + \h++ + A + Ket + End +------------------------------------------------------------------ + +/\v*B/BZ +------------------------------------------------------------------ + Bra + \v*+ + B + Ket + End +------------------------------------------------------------------ + +/\V+\x0a/BZ +------------------------------------------------------------------ + Bra + \V++ + \x0a + Ket + End +------------------------------------------------------------------ + +/A+\h/BZ +------------------------------------------------------------------ + Bra + A++ + \h + Ket + End +------------------------------------------------------------------ + +/ *\H/BZ +------------------------------------------------------------------ + Bra + *+ + \H + Ket + End +------------------------------------------------------------------ + +/A*\v/BZ +------------------------------------------------------------------ + Bra + A*+ + \v + Ket + End +------------------------------------------------------------------ + +/\x0b*\V/BZ +------------------------------------------------------------------ + Bra + \x0b*+ + \V + Ket + End +------------------------------------------------------------------ + +/\d+\h/BZ +------------------------------------------------------------------ + Bra + \d++ + \h + Ket + End +------------------------------------------------------------------ + +/\d*\v/BZ +------------------------------------------------------------------ + Bra + \d*+ + \v + Ket + End +------------------------------------------------------------------ + +/S+\h\S+\v/BZ +------------------------------------------------------------------ + Bra + S++ + \h + \S++ + \v + Ket + End +------------------------------------------------------------------ + +/\w{3,}\h\w+\v/BZ +------------------------------------------------------------------ + Bra + \w{3} + \w*+ + \h + \w++ + \v + Ket + End +------------------------------------------------------------------ + +/\h+\d\h+\w\h+\S\h+\H/BZ +------------------------------------------------------------------ + Bra + \h++ + \d + \h++ + \w + \h++ + \S + \h++ + \H + Ket + End +------------------------------------------------------------------ + +/\v+\d\v+\w\v+\S\v+\V/BZ +------------------------------------------------------------------ + Bra + \v++ + \d + \v++ + \w + \v+ + \S + \v++ + \V + Ket + End +------------------------------------------------------------------ + +/\H+\h\H+\d/BZ +------------------------------------------------------------------ + Bra + \H++ + \h + \H+ + \d + Ket + End +------------------------------------------------------------------ + +/\V+\v\V+\w/BZ +------------------------------------------------------------------ + Bra + \V++ + \v + \V+ + \w + Ket + End +------------------------------------------------------------------ + +/\( (?: [^()]* | (?R) )* \)/x +\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/ +Failed: missing terminating ] for character class at offset 7 + +/[\Q\E]AAA/ +Failed: missing terminating ] for character class at offset 9 + +/[^\E]AAA/ +Failed: missing terminating ] for character class at offset 8 + +/[^\Q\E]AAA/ +Failed: missing terminating ] for character class at offset 10 + +/[\E^]AAA/ +Failed: missing terminating ] for character class at offset 8 + +/[\Q\E^]AAA/ +Failed: missing terminating ] for character class at offset 10 + +/A(*PRUNE)B(*SKIP)C(*THEN)D(*COMMIT)E(*F)F(*FAIL)G(?!)H(*ACCEPT)I/BZ +------------------------------------------------------------------ + Bra + A + *PRUNE + B + *SKIP + C + *THEN + D + *COMMIT + E + *FAIL + F + *FAIL + G + *FAIL + H + *ACCEPT + I + Ket + End +------------------------------------------------------------------ + +/^a+(*FAIL)/C + aaaaaa +--->aaaaaa + +0 ^ ^ + +1 ^ a+ + +3 ^ ^ (*FAIL) + +3 ^ ^ (*FAIL) + +3 ^ ^ (*FAIL) + +3 ^ ^ (*FAIL) + +3 ^ ^ (*FAIL) + +3 ^^ (*FAIL) +No match + +/a+b?c+(*FAIL)/C + aaabccc +--->aaabccc + +0 ^ a+ + +2 ^ ^ b? + +4 ^ ^ c+ + +6 ^ ^ (*FAIL) + +6 ^ ^ (*FAIL) + +6 ^ ^ (*FAIL) + +4 ^ ^ c+ + +2 ^ ^ b? + +4 ^ ^ c+ + +2 ^^ b? + +4 ^^ c+ + +0 ^ a+ + +2 ^ ^ b? + +4 ^ ^ c+ + +6 ^ ^ (*FAIL) + +6 ^ ^ (*FAIL) + +6 ^ ^ (*FAIL) + +4 ^ ^ c+ + +2 ^^ b? + +4 ^^ c+ + +0 ^ a+ + +2 ^^ b? + +4 ^ ^ c+ + +6 ^ ^ (*FAIL) + +6 ^ ^ (*FAIL) + +6 ^ ^ (*FAIL) + +4 ^^ c+ +No match + +/a+b?(*PRUNE)c+(*FAIL)/C + aaabccc +--->aaabccc + +0 ^ a+ + +2 ^ ^ b? + +4 ^ ^ (*PRUNE) ++12 ^ ^ c+ ++14 ^ ^ (*FAIL) ++14 ^ ^ (*FAIL) ++14 ^ ^ (*FAIL) + +0 ^ a+ + +2 ^ ^ b? + +4 ^ ^ (*PRUNE) ++12 ^ ^ c+ ++14 ^ ^ (*FAIL) ++14 ^ ^ (*FAIL) ++14 ^ ^ (*FAIL) + +0 ^ a+ + +2 ^^ b? + +4 ^ ^ (*PRUNE) ++12 ^ ^ c+ ++14 ^ ^ (*FAIL) ++14 ^ ^ (*FAIL) ++14 ^ ^ (*FAIL) +No match + +/a+b?(*COMMIT)c+(*FAIL)/C + aaabccc +--->aaabccc + +0 ^ a+ + +2 ^ ^ b? + +4 ^ ^ (*COMMIT) ++13 ^ ^ c+ ++15 ^ ^ (*FAIL) ++15 ^ ^ (*FAIL) ++15 ^ ^ (*FAIL) +No match + +/a+b?(*SKIP)c+(*FAIL)/C + aaabcccaaabccc +--->aaabcccaaabccc + +0 ^ a+ + +2 ^ ^ b? + +4 ^ ^ (*SKIP) ++11 ^ ^ c+ ++13 ^ ^ (*FAIL) ++13 ^ ^ (*FAIL) ++13 ^ ^ (*FAIL) + +0 ^ a+ + +2 ^ ^ b? + +4 ^ ^ (*SKIP) ++11 ^ ^ c+ ++13 ^ ^ (*FAIL) ++13 ^ ^ (*FAIL) ++13 ^ ^ (*FAIL) +No match + +/a+b?(*THEN)c+(*FAIL)/C + aaabccc +--->aaabccc + +0 ^ a+ + +2 ^ ^ b? + +4 ^ ^ (*THEN) ++11 ^ ^ c+ ++13 ^ ^ (*FAIL) ++13 ^ ^ (*FAIL) ++13 ^ ^ (*FAIL) + +0 ^ a+ + +2 ^ ^ b? + +4 ^ ^ (*THEN) ++11 ^ ^ c+ ++13 ^ ^ (*FAIL) ++13 ^ ^ (*FAIL) ++13 ^ ^ (*FAIL) + +0 ^ a+ + +2 ^^ b? + +4 ^ ^ (*THEN) ++11 ^ ^ c+ ++13 ^ ^ (*FAIL) ++13 ^ ^ (*FAIL) ++13 ^ ^ (*FAIL) +No match + +/a(*MARK)b/ +Failed: (*MARK) must have an argument at offset 7 + +/(?i:A{1,}\6666666666)/ +Failed: number is too big at offset 19 + +/\g6666666666/ +Failed: number is too big at offset 11 + +/[\g6666666666]/BZ +------------------------------------------------------------------ + Bra + [6g] + Ket + End +------------------------------------------------------------------ + +/(?1)\c[/ +Failed: reference to non-existent subpattern at offset 3 + +/.+A/ + \r\nA +No match + +/\nA/ + \r\nA + 0: \x0aA + +/[\r\n]A/ + \r\nA + 0: \x0aA + +/(\r|\n)A/ + \r\nA + 0: \x0aA + 1: \x0a + +/a(*CR)b/ +Failed: (*VERB) not recognized at offset 5 + +/(*CR)a.b/ + a\nb + 0: a\x0ab + ** Failers +No match + a\rb +No match + +/(*CR)a.b/ + a\nb + 0: a\x0ab + ** Failers +No match + a\rb +No match + +/(*LF)a.b/ + a\rb + 0: a\x0db + ** Failers +No match + a\nb +No match + +/(*CRLF)a.b/ + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + ** Failers +No match + a\r\nb +No match + +/(*ANYCRLF)a.b/ + ** Failers +No match + a\rb +No match + a\nb +No match + a\r\nb +No match + +/(*ANY)a.b/ + ** Failers +No match + a\rb +No match + a\nb +No match + a\r\nb +No match + a\x85b +No match + +/(*ANY).*/g + abc\r\ndef + 0: abc + 0: + 0: def + 0: + +/(*ANYCRLF).*/g + abc\r\ndef + 0: abc + 0: + 0: def + 0: + +/(*CRLF).*/g + abc\r\ndef + 0: abc + 0: + 0: def + 0: + +/a\Rb/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + ** Failers +No match + a\x85b +No match + a\x0bb +No match + +/a\Rb/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + a\x85b + 0: a\x85b + a\x0bb + 0: a\x0bb + ** Failers +No match + a\x85b\ +No match + a\x0bb\ +No match + +/a\R?b/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + ** Failers +No match + a\x85b +No match + a\x0bb +No match + +/a\R?b/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + a\x85b + 0: a\x85b + a\x0bb + 0: a\x0bb + ** Failers +No match + a\x85b\ +No match + a\x0bb\ +No match + +/a\R{2,4}b/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\r\n\nb + 0: a\x0d\x0a\x0ab + a\n\r\rb + 0: a\x0a\x0d\x0db + a\r\n\r\n\r\n\r\nb + 0: a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0ab + ** Failers +No match + a\x85\85b +No match + a\x0b\0bb +No match + +/a\R{2,4}b/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\r\rb + 0: a\x0d\x0db + a\n\n\nb + 0: a\x0a\x0a\x0ab + a\r\n\n\r\rb + 0: a\x0d\x0a\x0a\x0d\x0db + a\x85\85b +No match + a\x0b\0bb +No match + ** Failers +No match + a\r\r\r\r\rb +No match + a\x85\85b\ +No match + a\x0b\0bb\ +No match + +/(*BSR_ANYCRLF)a\Rb/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\nb + 0: a\x0ab + a\rb + 0: a\x0db + +/(*BSR_UNICODE)a\Rb/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\x85b + 0: a\x85b + +/(*BSR_ANYCRLF)(*CRLF)a\Rb/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +Forced newline sequence: CRLF +First char = 'a' +Need char = 'b' + a\nb + 0: a\x0ab + a\rb + 0: a\x0db + +/(*CRLF)(*BSR_UNICODE)a\Rb/I +Capturing subpattern count = 0 +Options: bsr_unicode +Forced newline sequence: CRLF +First char = 'a' +Need char = 'b' + a\x85b + 0: a\x85b + +/(*CRLF)(*BSR_ANYCRLF)(*CR)ab/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +Forced newline sequence: CR +First char = 'a' +Need char = 'b' + +/(?)(?&)/ +Failed: subpattern name expected at offset 9 + +/(?)(?&a)/ +Failed: reference to non-existent subpattern at offset 12 + +/(?)(?&aaaaaaaaaaaaaaaaaaaaaaa)/ +Failed: reference to non-existent subpattern at offset 32 + +/(?+-a)/ +Failed: digit expected after (?+ at offset 3 + +/(?-+a)/ +Failed: unrecognized character after (? or (?- at offset 3 + +/(?(-1))/ +Failed: reference to non-existent subpattern at offset 6 + +/(?(+10))/ +Failed: reference to non-existent subpattern at offset 7 + +/(?(10))/ +Failed: reference to non-existent subpattern at offset 6 + +/(?(+2))()()/ + +/(?(2))()()/ + +/\k''/ +Failed: subpattern name expected at offset 3 + +/\k<>/ +Failed: subpattern name expected at offset 3 + +/\k{}/ +Failed: subpattern name expected at offset 3 + +/\k/ +Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 2 + +/\kabc/ +Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 5 + +/(?P=)/ +Failed: subpattern name expected at offset 4 + +/(?P>)/ +Failed: subpattern name expected at offset 4 + +/(?!\w)(?R)/ +Failed: recursive call could loop indefinitely at offset 9 + +/(?=\w)(?R)/ +Failed: recursive call could loop indefinitely at offset 9 + +/(?x|y){0}z/ + xzxx + 0: xz + yzyy + 0: yz + ** Failers +No match + xxz +No match + +/(\3)(\1)(a)/ + cat +No match + +/(\3)(\1)(a)/ + cat + 0: a + 1: + 2: + 3: a + +/TA]/ + The ACTA] comes + 0: TA] + +/TA]/ +Failed: ] is an invalid data character in JavaScript compatibility mode at offset 2 + +/(?2)[]a()b](abc)/ +Failed: reference to non-existent subpattern at offset 3 + +/(?2)[^]a()b](abc)/ +Failed: reference to non-existent subpattern at offset 3 + +/(?1)[]a()b](abc)/ + abcbabc + 0: abcbabc + 1: abc + ** Failers +No match + abcXabc +No match + +/(?1)[^]a()b](abc)/ + abcXabc + 0: abcXabc + 1: abc + ** Failers +No match + abcbabc +No match + +/(?2)[]a()b](abc)(xyz)/ + xyzbabcxyz + 0: xyzbabcxyz + 1: abc + 2: xyz + +/(?&N)[]a(?)](?abc)/ +Failed: reference to non-existent subpattern at offset 4 + +/(?&N)[]a(?)](abc)/ +Failed: reference to non-existent subpattern at offset 4 + +/a[]b/ +Failed: missing terminating ] for character class at offset 4 + +/a[^]b/ +Failed: missing terminating ] for character class at offset 5 + +/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 + +/a(?!)+b/ +Failed: nothing to repeat at offset 5 + +/a(*FAIL)+b/ +Failed: nothing to repeat at offset 8 + +/(abc|pqr|123){0}[xyz]/SI +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x y z + +/(?(?=.*b)b|^)/CI +Capturing subpattern count = 0 +Options: +No first char +No need char + adc +--->adc + +0 ^ (?(?=.*b)b|^) + +2 ^ (?=.*b) + +5 ^ .* + +7 ^ ^ b + +7 ^ ^ b + +7 ^^ b + +7 ^ b ++12 ^ ) ++13 ^ + 0: + abc +--->abc + +0 ^ (?(?=.*b)b|^) + +2 ^ (?=.*b) + +5 ^ .* + +7 ^ ^ b + +7 ^ ^ b + +7 ^^ b + +8 ^ ^ ) + +9 ^ b + +0 ^ (?(?=.*b)b|^) + +2 ^ (?=.*b) + +5 ^ .* + +7 ^ ^ b + +7 ^^ b + +7 ^ b + +8 ^^ ) + +9 ^ b ++10 ^^ | ++13 ^^ + 0: b + +/(?(?=b).*b|^d)/I +Capturing subpattern count = 0 +No options +No first char +No need char + +/(?(?=.*b).*b|^d)/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +No need char + +/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 + +/xyz/CY + abcxyz +--->abcxyz + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +3 ^ ^ + 0: xyz + +/^"((?(?=[a])[^"])|b)*"$/C + "ab" +--->"ab" + +0 ^ ^ + +1 ^ " + +2 ^^ ((?(?=[a])[^"])|b)* + +3 ^^ (?(?=[a])[^"]) + +5 ^^ (?=[a]) + +8 ^^ [a] ++11 ^ ^ ) ++12 ^^ [^"] ++16 ^ ^ ) ++17 ^ ^ | + +3 ^ ^ (?(?=[a])[^"]) + +5 ^ ^ (?=[a]) + +8 ^ ^ [a] ++21 ^ ^ " ++18 ^ ^ b ++19 ^ ^ ) + +3 ^ ^ (?(?=[a])[^"]) + +5 ^ ^ (?=[a]) + +8 ^ ^ [a] ++21 ^ ^ " ++22 ^ ^ $ ++23 ^ ^ + 0: "ab" + 1: + +/^"((?(?=[a])[^"])|b)*"$/ + "ab" + 0: "ab" + 1: + +/^X(?5)(a)(?|(b)|(q))(c)(d)Y/ +Failed: reference to non-existent subpattern at offset 5 + +/^X(?&N)(a)(?|(b)|(q))(c)(d)(?Y)/ + XYabcdY + 0: XYabcdY + 1: a + 2: b + 3: c + 4: d + 5: Y + +/Xa{2,4}b/ + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/Xa{2,4}?b/ + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/Xa{2,4}+b/ + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X\d{2,4}b/ + X\P +Partial match: X + X3\P +Partial match: X3 + X33\P +Partial match: X33 + X333\P +Partial match: X333 + X3333\P +Partial match: X3333 + +/X\d{2,4}?b/ + X\P +Partial match: X + X3\P +Partial match: X3 + X33\P +Partial match: X33 + X333\P +Partial match: X333 + X3333\P +Partial match: X3333 + +/X\d{2,4}+b/ + X\P +Partial match: X + X3\P +Partial match: X3 + X33\P +Partial match: X33 + X333\P +Partial match: X333 + X3333\P +Partial match: X3333 + +/X\D{2,4}b/ + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X\D{2,4}?b/ + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X\D{2,4}+b/ + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X[abc]{2,4}b/ + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X[abc]{2,4}?b/ + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X[abc]{2,4}+b/ + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X[^a]{2,4}b/ + X\P +Partial match: X + Xz\P +Partial match: Xz + Xzz\P +Partial match: Xzz + Xzzz\P +Partial match: Xzzz + Xzzzz\P +Partial match: Xzzzz + +/X[^a]{2,4}?b/ + X\P +Partial match: X + Xz\P +Partial match: Xz + Xzz\P +Partial match: Xzz + Xzzz\P +Partial match: Xzzz + Xzzzz\P +Partial match: Xzzzz + +/X[^a]{2,4}+b/ + X\P +Partial match: X + Xz\P +Partial match: Xz + Xzz\P +Partial match: Xzz + Xzzz\P +Partial match: Xzzz + Xzzzz\P +Partial match: Xzzzz + +/(Y)X\1{2,4}b/ + YX\P +Partial match: YX + YXY\P +Partial match: YXY + YXYY\P +Partial match: YXYY + YXYYY\P +Partial match: YXYYY + YXYYYY\P +Partial match: YXYYYY + +/(Y)X\1{2,4}?b/ + YX\P +Partial match: YX + YXY\P +Partial match: YXY + YXYY\P +Partial match: YXYY + YXYYY\P +Partial match: YXYYY + YXYYYY\P +Partial match: YXYYYY + +/(Y)X\1{2,4}+b/ + YX\P +Partial match: YX + YXY\P +Partial match: YXY + YXYY\P +Partial match: YXYY + YXYYY\P +Partial match: YXYYY + YXYYYY\P +Partial match: YXYYYY + +/\++\KZ|\d+X|9+Y/ + ++++123999\P +Partial match: 123999 + ++++123999Y\P + 0: 999Y + ++++Z1234\P + 0: Z + +/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 + 0: dog + +/dog|dogsbody/ + dogs\P + 0: dog + dogs\P\P + 0: dog + +/dogsbody|dog/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/\bthe cat\b/ + the cat\P + 0: the cat + the cat\P\P +Partial match: the cat + +/abc/ + abc\P + 0: abc + abc\P\P + 0: abc + +/abc\K123/ + xyzabc123pqr + 0: 123 + xyzabc12\P +Partial match: abc12 + xyzabc12\P\P +Partial match: abc12 + +/(?<=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 + +/(?&word)(?&element)(?(DEFINE)(?<[^m][^>]>[^<])(?\w*+))/BZ +------------------------------------------------------------------ + Bra + Recurse + Recurse + Cond + Cond def + CBra 1 + < + [^m] + [^>] + > + [^<] + Ket + CBra 2 + \w*+ + Ket + Ket + Ket + End +------------------------------------------------------------------ + +/(?&word)(?&element)(?(DEFINE)(?<[^\d][^>]>[^<])(?\w*+))/BZ +------------------------------------------------------------------ + Bra + Recurse + Recurse + Cond + Cond def + CBra 1 + < + [\x00-/:-\xff] (neg) + [^>] + > + [^<] + Ket + CBra 2 + \w*+ + Ket + Ket + Ket + End +------------------------------------------------------------------ + +/(ab)(x(y)z(cd(*ACCEPT)))pq/BZ +------------------------------------------------------------------ + Bra + CBra 1 + ab + Ket + CBra 2 + x + CBra 3 + y + Ket + z + CBra 4 + cd + Close 4 + Close 2 + *ACCEPT + Ket + Ket + pq + Ket + End +------------------------------------------------------------------ + +/abc\K/+ + abcdef + 0: + 0+ def + abcdef\N\N + 0: + 0+ def + xyzabcdef\N\N + 0: + 0+ def + ** Failers +No match + abcdef\N +No match + xyzabcdef\N +No match + +/^(?:(?=abc)|abc\K)/+ + abcdef + 0: + 0+ abcdef + abcdef\N\N + 0: + 0+ def + ** Failers +No match + abcdef\N +No match + +/a?b?/+ + xyz + 0: + 0+ xyz + xyzabc + 0: + 0+ xyzabc + xyzabc\N + 0: ab + 0+ c + xyzabc\N\N + 0: + 0+ yzabc + xyz\N\N + 0: + 0+ yz + ** Failers + 0: + 0+ ** Failers + xyz\N +No match + +/^a?b?/+ + xyz + 0: + 0+ xyz + xyzabc + 0: + 0+ xyzabc + ** Failers + 0: + 0+ ** Failers + xyzabc\N +No match + xyzabc\N\N +No match + xyz\N\N +No match + xyz\N +No match + +/^(?a|b\gc)/ + aaaa + 0: a + 1: a + bacxxx + 0: bac + 1: bac + bbaccxxx + 0: bbacc + 1: bbacc + bbbacccxx + 0: bbbaccc + 1: bbbaccc + +/^(?a|b\g'name'c)/ + aaaa + 0: a + 1: a + bacxxx + 0: bac + 1: bac + bbaccxxx + 0: bbacc + 1: bbacc + bbbacccxx + 0: bbbaccc + 1: bbbaccc + +/^(a|b\g<1>c)/ + aaaa + 0: a + 1: a + bacxxx + 0: bac + 1: bac + bbaccxxx + 0: bbacc + 1: bbacc + bbbacccxx + 0: bbbaccc + 1: bbbaccc + +/^(a|b\g'1'c)/ + aaaa + 0: a + 1: a + bacxxx + 0: bac + 1: bac + bbaccxxx + 0: bbacc + 1: bbacc + bbbacccxx + 0: bbbaccc + 1: bbbaccc + +/^(a|b\g'-1'c)/ + aaaa + 0: a + 1: a + bacxxx + 0: bac + 1: bac + bbaccxxx + 0: bbacc + 1: bbacc + bbbacccxx + 0: bbbaccc + 1: bbbaccc + +/(^(a|b\g<-1>c))/ + aaaa + 0: a + 1: a + 2: a + bacxxx + 0: bac + 1: bac + 2: bac + bbaccxxx + 0: bbacc + 1: bbacc + 2: bbacc + bbbacccxx + 0: bbbaccc + 1: bbbaccc + 2: bbbaccc + +/(?-i:\g)(?i:(?a))/ + XaaX + 0: aa + 1: a + XAAX + 0: AA + 1: A + +/(?i:\g)(?-i:(?a))/ + XaaX + 0: aa + 1: a + ** Failers +No match + XAAX +No match + +/(?-i:\g<+1>)(?i:(a))/ + XaaX + 0: aa + 1: a + XAAX + 0: AA + 1: A + +/(?=(?(?#simplesyntax)\$(?[a-zA-Z_\x{7f}-\x{ff}][a-zA-Z0-9_\x{7f}-\x{ff}]*)(?:\[(?[a-zA-Z0-9_\x{7f}-\x{ff}]+|\$\g)\]|->\g(\(.*?\))?)?|(?#simple syntax withbraces)\$\{(?:\g(?\[(?:\g|'(?:\\.|[^'\\])*'|"(?:\g|\\.|[^"\\])*")\])?|\g|\$\{\g\})\}|(?#complexsyntax)\{(?\$(?\g(\g*|\(.*?\))?)(?:->\g)*|\$\g|\$\{\g\})\}))\{/ + +/(?a|b|c)\g*/ + abc + 0: abc + 1: a + accccbbb + 0: accccbbb + 1: a + +/^X(?7)(a)(?|(b)|(q)(r)(s))(c)(d)(Y)/ + XYabcdY + 0: XYabcdY + 1: a + 2: b + 3: + 4: + 5: c + 6: d + 7: Y + +/(?<=b(?1)|zzz)(a)/ + xbaax + 0: a + 1: a + xzzzax + 0: a + 1: a + +/(a)(?<=b\1)/ +Failed: lookbehind assertion is not fixed length at offset 10 + +/(a)(?<=b+(?1))/ +Failed: lookbehind assertion is not fixed length at offset 13 + +/(a+)(?<=b(?1))/ +Failed: lookbehind assertion is not fixed length at offset 14 + +/(a(?<=b(?1)))/ +Failed: lookbehind assertion is not fixed length at offset 13 + +/(?<=b(?1))xyz/ +Failed: reference to non-existent subpattern at offset 8 + +/(?<=b(?1))xyz(b+)pqrstuvew/ +Failed: lookbehind assertion is not fixed length at offset 26 + +/(a|bc)\1/SI +Capturing subpattern count = 1 +Max back reference = 1 +No options +No first char +No need char +Subject length lower bound = 2 +Starting byte set: a b + +/(a|bc)\1{2,3}/SI +Capturing subpattern count = 1 +Max back reference = 1 +No options +No first char +No need char +Subject length lower bound = 3 +Starting byte set: a b + +/(a|bc)(?1)/SI +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 2 +Starting byte set: a b + +/(a|b\1)(a|b\1)/SI +Capturing subpattern count = 2 +Max back reference = 1 +No options +No first char +No need char +Subject length lower bound = 2 +Starting byte set: a b + +/(a|b\1){2}/SI +Capturing subpattern count = 1 +Max back reference = 1 +No options +No first char +No need char +Subject length lower bound = 2 +Starting byte set: a b + +/(a|bbbb\1)(a|bbbb\1)/SI +Capturing subpattern count = 2 +Max back reference = 1 +No options +No first char +No need char +Subject length lower bound = 2 +Starting byte set: a b + +/(a|bbbb\1){2}/SI +Capturing subpattern count = 1 +Max back reference = 1 +No options +No first char +No need char +Subject length lower bound = 2 +Starting byte set: a b + +/^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 +Capturing subpattern count = 1 +Options: anchored +No first char +Need char = ':' +Subject length lower bound = 22 +No set of starting bytes + +/]{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 +First char = '<' +Need char = '>' +Subject length lower bound = 47 +No set of starting bytes + +"(?>.*/)foo"SI +Capturing subpattern count = 0 +No options +No first char +Need char = 'o' +Subject length lower bound = 4 +No set of starting bytes + +/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /xSI +Capturing subpattern count = 0 +Options: extended +No first char +Need char = '-' +Subject length lower bound = 8 +No set of starting bytes + +/(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/iSI +Capturing subpattern count = 1 +Options: caseless +No first char +No need char +Subject length lower bound = 1 +Starting byte set: A B C a b c + +/(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/SI +Capturing subpattern count = 0 +No options +No first char +Need char = 'b' +Subject length lower bound = 41 +Starting byte set: c d + +/A)|(?
B))/I +Capturing subpattern count = 1 +Named capturing subpatterns: + a 1 + a 1 +No options +No first char +No need char + AB\Ca + 0: A + 1: A + C A (1) a + BA\Ca + 0: B + 1: B + C B (1) a + +/(?|(?A)|(?B))/ +Failed: different names for subpatterns of the same number are not allowed at offset 15 + +/(?:a(? (?')|(?")) | + b(? (?')|(?")) ) + (?('quote')[a-z]+|[0-9]+)/JIx +Capturing subpattern count = 6 +Named capturing subpatterns: + apostrophe 2 + apostrophe 5 + quote 1 + quote 4 + realquote 3 + realquote 6 +Options: extended dupnames +No first char +No need char + 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 + a"11111 +No match + +/^(?|(a)(b)(c)(?d)|(?e)) (?('D')X|Y)/JDZx +------------------------------------------------------------------ + Bra + ^ + Bra + CBra 1 + a + Ket + CBra 2 + b + Ket + CBra 3 + c + Ket + CBra 4 + d + Ket + Alt + CBra 1 + e + Ket + Ket + Cond + 4 Cond nref + X + Alt + Y + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 4 +Named capturing subpatterns: + D 4 + D 1 +Options: anchored extended dupnames +No first char +No need char + abcdX + 0: abcdX + 1: a + 2: b + 3: c + 4: d + eX + 0: eX + 1: e + ** Failers +No match + abcdY +No match + ey +No match + +/(?a) (b)(c) (?d (?(R&A)$ | (?4)) )/JDZx +------------------------------------------------------------------ + Bra + CBra 1 + a + Ket + CBra 2 + b + Ket + CBra 3 + c + Ket + CBra 4 + d + Cond + Cond nrecurse 1 + $ + Alt + Recurse + Ket + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 4 +Named capturing subpatterns: + A 1 + A 4 +Options: extended dupnames +First char = 'a' +Need char = 'd' + abcdd + 0: abcdd + 1: a + 2: b + 3: c + 4: dd + ** Failers +No match + abcdde +No match + +/abcd*/ + xxxxabcd\P + 0: abcd + xxxxabcd\P\P +Partial match: abcd + +/abcd*/i + xxxxabcd\P + 0: abcd + xxxxabcd\P\P +Partial match: abcd + XXXXABCD\P + 0: ABCD + XXXXABCD\P\P +Partial match: ABCD + +/abc\d*/ + xxxxabc1\P + 0: abc1 + xxxxabc1\P\P +Partial match: abc1 + +/(a)bc\1*/ + xxxxabca\P + 0: abca + 1: a + xxxxabca\P\P +Partial match: abca + +/abc[de]*/ + xxxxabcde\P + 0: abcde + xxxxabcde\P\P +Partial match: abcde + +/-- This is not in the Perl >= 5.10 test because Perl seems currently to be + broken and not behaving as specified in that it *does* bumpalong after + hitting (*COMMIT). --/ + +/(?1)(A(*COMMIT)|B)D/ + ABD + 0: ABD + 1: B + XABD + 0: ABD + 1: B + BAD + 0: BAD + 1: A + ABXABD + 0: ABD + 1: B + ** Failers +No match + ABX +No match + BAXBAD +No match + +/(\3)(\1)(a)/ + cat + 0: a + 1: + 2: + 3: a + +/(\3)(\1)(a)/SI +Capturing subpattern count = 3 +Max back reference = 3 +Options: +No first char +Need char = 'a' +Subject length lower bound = 1 +No set of starting bytes + cat + 0: a + 1: + 2: + 3: a + +/(\3)(\1)(a)/SI +Capturing subpattern count = 3 +Max back reference = 3 +No options +No first char +Need char = 'a' +Subject length lower bound = 3 +No set of starting bytes + cat +No match + +/i(?(DEFINE)(?a))/SI +Capturing subpattern count = 1 +Named capturing subpatterns: + s 1 +No options +First char = 'i' +No need char +Subject length lower bound = 1 +No set of starting bytes + i + 0: i + +/()i(?(1)a)/SI +Capturing subpattern count = 1 +No options +No first char +Need char = 'i' +Subject length lower bound = 1 +Starting byte set: i + ia + 0: ia + 1: + +/(?i)a(?-i)b|c/BZ +------------------------------------------------------------------ + Bra + /i a + b + Alt + c + Ket + End +------------------------------------------------------------------ + XabX + 0: ab + XAbX + 0: Ab + CcC + 0: c + ** Failers +No match + XABX +No match + +/(?i)a(?s)b|c/BZ +------------------------------------------------------------------ + Bra + /i ab + Alt + /i c + Ket + End +------------------------------------------------------------------ + +/(?i)a(?s-i)b|c/BZ +------------------------------------------------------------------ + Bra + /i a + b + Alt + c + Ket + End +------------------------------------------------------------------ + +/^(ab(c\1)d|x){2}$/BZ +------------------------------------------------------------------ + Bra + ^ + Once + CBra 1 + ab + CBra 2 + c + \1 + Ket + d + Alt + x + Ket + Ket + Once + CBra 1 + ab + CBra 2 + c + \1 + Ket + d + Alt + x + Ket + Ket + $ + Ket + End +------------------------------------------------------------------ + xabcxd + 0: xabcxd + 1: abcxd + 2: cx + +/^(?&t)*+(?(DEFINE)(?.))$/BZ +------------------------------------------------------------------ + Bra + ^ + Braposzero + SBraPos + Recurse + KetRpos + Cond + Cond def + CBra 1 + Any + Ket + Ket + $ + Ket + End +------------------------------------------------------------------ + +/^(?&t)*(?(DEFINE)(?.))$/BZ +------------------------------------------------------------------ + Bra + ^ + Brazero + Once + Recurse + KetRmax + Cond + Cond def + CBra 1 + Any + Ket + Ket + $ + Ket + End +------------------------------------------------------------------ + +/ -- The first four of these are not in the Perl >= 5.10 test because Perl + documents that the use of \K in assertions is "not well defined". The + last is here because Perl gives the match as "b" rather than "ab". I + believe this to be a Perl bug. --/ + +/(?=a\Kb)ab/ + ab + 0: b + +/(?!a\Kb)ac/ + ac + 0: ac + +/^abc(?<=b\Kc)d/ + abcd + 0: cd + +/^abc(?a\Kb)z|(ab)/ + ab + 0: ab + 1: ab + +/----------------------/ + +/(?P(?P0|)|(?P>L2)(?P>L1))/ +Failed: recursive call could loop indefinitely at offset 31 + +/abc(*MARK:)pqr/ +Failed: (*MARK) must have an argument at offset 10 + +/abc(*:)pqr/ +Failed: (*MARK) must have an argument at offset 6 + +/abc(*FAIL:123)xyz/ +Failed: an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) at offset 13 + +/--- This should, and does, fail. In Perl, it does not, which I think is a + bug because replacing the B in the pattern by (B|D) does make it fail. ---/ + +/A(*COMMIT)B/+K + ACABX +No match + +/--- These should be different, but in Perl 5.11 are not, which I think + is a bug in Perl. ---/ + +/A(*THEN)B|A(*THEN)C/K + AC + 0: AC + +/A(*PRUNE)B|A(*PRUNE)C/K + AC +No match + +/--- This should fail; the SKIP advances by one, but when we get to AC, the + PRUNE kills it. Perl behaves differently. ---/ + +/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK + AAAC +No match, mark = A + +/--- Mark names can be duplicated. Perl doesn't give a mark for this one, +though PCRE does. ---/ + +/^A(*:A)B|^X(*:A)Y/K + ** Failers +No match + XAQQ +No match, mark = A + +/--- 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. ---/ + +/(*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 +No match + +/^(ab (c+(*FAIL)cd) | xyz)/x + abcccd +No match + +/--- Perl 5.11 gets some of these wrong ---/ + +/(?>.(*ACCEPT))*?5/ + abcde + 0: a + +/(.(*ACCEPT))*?5/ + abcde + 0: a + 1: a + +/(.(*ACCEPT))5/ + abcde + 0: a + 1: a + +/(.(*ACCEPT))*5/ + abcde + 0: a + 1: a + +/A\NB./BZ +------------------------------------------------------------------ + Bra + A + Any + B + Any + Ket + End +------------------------------------------------------------------ + ACBD + 0: ACBD + *** Failers +No match + A\nB +No match + ACB\n +No match + +/A\NB./sBZ +------------------------------------------------------------------ + Bra + A + Any + B + AllAny + Ket + End +------------------------------------------------------------------ + ACBD + 0: ACBD + ACB\n + 0: ACB\x0a + *** Failers +No match + A\nB +No match + +/A\NB/ + A\nB + 0: A\x0aB + A\rB + 0: A\x0dB + ** Failers +No match + A\r\nB +No match + +/\R+b/BZ +------------------------------------------------------------------ + Bra + \R++ + b + Ket + End +------------------------------------------------------------------ + +/\R+\n/BZ +------------------------------------------------------------------ + Bra + \R+ + \x0a + Ket + End +------------------------------------------------------------------ + +/\R+\d/BZ +------------------------------------------------------------------ + Bra + \R++ + \d + Ket + End +------------------------------------------------------------------ + +/\d*\R/BZ +------------------------------------------------------------------ + Bra + \d*+ + \R + Ket + End +------------------------------------------------------------------ + +/\s*\R/BZ +------------------------------------------------------------------ + Bra + \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. --/ + +/^((abc|abcx)(*THEN)y|abcd)/ + abcd + 0: abcd + 1: abcd + *** Failers +No match + abcxy +No match + +/(?<=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 + abc\>1 + 0: bc + abc\>2 + 0: c + abc\>3 +No match + abc\>4 +Error -24 (bad offset value) + abc\>-4 +Error -24 (bad offset value) + +/^\cÄ£/ +Failed: \c must be followed by an ASCII character at offset 3 + +/(?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 +------------------------------------------------------------------ + +/(?P(?P=abn)(?(?P=axn)xxx)/BZ +Failed: reference to non-existent subpattern at offset 15 + +/(?P(?P=axn)xxx)(?yy)/BZ +------------------------------------------------------------------ + Bra + CBra 1 + \2 + xxx + Ket + CBra 2 + yy + Ket + Ket + 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 + +/-- These are all run as real matches in test 1; here we are just checking the +settings of the anchored and startline bits. --/ + +/(?>.*?a)(?<=ba)/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'a' +Max lookbehind = 2 + +/(?:.*?a)(?<=ba)/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +Need char = 'a' +Max lookbehind = 2 + +/.*?a(*PRUNE)b/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'b' + +/.*?a(*PRUNE)b/sI +Capturing subpattern count = 0 +Options: dotall +No first char +Need char = 'b' + +/^a(*PRUNE)b/sI +Capturing subpattern count = 0 +Options: anchored dotall +No first char +No need char + +/.*?a(*SKIP)b/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'b' + +/(?>.*?a)b/sI +Capturing subpattern count = 0 +Options: dotall +No first char +Need char = 'b' + +/(?>.*?a)b/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'b' + +/(?>^a)b/sI +Capturing subpattern count = 0 +Options: anchored dotall +No first char +No need char + +/(?>.*?)(?<=(abcd)|(wxyz))/I +Capturing subpattern count = 2 +No options +No first char +No need char +Max lookbehind = 4 + +/(?>.*)(?<=(abcd)|(wxyz))/I +Capturing subpattern count = 2 +No options +No first char +No need char +Max lookbehind = 4 + +"(?>.*)foo"I +Capturing subpattern count = 0 +No options +No first char +Need char = 'o' + +"(?>.*?)foo"I +Capturing subpattern count = 0 +No options +No first char +Need char = 'o' + +/(?>^abc)/mI +Capturing subpattern count = 0 +Options: multiline +First char at start or follows newline +Need char = 'c' + +/(?>.*abc)/mI +Capturing subpattern count = 0 +Options: multiline +No first char +Need char = 'c' + +/(?:.*abc)/mI +Capturing subpattern count = 0 +Options: multiline +First char at start or follows newline +Need char = 'c' + +/-- Check PCRE_STUDY_EXTRA_NEEDED --/ + +/.?/S-I +Capturing subpattern count = 0 +No options +No first char +No need char +Study returned NULL + +/.?/S!I +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = -1 +No set of starting bytes + +/-- End of testinput2 --/ diff --git a/tools/pcre/testdata/testoutput20 b/tools/pcre/testdata/testoutput20 new file mode 100644 index 00000000..7753be2d --- /dev/null +++ b/tools/pcre/testdata/testoutput20 @@ -0,0 +1,27 @@ +/-- These DFA tests are for the handling of characters greater than 255 in + 16- or 32-bit, non-UTF mode. --/ + +/^\x{ffff}+/i + \x{ffff} + 0: \x{ffff} + +/^\x{ffff}?/i + \x{ffff} + 0: \x{ffff} + 1: + +/^\x{ffff}*/i + \x{ffff} + 0: \x{ffff} + 1: + +/^\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} + 1: + +/-- End of testinput20 --/ diff --git a/tools/pcre/testdata/testoutput21-16 b/tools/pcre/testdata/testoutput21-16 new file mode 100644 index 00000000..05107989 --- /dev/null +++ b/tools/pcre/testdata/testoutput21-16 @@ -0,0 +1,90 @@ +/-- 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}$ --/ + +(?:[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 + +[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 + +>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/[\W]+/Lfr_FR + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/[^[:alpha:]]+/Lfr_FR + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/\w+/Lfr_FR + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[\w]+/Lfr_FR + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[[:alpha:]]+/Lfr_FR + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[[:alpha:]][[:lower:]][[:upper:]]/DZLfr_FR +------------------------------------------------------------------ + Bra + [A-Za-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\xff] + [a-z\xb5\xdf-\xf6\xf8-\xff] + [A-Z\xc0-\xd6\xd8-\xde] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/-- End of testinput3 --/ diff --git a/tools/pcre/testdata/testoutput4 b/tools/pcre/testdata/testoutput4 new file mode 100644 index 00000000..2082721c --- /dev/null +++ b/tools/pcre/testdata/testoutput4 @@ -0,0 +1,1094 @@ +/-- This set of tests is for UTF support, excluding Unicode properties. It is + compatible with all versions of Perl >= 5.10 and both the 8-bit and 16-bit + PCRE libraries. --/ + +/a.b/8 + acb + 0: acb + a\x7fb + 0: a\x{7f}b + a\x{100}b + 0: a\x{100}b + *** Failers +No match + a\nb +No match + +/a(.{3})b/8 + a\x{4000}xyb + 0: a\x{4000}xyb + 1: \x{4000}xy + a\x{4000}\x7fyb + 0: a\x{4000}\x{7f}yb + 1: \x{4000}\x{7f}y + a\x{4000}\x{100}yb + 0: a\x{4000}\x{100}yb + 1: \x{4000}\x{100}y + *** Failers +No match + a\x{4000}b +No match + ac\ncb +No match + +/a(.*?)(.)/ + a\xc0\x88b + 0: a\xc0 + 1: + 2: \xc0 + +/a(.*?)(.)/8 + a\x{100}b + 0: a\x{100} + 1: + 2: \x{100} + +/a(.*)(.)/ + a\xc0\x88b + 0: a\xc0\x88b + 1: \xc0\x88 + 2: b + +/a(.*)(.)/8 + a\x{100}b + 0: a\x{100}b + 1: \x{100} + 2: b + +/a(.)(.)/ + a\xc0\x92bcd + 0: a\xc0\x92 + 1: \xc0 + 2: \x92 + +/a(.)(.)/8 + a\x{240}bcd + 0: a\x{240}b + 1: \x{240} + 2: b + +/a(.?)(.)/ + a\xc0\x92bcd + 0: a\xc0\x92 + 1: \xc0 + 2: \x92 + +/a(.?)(.)/8 + a\x{240}bcd + 0: a\x{240}b + 1: \x{240} + 2: b + +/a(.??)(.)/ + a\xc0\x92bcd + 0: a\xc0 + 1: + 2: \xc0 + +/a(.??)(.)/8 + a\x{240}bcd + 0: a\x{240} + 1: + 2: \x{240} + +/a(.{3})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + 1: \x{1234}xy + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + 1: \x{1234}\x{4321}y + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + 1: \x{1234}\x{4321}\x{3412} + *** Failers +No match + a\x{1234}b +No match + ac\ncb +No match + +/a(.{3,})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + 1: \x{1234}xy + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + 1: \x{1234}\x{4321}y + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + 1: \x{1234}\x{4321}\x{3412} + axxxxbcdefghijb + 0: axxxxbcdefghijb + 1: xxxxbcdefghij + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + 1: \x{1234}\x{4321}\x{3412}\x{3421} + *** Failers +No match + a\x{1234}b +No match + +/a(.{3,}?)b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + 1: \x{1234}xy + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + 1: \x{1234}\x{4321}y + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + 1: \x{1234}\x{4321}\x{3412} + axxxxbcdefghijb + 0: axxxxb + 1: xxxx + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + 1: \x{1234}\x{4321}\x{3412}\x{3421} + *** Failers +No match + a\x{1234}b +No match + +/a(.{3,5})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + 1: \x{1234}xy + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + 1: \x{1234}\x{4321}y + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + 1: \x{1234}\x{4321}\x{3412} + axxxxbcdefghijb + 0: axxxxb + 1: xxxx + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + 1: \x{1234}\x{4321}\x{3412}\x{3421} + axbxxbcdefghijb + 0: axbxxb + 1: xbxx + axxxxxbcdefghijb + 0: axxxxxb + 1: xxxxx + *** Failers +No match + a\x{1234}b +No match + axxxxxxbcdefghijb +No match + +/a(.{3,5}?)b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + 1: \x{1234}xy + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + 1: \x{1234}\x{4321}y + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + 1: \x{1234}\x{4321}\x{3412} + axxxxbcdefghijb + 0: axxxxb + 1: xxxx + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + 1: \x{1234}\x{4321}\x{3412}\x{3421} + axbxxbcdefghijb + 0: axbxxb + 1: xbxx + axxxxxbcdefghijb + 0: axxxxxb + 1: xxxxx + *** Failers +No match + a\x{1234}b +No match + axxxxxxbcdefghijb +No match + +/^[a\x{c0}]/8 + *** Failers +No match + \x{100} +No match + +/(?<=aXb)cd/8 + aXbcd + 0: cd + +/(?<=a\x{100}b)cd/8 + a\x{100}bcd + 0: cd + +/(?<=a\x{100000}b)cd/8 + a\x{100000}bcd + 0: cd + +/(?:\x{100}){3}b/8 + \x{100}\x{100}\x{100}b + 0: \x{100}\x{100}\x{100}b + *** Failers +No match + \x{100}\x{100}b +No match + +/\x{ab}/8 + \x{ab} + 0: \x{ab} + \xc2\xab + 0: \x{ab} + *** Failers +No match + \x00{ab} +No match + +/(?<=(.))X/8 + WXYZ + 0: X + 1: W + \x{256}XYZ + 0: X + 1: \x{256} + *** Failers +No match + XYZ +No match + +/[^a]+/8g + bcd + 0: bcd + \x{100}aY\x{256}Z + 0: \x{100} + 0: Y\x{256}Z + +/^[^a]{2}/8 + \x{100}bc + 0: \x{100}b + +/^[^a]{2,}/8 + \x{100}bcAa + 0: \x{100}bcA + +/^[^a]{2,}?/8 + \x{100}bca + 0: \x{100}b + +/[^a]+/8ig + bcd + 0: bcd + \x{100}aY\x{256}Z + 0: \x{100} + 0: Y\x{256}Z + +/^[^a]{2}/8i + \x{100}bc + 0: \x{100}b + +/^[^a]{2,}/8i + \x{100}bcAa + 0: \x{100}bc + +/^[^a]{2,}?/8i + \x{100}bca + 0: \x{100}b + +/\x{100}{0,0}/8 + abcd + 0: + +/\x{100}?/8 + abcd + 0: + \x{100}\x{100} + 0: \x{100} + +/\x{100}{0,3}/8 + \x{100}\x{100} + 0: \x{100}\x{100} + \x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100} + +/\x{100}*/8 + abce + 0: + \x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100}\x{100} + +/\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} + +/\x{100}+/8 + abcd\x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100}\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} + +/\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} + +/(?<=a\x{100}{2}b)X/8+ + Xyyya\x{100}\x{100}bXzzz + 0: X + 0+ zzz + +/\D*/8 + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/\D*/8 + \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 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} + +/\D/8 + 1X2 + 0: X + 1\x{100}2 + 0: \x{100} + +/>\S/8 + > >X Y + 0: >X + > >\x{100} Y + 0: >\x{100} + +/\d/8 + \x{100}3 + 0: 3 + +/\s/8 + \x{100} X + 0: + +/\D+/8 + 12abcd34 + 0: abcd + *** Failers + 0: *** Failers + 1234 +No match + +/\D{2,3}/8 + 12abcd34 + 0: abc + 12ab34 + 0: ab + *** Failers + 0: *** + 1234 +No match + 12a34 +No match + +/\D{2,3}?/8 + 12abcd34 + 0: ab + 12ab34 + 0: ab + *** Failers + 0: ** + 1234 +No match + 12a34 +No match + +/\d+/8 + 12abcd34 + 0: 12 + *** Failers +No match + +/\d{2,3}/8 + 12abcd34 + 0: 12 + 1234abcd + 0: 123 + *** Failers +No match + 1.4 +No match + +/\d{2,3}?/8 + 12abcd34 + 0: 12 + 1234abcd + 0: 12 + *** Failers +No match + 1.4 +No match + +/\S+/8 + 12abcd34 + 0: 12abcd34 + *** Failers + 0: *** + \ \ +No match + +/\S{2,3}/8 + 12abcd34 + 0: 12a + 1234abcd + 0: 123 + *** Failers + 0: *** + \ \ +No match + +/\S{2,3}?/8 + 12abcd34 + 0: 12 + 1234abcd + 0: 12 + *** Failers + 0: ** + \ \ +No match + +/>\s+ <34 + 0: > < + 0+ 34 + *** Failers +No match + +/>\s{2,3} < + 0+ cd + ab> < + 0+ ce + *** Failers +No match + ab> \s{2,3}? < + 0+ cd + ab> < + 0+ ce + *** Failers +No match + ab> \xff< + 0: \xff + +/[\xff]/8 + >\x{ff}< + 0: \x{ff} + +/[^\xFF]/ + XYZ + 0: X + +/[^\xff]/8 + XYZ + 0: X + \x{123} + 0: \x{123} + +/^[ac]*b/8 + xb +No match + +/^[ac\x{100}]*b/8 + xb +No match + +/^[^x]*b/8i + xb +No match + +/^[^x]*b/8 + xb +No match + +/^\d*b/8 + xb +No match + +/(|a)/g8 + catac + 0: + 1: + 0: + 1: + 0: a + 1: a + 0: + 1: + 0: + 1: + 0: a + 1: a + 0: + 1: + 0: + 1: + a\x{256}a + 0: + 1: + 0: a + 1: a + 0: + 1: + 0: + 1: + 0: a + 1: a + 0: + 1: + +/^\x{85}$/8i + \x{85} + 0: \x{85} + +/^ሴ/8 + ሴ + 0: \x{1234} + +/^\ሴ/8 + ሴ + 0: \x{1234} + +"(?s)(.{1,5})"8 + abcdefg + 0: abcde + 1: abcde + ab + 0: ab + 1: ab + +/a*\x{100}*\w/8 + a + 0: a + +/\S\S/8g + A\x{a3}BC + 0: A\x{a3} + 0: BC + +/\S{2}/8g + A\x{a3}BC + 0: A\x{a3} + 0: BC + +/\W\W/8g + +\x{a3}== + 0: +\x{a3} + 0: == + +/\W{2}/8g + +\x{a3}== + 0: +\x{a3} + 0: == + +/\S/8g + \x{442}\x{435}\x{441}\x{442} + 0: \x{442} + 0: \x{435} + 0: \x{441} + 0: \x{442} + +/[\S]/8g + \x{442}\x{435}\x{441}\x{442} + 0: \x{442} + 0: \x{435} + 0: \x{441} + 0: \x{442} + +/\D/8g + \x{442}\x{435}\x{441}\x{442} + 0: \x{442} + 0: \x{435} + 0: \x{441} + 0: \x{442} + +/[\D]/8g + \x{442}\x{435}\x{441}\x{442} + 0: \x{442} + 0: \x{435} + 0: \x{441} + 0: \x{442} + +/\W/8g + \x{2442}\x{2435}\x{2441}\x{2442} + 0: \x{2442} + 0: \x{2435} + 0: \x{2441} + 0: \x{2442} + +/[\W]/8g + \x{2442}\x{2435}\x{2441}\x{2442} + 0: \x{2442} + 0: \x{2435} + 0: \x{2441} + 0: \x{2442} + +/[\S\s]*/8 + abc\n\r\x{442}\x{435}\x{441}\x{442}xyz + 0: abc\x{0a}\x{0d}\x{442}\x{435}\x{441}\x{442}xyz + +/[\x{41f}\S]/8g + \x{442}\x{435}\x{441}\x{442} + 0: \x{442} + 0: \x{435} + 0: \x{441} + 0: \x{442} + +/.[^\S]./8g + abc def\x{442}\x{443}xyz\npqr + 0: c d + 0: z\x{0a}p + +/.[^\S\n]./8g + abc def\x{442}\x{443}xyz\npqr + 0: c d + +/[[:^alnum:]]/8g + +\x{2442} + 0: + + 0: \x{2442} + +/[[:^alpha:]]/8g + +\x{2442} + 0: + + 0: \x{2442} + +/[[:^ascii:]]/8g + A\x{442} + 0: \x{442} + +/[[:^blank:]]/8g + A\x{442} + 0: A + 0: \x{442} + +/[[:^cntrl:]]/8g + A\x{442} + 0: A + 0: \x{442} + +/[[:^digit:]]/8g + A\x{442} + 0: A + 0: \x{442} + +/[[:^graph:]]/8g + \x19\x{e01ff} + 0: \x{19} + 0: \x{e01ff} + +/[[:^lower:]]/8g + A\x{422} + 0: A + 0: \x{422} + +/[[:^print:]]/8g + \x{19}\x{e01ff} + 0: \x{19} + 0: \x{e01ff} + +/[[:^punct:]]/8g + A\x{442} + 0: A + 0: \x{442} + +/[[:^space:]]/8g + A\x{442} + 0: A + 0: \x{442} + +/[[:^upper:]]/8g + a\x{442} + 0: a + 0: \x{442} + +/[[:^word:]]/8g + +\x{2442} + 0: + + 0: \x{2442} + +/[[:^xdigit:]]/8g + M\x{442} + 0: M + 0: \x{442} + +/[^ABCDEFGHIJKLMNOPQRSTUVWXYZÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖØÙÚÛÜÃÞĀĂĄĆĈĊČĎÄĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶĹĻĽĿÅŃŅŇŊŌŎÅŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽÆƂƄƆƇƉƊƋƎÆÆƑƓƔƖƗƘƜÆƟƠƢƤƦƧƩƬƮƯƱƲƳƵƷƸƼDŽLJNJÇÇǑǓǕǗǙǛǞǠǢǤǦǨǪǬǮDZǴǶǷǸǺǼǾȀȂȄȆȈȊȌȎÈȒȔȖȘȚȜȞȠȢȤȦȨȪȬȮȰȲȺȻȽȾÉΆΈΉΊΌΎÎΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩΪΫϒϓϔϘϚϜϞϠϢϤϦϨϪϬϮϴϷϹϺϽϾϿЀÐЂЃЄЅІЇЈЉЊЋЌÐÐŽÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎÒҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾӀÓÓƒÓ…Ó‡Ó‰Ó‹ÓÓӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӶӸԀԂԄԆԈԊԌԎԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀÕÕ‚ÕƒÕ„Õ…Õ†Õ‡ÕˆÕ‰ÕŠÕ‹ÕŒÕÕŽÕÕՑՒՓՔՕՖႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀáƒáƒ‚ჃჄჅḀḂḄḆḈḊḌḎá¸á¸’ḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎá¹á¹’ṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎáºáº’ẔẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎá»á»’ỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸἈἉἊἋἌá¼á¼Žá¼á¼˜á¼™á¼šá¼›á¼œá¼á¼¨á¼©á¼ªá¼«á¼¬á¼­á¼®á¼¯á¼¸á¼¹á¼ºá¼»á¼¼á¼½á¼¾á¼¿á½ˆá½‰á½Šá½‹á½Œá½á½™á½›á½á½Ÿá½¨á½©á½ªá½«á½¬á½­á½®á½¯á¾¸á¾¹á¾ºá¾»á¿ˆá¿‰á¿Šá¿‹á¿˜á¿™á¿šá¿›á¿¨á¿©á¿ªá¿«á¿¬á¿¸á¿¹á¿ºá¿»abcdefghijklmnopqrstuvwxyzªµºßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿÄăąćĉċÄÄđēĕėęěÄğġģĥħĩīĭįıijĵķĸĺļľŀłńņňʼnŋÅÅőœŕŗřśÅşšţťŧũūŭůűųŵŷźżžſƀƃƅƈƌƃƕƙƚƛƞơƣƥƨƪƫƭưƴƶƹƺƽƾƿdžljnjǎÇǒǔǖǘǚǜÇǟǡǣǥǧǩǫǭǯǰdzǵǹǻǽǿÈȃȅȇȉȋÈÈȑȓȕȗșțÈȟȡȣȥȧȩȫȭȯȱȳȴȵȶȷȸȹȼȿɀÉɑɒɓɔɕɖɗɘəɚɛɜÉɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀÊʂʃʄʅʆʇʈʉʊʋʌÊÊŽÊÊʑʒʓʔʕʖʗʘʙʚʛʜÊʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯÎάέήίΰαβγδεζηθικλμνξοπÏςστυφχψωϊϋόÏÏŽÏϑϕϖϗϙϛÏϟϡϣϥϧϩϫϭϯϰϱϲϳϵϸϻϼабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÑёђѓєѕіїјљњћќÑўџѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿÒÒ‹ÒÒÒ‘Ò“Ò•Ò—Ò™Ò›ÒҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӂӄӆӈӊӌӎӑӓӕӗәӛÓÓŸÓ¡Ó£Ó¥Ó§Ó©Ó«Ó­Ó¯Ó±Ó³ÓµÓ·Ó¹ÔÔƒÔ…Ô‡Ô‰Ô‹ÔÔÕ¡Õ¢Õ£Õ¤Õ¥Õ¦Õ§Õ¨Õ©ÕªÕ«Õ¬Õ­Õ®Õ¯Õ°Õ±Õ²Õ³Õ´ÕµÕ¶Õ·Õ¸Õ¹ÕºÕ»Õ¼Õ½Õ¾Õ¿Ö€Öւփքօֆևᴀá´á´‚ᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌá´á´Žá´á´á´‘ᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜá´á´žá´Ÿá´ á´¡á´¢á´£á´¤á´¥á´¦á´§á´¨á´©á´ªá´«áµ¢áµ£áµ¤áµ¥áµ¦áµ§áµ¨áµ©áµªáµ«áµ¬áµ­áµ®áµ¯áµ°áµ±áµ²áµ³áµ´áµµáµ¶áµ·áµ¹áµºáµ»áµ¼áµ½áµ¾áµ¿á¶€á¶á¶‚ᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌá¶á¶Žá¶á¶á¶‘ᶒᶓᶔᶕᶖᶗᶘᶙᶚá¸á¸ƒá¸…ḇḉḋá¸á¸á¸‘ḓḕḗḙḛá¸á¸Ÿá¸¡á¸£á¸¥á¸§á¸©á¸«á¸­á¸¯á¸±á¸³á¸µá¸·á¸¹á¸»á¸½á¸¿á¹á¹ƒá¹…ṇṉṋá¹á¹á¹‘ṓṕṗṙṛá¹á¹Ÿá¹¡á¹£á¹¥á¹§á¹©á¹«á¹­á¹¯á¹±á¹³á¹µá¹·á¹¹á¹»á¹½á¹¿áºáºƒáº…ẇẉẋáºáºáº‘ẓẕẖẗẘẙẚẛạảấầẩẫậắằẳẵặẹẻẽếá»á»ƒá»…ệỉịá»á»á»‘ồổỗộớá»á»Ÿá»¡á»£á»¥á»§á»©á»«á»­á»¯á»±á»³á»µá»·á»¹á¼€á¼á¼‚ἃἄἅἆἇá¼á¼‘ἒἓἔἕἠἡἢἣἤἥἦἧἰἱἲἳἴἵἶἷὀá½á½‚ὃὄὅá½á½‘ὒὓὔὕὖὗὠὡὢὣὤὥὦὧὰάὲέὴήὶίὸόὺύὼώᾀá¾á¾‚ᾃᾄᾅᾆᾇá¾á¾‘ᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷιῂῃῄῆῇá¿á¿‘ῒΐῖῗῠῡῢΰῤῥῦῧῲῳῴῶῷâ²â²ƒâ²…ⲇⲉⲋâ²â²â²‘ⲓⲕⲗⲙⲛâ²â²Ÿâ²¡â²£â²¥â²§â²©â²«â²­â²¯â²±â²³â²µâ²·â²¹â²»â²½â²¿â³â³ƒâ³…ⳇⳉⳋâ³â³â³‘ⳓⳕⳗⳙⳛâ³â³Ÿâ³¡â³£â³¤â´€â´â´‚ⴃⴄⴅⴆⴇⴈⴉⴊⴋⴌâ´â´Žâ´â´â´‘ⴒⴓⴔⴕⴖⴗⴘⴙⴚⴛⴜâ´â´žâ´Ÿâ´ â´¡â´¢â´£â´¤â´¥ï¬€ï¬ï¬‚ffifflſtstﬓﬔﬕﬖﬗ\d-_^]/8 + +/^[^d]*?$/ + abc + 0: abc + +/^[^d]*?$/8 + abc + 0: abc + +/^[^d]*?$/i + abc + 0: abc + +/^[^d]*?$/8i + abc + 0: abc + +/(?i)[\xc3\xa9\xc3\xbd]|[\xc3\xa9\xc3\xbdA]/8 + +/^[a\x{c0}]b/8 + \x{c0}b + 0: \x{c0}b + +/^([a\x{c0}]*?)aa/8 + a\x{c0}aaaa/ + 0: a\x{c0}aa + 1: a\x{c0} + +/^([a\x{c0}]*?)aa/8 + a\x{c0}aaaa/ + 0: a\x{c0}aa + 1: a\x{c0} + a\x{c0}a\x{c0}aaa/ + 0: a\x{c0}a\x{c0}aa + 1: a\x{c0}a\x{c0} + +/^([a\x{c0}]*)aa/8 + a\x{c0}aaaa/ + 0: a\x{c0}aaaa + 1: a\x{c0}aa + a\x{c0}a\x{c0}aaa/ + 0: a\x{c0}a\x{c0}aaa + 1: a\x{c0}a\x{c0}a + +/^([a\x{c0}]*)a\x{c0}/8 + a\x{c0}aaaa/ + 0: a\x{c0} + 1: + a\x{c0}a\x{c0}aaa/ + 0: a\x{c0}a\x{c0} + 1: a\x{c0} + +/A*/g8 + AAB\x{123}BAA + 0: AA + 0: + 0: + 0: + 0: AA + 0: + +/(abc)\1/8i + abc +No match + +/(abc)\1/8 + abc +No match + +/a(*:a\x{1234}b)/8K + abc + 0: a +MK: a\x{1234}b + +/a(*:a£b)/8K + abc + 0: a +MK: a\x{a3}b + +/-- End of testinput4 --/ diff --git a/tools/pcre/testdata/testoutput5 b/tools/pcre/testdata/testoutput5 new file mode 100644 index 00000000..0e840540 --- /dev/null +++ b/tools/pcre/testdata/testoutput5 @@ -0,0 +1,1849 @@ +/-- 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{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 + +/\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} + +/\x{0041}\x{2262}\x{0391}\x{002e}/DZ8 +------------------------------------------------------------------ + Bra + A\x{2262}\x{391}. + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = '.' + \x{0041}\x{2262}\x{0391}\x{002e} + 0: A\x{2262}\x{391}. + +/.{3,5}X/DZ8 +------------------------------------------------------------------ + Bra + Any{3} + Any{0,2} + X + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +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 + Any{3} + Any{0,2}? + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + \x{212ab}\x{212ab}\x{212ab}\x{861} + 0: \x{212ab}\x{212ab}\x{212ab} + +/(?<=\C)X/8 +Failed: \C not allowed in lookbehind assertion at offset 6 + +/^[ab]/8DZ +------------------------------------------------------------------ + Bra + ^ + [ab] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored utf +No first char +No need char + bar + 0: b + *** Failers +No match + c +No match + \x{ff} +No match + \x{100} +No match + +/^[^ab]/8DZ +------------------------------------------------------------------ + Bra + ^ + [\x00-`c-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored utf +No first char +No need char + c + 0: c + \x{ff} + 0: \x{ff} + \x{100} + 0: \x{100} + *** Failers + 0: * + aaa +No match + +/\x{100}*(\d+|"(?1)")/8 + 1234 + 0: 1234 + 1: 1234 + "1234" + 0: "1234" + 1: "1234" + \x{100}1234 + 0: \x{100}1234 + 1: 1234 + "\x{100}1234" + 0: \x{100}1234 + 1: 1234 + \x{100}\x{100}12ab + 0: \x{100}\x{100}12 + 1: 12 + \x{100}\x{100}"12" + 0: \x{100}\x{100}"12" + 1: "12" + *** Failers +No match + \x{100}\x{100}abcd +No match + +/\x{100}*/8DZ +------------------------------------------------------------------ + Bra + \x{100}* + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/a\x{100}*/8DZ +------------------------------------------------------------------ + Bra + a + \x{100}* + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +No need char + +/ab\x{100}*/8DZ +------------------------------------------------------------------ + Bra + ab + \x{100}* + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = 'b' + +/\x{100}*A/8DZ +------------------------------------------------------------------ + Bra + \x{100}*+ + A + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' + A + 0: A + +/\x{100}*\d(?R)/8DZ +------------------------------------------------------------------ + Bra + \x{100}*+ + \d + Recurse + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/[Z\x{100}]/8DZ +------------------------------------------------------------------ + Bra + [Z\x{100}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + Z\x{100} + 0: Z + \x{100} + 0: \x{100} + \x{100}Z + 0: \x{100} + *** Failers +No match + +/[\x{200}-\x{100}]/8 +Failed: range out of order in character class at offset 15 + +/[Ä€-Ä„]/8 + \x{100} + 0: \x{100} + \x{104} + 0: \x{104} + *** Failers +No match + \x{105} +No match + \x{ff} +No match + +/[z-\x{100}]/8DZ +------------------------------------------------------------------ + Bra + [z-\x{100}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/[z\Qa-d]Ä€\E]/8DZ +------------------------------------------------------------------ + Bra + [\-\]adz\x{100}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + \x{100} + 0: \x{100} + Ä€ + 0: \x{100} + +/[\xFF]/DZ +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = \xff +No need char + >\xff< + 0: \xff + +/[^\xFF]/DZ +------------------------------------------------------------------ + Bra + [^\x{ff}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[Ä-Ãœ]/8 + Ö # Matches without Study + 0: \x{d6} + \x{d6} + 0: \x{d6} + +/[Ä-Ãœ]/8S + Ö <-- Same with Study + 0: \x{d6} + \x{d6} + 0: \x{d6} + +/[\x{c4}-\x{dc}]/8 + Ö # Matches without Study + 0: \x{d6} + \x{d6} + 0: \x{d6} + +/[\x{c4}-\x{dc}]/8S + Ö <-- Same with Study + 0: \x{d6} + \x{d6} + 0: \x{d6} + +/[^\x{100}]abc(xyz(?1))/8DZ +------------------------------------------------------------------ + Bra + [^\x{100}] + abc + CBra 1 + xyz + Recurse + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +Need char = 'z' + +/[ab\x{100}]abc(xyz(?1))/8DZ +------------------------------------------------------------------ + Bra + [ab\x{100}] + abc + CBra 1 + xyz + Recurse + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +Need char = 'z' + +/(\x{100}(b(?2)c))?/DZ8 +------------------------------------------------------------------ + Bra + Brazero + CBra 1 + \x{100} + CBra 2 + b + Recurse + c + Ket + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Options: utf +No first char +No need char + +/(\x{100}(b(?2)c)){0,2}/DZ8 +------------------------------------------------------------------ + Bra + Brazero + Bra + CBra 1 + \x{100} + CBra 2 + b + Recurse + c + Ket + Ket + Brazero + CBra 1 + \x{100} + CBra 2 + b + Recurse + c + Ket + Ket + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Options: utf +No first char +No need char + +/(\x{100}(b(?1)c))?/DZ8 +------------------------------------------------------------------ + Bra + Brazero + CBra 1 + \x{100} + CBra 2 + b + Recurse + c + Ket + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Options: utf +No first char +No need char + +/(\x{100}(b(?1)c)){0,2}/DZ8 +------------------------------------------------------------------ + Bra + Brazero + Bra + CBra 1 + \x{100} + CBra 2 + b + Recurse + c + Ket + Ket + Brazero + CBra 1 + \x{100} + CBra 2 + b + Recurse + c + Ket + Ket + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Options: utf +No first char +No need char + +/\W/8 + A.B + 0: . + A\x{100}B + 0: \x{100} + +/\w/8 + \x{100}X + 0: X + +/^\ሴ/8DZ +------------------------------------------------------------------ + Bra + ^ + \x{1234} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored utf +No first char +No need char + +/\x{100}*\d/8DZ +------------------------------------------------------------------ + Bra + \x{100}*+ + \d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/\x{100}*\s/8DZ +------------------------------------------------------------------ + Bra + \x{100}*+ + \s + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/\x{100}*\w/8DZ +------------------------------------------------------------------ + Bra + \x{100}*+ + \w + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/\x{100}*\D/8DZ +------------------------------------------------------------------ + Bra + \x{100}* + \D + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/\x{100}*\S/8DZ +------------------------------------------------------------------ + Bra + \x{100}* + \S + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/\x{100}*\W/8DZ +------------------------------------------------------------------ + Bra + \x{100}* + \W + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/()()()()()()()()()() + ()()()()()()()()()() + ()()()()()()()()()() + ()()()()()()()()()() + A (x) (?41) B/8x + AxxB +Matched, but too many substrings + 0: AxxB + 1: + 2: + 3: + 4: + 5: + 6: + 7: + 8: + 9: +10: +11: +12: +13: +14: + +/^[\x{100}\E-\Q\E\x{150}]/BZ8 +------------------------------------------------------------------ + Bra + ^ + [\x{100}-\x{150}] + Ket + End +------------------------------------------------------------------ + +/^[\QÄ€\E-\QÅ\E]/BZ8 +------------------------------------------------------------------ + Bra + ^ + [\x{100}-\x{150}] + Ket + End +------------------------------------------------------------------ + +/^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\h\V\v/8 + X X\x0a + 0: X X\x{0a} + X\x09X\x0b + 0: X\x{09}X\x{0b} + ** Failers +No match + \x{a0} X\x0a +No match + +/\H*\h+\V?\v{3,4}/8 + \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} + \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a + 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}\x{0d} + \x09\x20\x{a0}\x0a\x0b\x0c + 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} + ** Failers +No match + \x09\x20\x{a0}\x0a\x0b +No match + +/\H\h\V\v/8 + \x{3001}\x{3000}\x{2030}\x{2028} + 0: \x{3001}\x{3000}\x{2030}\x{2028} + X\x{180e}X\x{85} + 0: X\x{180e}X\x{85} + ** Failers +No match + \x{2009} X\x0a +No match + +/\H*\h+\V?\v{3,4}/8 + \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a + 0: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}\x{0d} + \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} + \x09\x20\x{202f}\x0a\x0b\x0c + 0: \x{09} \x{202f}\x{0a}\x{0b}\x{0c} + ** Failers +No match + \x09\x{200a}\x{a0}\x{2028}\x0b +No match + +/[\h]/8BZ +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] + Ket + End +------------------------------------------------------------------ + >\x{1680} + 0: \x{1680} + +/[\h]{3,}/8BZ +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]{3,} + Ket + End +------------------------------------------------------------------ + >\x{1680}\x{180e}\x{2000}\x{2003}\x{200a}\x{202f}\x{205f}\x{3000}< + 0: \x{1680}\x{180e}\x{2000}\x{2003}\x{200a}\x{202f}\x{205f}\x{3000} + +/[\v]/8BZ +------------------------------------------------------------------ + Bra + [\x0a-\x0d\x85\x{2028}-\x{2029}] + Ket + End +------------------------------------------------------------------ + +/[\H]/8BZ +------------------------------------------------------------------ + Bra + [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}] + Ket + End +------------------------------------------------------------------ + +/[\V]/8BZ +------------------------------------------------------------------ + Bra + [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{10ffff}] + Ket + End +------------------------------------------------------------------ + +/.*$/8 + \x{1ec5} + 0: \x{1ec5} + +/a\Rb/I8 +Capturing subpattern count = 0 +Options: bsr_anycrlf utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + ** Failers +No match + a\x{85}b +No match + a\x0bb +No match + +/a\Rb/I8 +Capturing subpattern count = 0 +Options: bsr_unicode utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x{85}b + 0: a\x{85}b + a\x0bb + 0: a\x{0b}b + ** Failers +No match + a\x{85}b\ +No match + a\x0bb\ +No match + +/a\R?b/I8 +Capturing subpattern count = 0 +Options: bsr_anycrlf utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + ** Failers +No match + a\x{85}b +No match + a\x0bb +No match + +/a\R?b/I8 +Capturing subpattern count = 0 +Options: bsr_unicode utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x{85}b + 0: a\x{85}b + a\x0bb + 0: a\x{0b}b + ** Failers +No match + a\x{85}b\ +No match + a\x0bb\ +No match + +/.*a.*=.b.*/8 + QQQ\x{2029}ABCaXYZ=!bPQR + 0: ABCaXYZ=!bPQR + ** Failers +No match + a\x{2029}b +No match + \x61\xe2\x80\xa9\x62 +No match + +/[[:a\x{100}b:]]/8 +Failed: unknown POSIX class name at offset 3 + +/a[^]b/8 + a\x{1234}b + 0: a\x{1234}b + a\nb + 0: a\x{0a}b + ** Failers +No match + ab +No match + +/a[^]+b/8 + aXb + 0: aXb + a\nX\nX\x{1234}b + 0: a\x{0a}X\x{0a}X\x{1234}b + ** Failers +No match + ab +No match + +/(\x{de})\1/ + \x{de}\x{de} + 0: \xde\xde + 1: \xde + +/X/8f + A\x{1ec5}ABCXYZ + 0: X + +/Xa{2,4}b/8 + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/Xa{2,4}?b/8 + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/Xa{2,4}+b/8 + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X\x{123}{2,4}b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X\x{123}{2,4}?b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X\x{123}{2,4}+b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X\x{123}{2,4}b/8 + Xx\P +No match + X\x{123}x\P +No match + X\x{123}\x{123}x\P +No match + X\x{123}\x{123}\x{123}x\P +No match + X\x{123}\x{123}\x{123}\x{123}x\P +No match + +/X\x{123}{2,4}?b/8 + Xx\P +No match + X\x{123}x\P +No match + X\x{123}\x{123}x\P +No match + X\x{123}\x{123}\x{123}x\P +No match + X\x{123}\x{123}\x{123}\x{123}x\P +No match + +/X\x{123}{2,4}+b/8 + Xx\P +No match + X\x{123}x\P +No match + X\x{123}\x{123}x\P +No match + X\x{123}\x{123}\x{123}x\P +No match + X\x{123}\x{123}\x{123}\x{123}x\P +No match + +/X\d{2,4}b/8 + X\P +Partial match: X + X3\P +Partial match: X3 + X33\P +Partial match: X33 + X333\P +Partial match: X333 + X3333\P +Partial match: X3333 + +/X\d{2,4}?b/8 + X\P +Partial match: X + X3\P +Partial match: X3 + X33\P +Partial match: X33 + X333\P +Partial match: X333 + X3333\P +Partial match: X3333 + +/X\d{2,4}+b/8 + X\P +Partial match: X + X3\P +Partial match: X3 + X33\P +Partial match: X33 + X333\P +Partial match: X333 + X3333\P +Partial match: X3333 + +/X\D{2,4}b/8 + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X\D{2,4}?b/8 + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X\D{2,4}+b/8 + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X\D{2,4}b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X\D{2,4}?b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X\D{2,4}+b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X[abc]{2,4}b/8 + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X[abc]{2,4}?b/8 + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X[abc]{2,4}+b/8 + X\P +Partial match: X + Xa\P +Partial match: Xa + Xaa\P +Partial match: Xaa + Xaaa\P +Partial match: Xaaa + Xaaaa\P +Partial match: Xaaaa + +/X[abc\x{123}]{2,4}b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X[abc\x{123}]{2,4}?b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X[abc\x{123}]{2,4}+b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X[^a]{2,4}b/8 + X\P +Partial match: X + Xz\P +Partial match: Xz + Xzz\P +Partial match: Xzz + Xzzz\P +Partial match: Xzzz + Xzzzz\P +Partial match: Xzzzz + +/X[^a]{2,4}?b/8 + X\P +Partial match: X + Xz\P +Partial match: Xz + Xzz\P +Partial match: Xzz + Xzzz\P +Partial match: Xzzz + Xzzzz\P +Partial match: Xzzzz + +/X[^a]{2,4}+b/8 + X\P +Partial match: X + Xz\P +Partial match: Xz + Xzz\P +Partial match: Xzz + Xzzz\P +Partial match: Xzzz + Xzzzz\P +Partial match: Xzzzz + +/X[^a]{2,4}b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X[^a]{2,4}?b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/X[^a]{2,4}+b/8 + X\P +Partial match: X + X\x{123}\P +Partial match: X\x{123} + X\x{123}\x{123}\P +Partial match: X\x{123}\x{123} + X\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123} + X\x{123}\x{123}\x{123}\x{123}\P +Partial match: X\x{123}\x{123}\x{123}\x{123} + +/(Y)X\1{2,4}b/8 + YX\P +Partial match: YX + YXY\P +Partial match: YXY + YXYY\P +Partial match: YXYY + YXYYY\P +Partial match: YXYYY + YXYYYY\P +Partial match: YXYYYY + +/(Y)X\1{2,4}?b/8 + YX\P +Partial match: YX + YXY\P +Partial match: YXY + YXYY\P +Partial match: YXYY + YXYYY\P +Partial match: YXYYY + YXYYYY\P +Partial match: YXYYYY + +/(Y)X\1{2,4}+b/8 + YX\P +Partial match: YX + YXY\P +Partial match: YXY + YXYY\P +Partial match: YXYY + YXYYY\P +Partial match: YXYYY + YXYYYY\P +Partial match: YXYYYY + +/(\x{123})X\1{2,4}b/8 + \x{123}X\P +Partial match: \x{123}X + \x{123}X\x{123}\P +Partial match: \x{123}X\x{123} + \x{123}X\x{123}\x{123}\P +Partial match: \x{123}X\x{123}\x{123} + \x{123}X\x{123}\x{123}\x{123}\P +Partial match: \x{123}X\x{123}\x{123}\x{123} + \x{123}X\x{123}\x{123}\x{123}\x{123}\P +Partial match: \x{123}X\x{123}\x{123}\x{123}\x{123} + +/(\x{123})X\1{2,4}?b/8 + \x{123}X\P +Partial match: \x{123}X + \x{123}X\x{123}\P +Partial match: \x{123}X\x{123} + \x{123}X\x{123}\x{123}\P +Partial match: \x{123}X\x{123}\x{123} + \x{123}X\x{123}\x{123}\x{123}\P +Partial match: \x{123}X\x{123}\x{123}\x{123} + \x{123}X\x{123}\x{123}\x{123}\x{123}\P +Partial match: \x{123}X\x{123}\x{123}\x{123}\x{123} + +/(\x{123})X\1{2,4}+b/8 + \x{123}X\P +Partial match: \x{123}X + \x{123}X\x{123}\P +Partial match: \x{123}X\x{123} + \x{123}X\x{123}\x{123}\P +Partial match: \x{123}X\x{123}\x{123} + \x{123}X\x{123}\x{123}\x{123}\P +Partial match: \x{123}X\x{123}\x{123}\x{123} + \x{123}X\x{123}\x{123}\x{123}\x{123}\P +Partial match: \x{123}X\x{123}\x{123}\x{123}\x{123} + +/\bthe cat\b/8 + the cat\P + 0: the cat + the cat\P\P +Partial match: the cat + +/abcd*/8 + xxxxabcd\P + 0: abcd + xxxxabcd\P\P +Partial match: abcd + +/abcd*/i8 + xxxxabcd\P + 0: abcd + xxxxabcd\P\P +Partial match: abcd + XXXXABCD\P + 0: ABCD + XXXXABCD\P\P +Partial match: ABCD + +/abc\d*/8 + xxxxabc1\P + 0: abc1 + xxxxabc1\P\P +Partial match: abc1 + +/(a)bc\1*/8 + xxxxabca\P + 0: abca + 1: a + xxxxabca\P\P +Partial match: abca + +/abc[de]*/8 + xxxxabcde\P + 0: abcde + xxxxabcde\P\P +Partial match: abcde + +/X\W{3}X/8 + \PX +Partial match: 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} + +/\S \S/8T1 + \x{a2} \x{84} + 0: \x{a2} \x{84} + +'A#хц'8xBZ +------------------------------------------------------------------ + Bra + A + Ket + End +------------------------------------------------------------------ + +'A#хц + PQ'8xBZ +------------------------------------------------------------------ + Bra + APQ + Ket + End +------------------------------------------------------------------ + +/a+#Ñ…aa + z#XX?/8xBZ +------------------------------------------------------------------ + Bra + a++ + z + Ket + End +------------------------------------------------------------------ + +/a+#Ñ…aa + z#Ñ…?/8xBZ +------------------------------------------------------------------ + Bra + a++ + z + Ket + End +------------------------------------------------------------------ + +/\g{A}xxx#bXX(?'A'123) (?'A'456)/8xBZ +------------------------------------------------------------------ + Bra + \1 + xxx + CBra 1 + 456 + Ket + Ket + End +------------------------------------------------------------------ + +/\g{A}xxx#bÑ…(?'A'123) (?'A'456)/8xBZ +------------------------------------------------------------------ + Bra + \1 + xxx + CBra 1 + 456 + Ket + Ket + End +------------------------------------------------------------------ + +/^\cÄ£/8 +Failed: \c must be followed by an ASCII character at offset 3 + +/(\R*)(.)/s8 + \r\n + 0: \x{0d} + 1: + 2: \x{0d} + \r\r\n\n\r + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0d}\x{0d}\x{0a}\x{0a} + 2: \x{0d} + \r\r\n\n\r\n + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0d}\x{0d}\x{0a}\x{0a} + 2: \x{0d} + +/(\R)*(.)/s8 + \r\n + 0: \x{0d} + 1: + 2: \x{0d} + \r\r\n\n\r + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0a} + 2: \x{0d} + \r\r\n\n\r\n + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0a} + 2: \x{0d} + +/[^\x{1234}]+/iS8I +Capturing subpattern count = 0 +Options: 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\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}\x{d7ff}]+ + Ket + End +------------------------------------------------------------------ + \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\x{86}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]+ + Ket + End +------------------------------------------------------------------ + \x{2028}\x{2029}\x{2027}\x{2030} + 0: \x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + 0: \x{09}\x{0e}\x{84}\x{86} + +/\R+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + 0: \x{85}\x{0a}\x{0b}\x{0c}\x{0d} + +/(..)\1/8 + ab\P +Partial match: ab + aba\P +Partial match: aba + abab\P + 0: abab + 1: ab + +/(..)\1/8i + ab\P +Partial match: ab + abA\P +Partial match: abA + aBAb\P + 0: aBAb + 1: aB + +/(..)\1{2,}/8 + ab\P +Partial match: ab + aba\P +Partial match: aba + abab\P +Partial match: abab + ababa\P +Partial match: ababa + ababab\P + 0: ababab + 1: ab + ababab\P\P +Partial match: ababab + abababa\P + 0: ababab + 1: ab + abababa\P\P +Partial match: abababa + +/(..)\1{2,}/8i + ab\P +Partial match: ab + aBa\P +Partial match: aBa + aBAb\P +Partial match: aBAb + AbaBA\P +Partial match: AbaBA + abABAb\P + 0: abABAb + 1: ab + aBAbaB\P\P +Partial match: aBAbaB + abABabA\P + 0: abABab + 1: ab + abaBABa\P\P +Partial match: abaBABa + +/(..)\1{2,}?x/8i + ab\P +Partial match: ab + abA\P +Partial match: abA + aBAb\P +Partial match: aBAb + abaBA\P +Partial match: abaBA + abAbaB\P +Partial match: abAbaB + abaBabA\P +Partial match: abaBabA + abAbABaBx\P + 0: abAbABaBx + 1: ab + +/./8 + \r\P + 0: \x{0d} + \r\P\P +Partial match: \x{0d} + +/.{2,3}/8 + \r\P +Partial match: \x{0d} + \r\P\P +Partial match: \x{0d} + \r\r\P + 0: \x{0d}\x{0d} + \r\r\P\P +Partial match: \x{0d}\x{0d} + \r\r\r\P + 0: \x{0d}\x{0d}\x{0d} + \r\r\r\P\P +Partial match: \x{0d}\x{0d}\x{0d} + +/.{2,3}?/8 + \r\P +Partial match: \x{0d} + \r\P\P +Partial match: \x{0d} + \r\r\P + 0: \x{0d}\x{0d} + \r\r\P\P +Partial match: \x{0d}\x{0d} + \r\r\r\P + 0: \x{0d}\x{0d} + \r\r\r\P\P + 0: \x{0d}\x{0d} + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZ +------------------------------------------------------------------ + Bra + [^\x{100}] + [^\x{1234}] + [^\x{ffff}] + [^\x{10000}] + [^\x{10ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZi +------------------------------------------------------------------ + Bra + /i [^\x{100}] + /i [^\x{1234}] + /i [^\x{ffff}] + /i [^\x{10000}] + /i [^\x{10ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZ +------------------------------------------------------------------ + Bra + [^\x{100}]* + [^\x{10000}]+ + [^\x{10ffff}]?? + [^\x{8000}]{4} + [^\x{8000}]* + [^\x{7fff}]{2} + [^\x{7fff}]{0,7}? + [^\x{fffff}]{5} + [^\x{fffff}]?+ + Ket + End +------------------------------------------------------------------ + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZi +------------------------------------------------------------------ + Bra + /i [^\x{100}]* + /i [^\x{10000}]+ + /i [^\x{10ffff}]?? + /i [^\x{8000}]{4} + /i [^\x{8000}]* + /i [^\x{7fff}]{2} + /i [^\x{7fff}]{0,7}? + Once + /i [^\x{fffff}]{5} + /i [^\x{fffff}]? + Ket + Ket + End +------------------------------------------------------------------ + +/(?<=\x{1234}\x{1234})\bxy/I8 +Capturing subpattern count = 0 +Options: utf +First char = 'x' +Need char = 'y' +Max lookbehind = 2 + +/(?8BZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ + +/[\u0100-\u0200]/8BZ +------------------------------------------------------------------ + Bra + [\x{100}-\x{200}] + Ket + End +------------------------------------------------------------------ + +/\ud800/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 5 + +/-- End of testinput5 --/ diff --git a/tools/pcre/testdata/testoutput6 b/tools/pcre/testdata/testoutput6 new file mode 100644 index 00000000..01827461 --- /dev/null +++ b/tools/pcre/testdata/testoutput6 @@ -0,0 +1,2137 @@ +/-- This set of tests is for Unicode property support. It is compatible with + Perl >= 5.15. --/ + +/^\pC\pL\pM\pN\pP\pS\pZ\s+/8W + >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} + 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{09} + +/^>\pZ+/8W + >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} + 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f} + +/^>[[:space:]]*/8W + >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} + 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{09}\x{0b} + +/^>[[:blank:]]*/8W + >\x{20}\x{a0}\x{1680}\x{180e}\x{2000}\x{202f}\x{9}\x{b}\x{2028} + 0: > \x{a0}\x{1680}\x{180e}\x{2000}\x{202f}\x{09} + +/^[[:alpha:]]*/8W + Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d} + 0: Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d} + +/^[[:alnum:]]*/8W + Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d}1\x{660}\x{bef}\x{16ee} + 0: Az\x{aa}\x{c0}\x{1c5}\x{2b0}\x{3b6}\x{1d7c9}\x{2fa1d}1\x{660}\x{bef}\x{16ee} + +/^[[:cntrl:]]*/8W + \x{0}\x{09}\x{1f}\x{7f}\x{9f} + 0: \x{00}\x{09}\x{1f}\x{7f} + +/^[[:graph:]]*/8W + A\x{a1}\x{a0} + 0: A + +/^[[:print:]]*/8W + A z\x{a0}\x{a1} + 0: A z + +/^[[:punct:]]*/8W + .+\x{a1}\x{a0} + 0: .+ + +/\p{Zs}*?\R/ + ** Failers +No match + a\xFCb +No match + +/\p{Zs}*\R/ + ** Failers +No match + a\xFCb +No match + +/â±¥/8i + â±¥ + 0: \x{2c65} + Ⱥx + 0: \x{23a} + Ⱥ + 0: \x{23a} + +/[â±¥]/8i + â±¥ + 0: \x{2c65} + Ⱥx + 0: \x{23a} + Ⱥ + 0: \x{23a} + +/Ⱥ/8i + Ⱥ + 0: \x{23a} + â±¥ + 0: \x{2c65} + +/-- These are tests for extended grapheme clusters --/ + +/^\X/8+ + G\x{34e}\x{34e}X + 0: G\x{34e}\x{34e} + 0+ X + \x{34e}\x{34e}X + 0: \x{34e}\x{34e} + 0+ X + \x04X + 0: \x{04} + 0+ X + \x{1100}X + 0: \x{1100} + 0+ X + \x{1100}\x{34e}X + 0: \x{1100}\x{34e} + 0+ X + \x{1b04}\x{1b04}X + 0: \x{1b04}\x{1b04} + 0+ X + *These match up to the roman letters + 0: * + 0+ These match up to the roman letters + \x{1111}\x{1111}L,L + 0: \x{1111}\x{1111} + 0+ L,L + \x{1111}\x{1111}\x{1169}L,L,V + 0: \x{1111}\x{1111}\x{1169} + 0+ L,L,V + \x{1111}\x{ae4c}L, LV + 0: \x{1111}\x{ae4c} + 0+ L, LV + \x{1111}\x{ad89}L, LVT + 0: \x{1111}\x{ad89} + 0+ L, LVT + \x{1111}\x{ae4c}\x{1169}L, LV, V + 0: \x{1111}\x{ae4c}\x{1169} + 0+ L, LV, V + \x{1111}\x{ae4c}\x{1169}\x{1169}L, LV, V, V + 0: \x{1111}\x{ae4c}\x{1169}\x{1169} + 0+ L, LV, V, V + \x{1111}\x{ae4c}\x{1169}\x{11fe}L, LV, V, T + 0: \x{1111}\x{ae4c}\x{1169}\x{11fe} + 0+ L, LV, V, T + \x{1111}\x{ad89}\x{11fe}L, LVT, T + 0: \x{1111}\x{ad89}\x{11fe} + 0+ L, LVT, T + \x{1111}\x{ad89}\x{11fe}\x{11fe}L, LVT, T, T + 0: \x{1111}\x{ad89}\x{11fe}\x{11fe} + 0+ L, LVT, T, T + \x{ad89}\x{11fe}\x{11fe}LVT, T, T + 0: \x{ad89}\x{11fe}\x{11fe} + 0+ LVT, T, T + *These match just the first codepoint (invalid sequence) + 0: * + 0+ These match just the first codepoint (invalid sequence) + \x{1111}\x{11fe}L, T + 0: \x{1111} + 0+ \x{11fe}L, T + \x{ae4c}\x{1111}LV, L + 0: \x{ae4c} + 0+ \x{1111}LV, L + \x{ae4c}\x{ae4c}LV, LV + 0: \x{ae4c} + 0+ \x{ae4c}LV, LV + \x{ae4c}\x{ad89}LV, LVT + 0: \x{ae4c} + 0+ \x{ad89}LV, LVT + \x{1169}\x{1111}V, L + 0: \x{1169} + 0+ \x{1111}V, L + \x{1169}\x{ae4c}V, LV + 0: \x{1169} + 0+ \x{ae4c}V, LV + \x{1169}\x{ad89}V, LVT + 0: \x{1169} + 0+ \x{ad89}V, LVT + \x{ad89}\x{1111}LVT, L + 0: \x{ad89} + 0+ \x{1111}LVT, L + \x{ad89}\x{1169}LVT, V + 0: \x{ad89} + 0+ \x{1169}LVT, V + \x{ad89}\x{ae4c}LVT, LV + 0: \x{ad89} + 0+ \x{ae4c}LVT, LV + \x{ad89}\x{ad89}LVT, LVT + 0: \x{ad89} + 0+ \x{ad89}LVT, LVT + \x{11fe}\x{1111}T, L + 0: \x{11fe} + 0+ \x{1111}T, L + \x{11fe}\x{1169}T, V + 0: \x{11fe} + 0+ \x{1169}T, V + \x{11fe}\x{ae4c}T, LV + 0: \x{11fe} + 0+ \x{ae4c}T, LV + \x{11fe}\x{ad89}T, LVT + 0: \x{11fe} + 0+ \x{ad89}T, LVT + *Test extend and spacing mark + 0: * + 0+ Test extend and spacing mark + \x{1111}\x{ae4c}\x{0711}L, LV, extend + 0: \x{1111}\x{ae4c}\x{711} + 0+ L, LV, extend + \x{1111}\x{ae4c}\x{1b04}L, LV, spacing mark + 0: \x{1111}\x{ae4c}\x{1b04} + 0+ L, LV, spacing mark + \x{1111}\x{ae4c}\x{1b04}\x{0711}\x{1b04}L, LV, spacing mark, extend, spacing mark + 0: \x{1111}\x{ae4c}\x{1b04}\x{711}\x{1b04} + 0+ L, LV, spacing mark, extend, spacing mark + *Test CR, LF, and control + 0: * + 0+ Test CR, LF, and control + \x0d\x{0711}CR, extend + 0: \x{0d} + 0+ \x{711}CR, extend + \x0d\x{1b04}CR, spacingmark + 0: \x{0d} + 0+ \x{1b04}CR, spacingmark + \x0a\x{0711}LF, extend + 0: \x{0a} + 0+ \x{711}LF, extend + \x0a\x{1b04}LF, spacingmark + 0: \x{0a} + 0+ \x{1b04}LF, spacingmark + \x0b\x{0711}Control, extend + 0: \x{0b} + 0+ \x{711}Control, extend + \x09\x{1b04}Control, spacingmark + 0: \x{09} + 0+ \x{1b04}Control, spacingmark + *There are no Prepend characters, so we can't test Prepend, CR + 0: * + 0+ There are no Prepend characters, so we can't test Prepend, CR + +/^(?>\X{2})X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + +/^\X{2,4}X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + +/^\X{2,4}?X/8+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X + 0+ + +/-- --/ + +/\x{1e9e}+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + +/[z\x{1e9e}]+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + +/\x{00df}+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + +/[z\x{00df}]+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + +/\x{1f88}+/8i + \x{1f88}\x{1f80} + 0: \x{1f88}\x{1f80} + +/[z\x{1f88}]+/8i + \x{1f88}\x{1f80} + 0: \x{1f88}\x{1f80} + +/-- Characters with more than one other case; test in classes --/ + +/[z\x{00b5}]+/8i + \x{00b5}\x{039c}\x{03bc} + 0: \x{b5}\x{39c}\x{3bc} + +/[z\x{039c}]+/8i + \x{00b5}\x{039c}\x{03bc} + 0: \x{b5}\x{39c}\x{3bc} + +/[z\x{03bc}]+/8i + \x{00b5}\x{039c}\x{03bc} + 0: \x{b5}\x{39c}\x{3bc} + +/[z\x{00c5}]+/8i + \x{00c5}\x{00e5}\x{212b} + 0: \x{c5}\x{e5}\x{212b} + +/[z\x{00e5}]+/8i + \x{00c5}\x{00e5}\x{212b} + 0: \x{c5}\x{e5}\x{212b} + +/[z\x{212b}]+/8i + \x{00c5}\x{00e5}\x{212b} + 0: \x{c5}\x{e5}\x{212b} + +/[z\x{01c4}]+/8i + \x{01c4}\x{01c5}\x{01c6} + 0: \x{1c4}\x{1c5}\x{1c6} + +/[z\x{01c5}]+/8i + \x{01c4}\x{01c5}\x{01c6} + 0: \x{1c4}\x{1c5}\x{1c6} + +/[z\x{01c6}]+/8i + \x{01c4}\x{01c5}\x{01c6} + 0: \x{1c4}\x{1c5}\x{1c6} + +/[z\x{01c7}]+/8i + \x{01c7}\x{01c8}\x{01c9} + 0: \x{1c7}\x{1c8}\x{1c9} + +/[z\x{01c8}]+/8i + \x{01c7}\x{01c8}\x{01c9} + 0: \x{1c7}\x{1c8}\x{1c9} + +/[z\x{01c9}]+/8i + \x{01c7}\x{01c8}\x{01c9} + 0: \x{1c7}\x{1c8}\x{1c9} + +/[z\x{01ca}]+/8i + \x{01ca}\x{01cb}\x{01cc} + 0: \x{1ca}\x{1cb}\x{1cc} + +/[z\x{01cb}]+/8i + \x{01ca}\x{01cb}\x{01cc} + 0: \x{1ca}\x{1cb}\x{1cc} + +/[z\x{01cc}]+/8i + \x{01ca}\x{01cb}\x{01cc} + 0: \x{1ca}\x{1cb}\x{1cc} + +/[z\x{01f1}]+/8i + \x{01f1}\x{01f2}\x{01f3} + 0: \x{1f1}\x{1f2}\x{1f3} + +/[z\x{01f2}]+/8i + \x{01f1}\x{01f2}\x{01f3} + 0: \x{1f1}\x{1f2}\x{1f3} + +/[z\x{01f3}]+/8i + \x{01f1}\x{01f2}\x{01f3} + 0: \x{1f1}\x{1f2}\x{1f3} + +/[z\x{0345}]+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + +/[z\x{0399}]+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + +/[z\x{03b9}]+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + +/[z\x{1fbe}]+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + +/[z\x{0392}]+/8i + \x{0392}\x{03b2}\x{03d0} + 0: \x{392}\x{3b2}\x{3d0} + +/[z\x{03b2}]+/8i + \x{0392}\x{03b2}\x{03d0} + 0: \x{392}\x{3b2}\x{3d0} + +/[z\x{03d0}]+/8i + \x{0392}\x{03b2}\x{03d0} + 0: \x{392}\x{3b2}\x{3d0} + +/[z\x{0395}]+/8i + \x{0395}\x{03b5}\x{03f5} + 0: \x{395}\x{3b5}\x{3f5} + +/[z\x{03b5}]+/8i + \x{0395}\x{03b5}\x{03f5} + 0: \x{395}\x{3b5}\x{3f5} + +/[z\x{03f5}]+/8i + \x{0395}\x{03b5}\x{03f5} + 0: \x{395}\x{3b5}\x{3f5} + +/[z\x{0398}]+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + +/[z\x{03b8}]+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + +/[z\x{03d1}]+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + +/[z\x{03f4}]+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + +/[z\x{039a}]+/8i + \x{039a}\x{03ba}\x{03f0} + 0: \x{39a}\x{3ba}\x{3f0} + +/[z\x{03ba}]+/8i + \x{039a}\x{03ba}\x{03f0} + 0: \x{39a}\x{3ba}\x{3f0} + +/[z\x{03f0}]+/8i + \x{039a}\x{03ba}\x{03f0} + 0: \x{39a}\x{3ba}\x{3f0} + +/[z\x{03a0}]+/8i + \x{03a0}\x{03c0}\x{03d6} + 0: \x{3a0}\x{3c0}\x{3d6} + +/[z\x{03c0}]+/8i + \x{03a0}\x{03c0}\x{03d6} + 0: \x{3a0}\x{3c0}\x{3d6} + +/[z\x{03d6}]+/8i + \x{03a0}\x{03c0}\x{03d6} + 0: \x{3a0}\x{3c0}\x{3d6} + +/[z\x{03a1}]+/8i + \x{03a1}\x{03c1}\x{03f1} + 0: \x{3a1}\x{3c1}\x{3f1} + +/[z\x{03c1}]+/8i + \x{03a1}\x{03c1}\x{03f1} + 0: \x{3a1}\x{3c1}\x{3f1} + +/[z\x{03f1}]+/8i + \x{03a1}\x{03c1}\x{03f1} + 0: \x{3a1}\x{3c1}\x{3f1} + +/[z\x{03a3}]+/8i + \x{03A3}\x{03C2}\x{03C3} + 0: \x{3a3}\x{3c2}\x{3c3} + +/[z\x{03c2}]+/8i + \x{03A3}\x{03C2}\x{03C3} + 0: \x{3a3}\x{3c2}\x{3c3} + +/[z\x{03c3}]+/8i + \x{03A3}\x{03C2}\x{03C3} + 0: \x{3a3}\x{3c2}\x{3c3} + +/[z\x{03a6}]+/8i + \x{03a6}\x{03c6}\x{03d5} + 0: \x{3a6}\x{3c6}\x{3d5} + +/[z\x{03c6}]+/8i + \x{03a6}\x{03c6}\x{03d5} + 0: \x{3a6}\x{3c6}\x{3d5} + +/[z\x{03d5}]+/8i + \x{03a6}\x{03c6}\x{03d5} + 0: \x{3a6}\x{3c6}\x{3d5} + +/[z\x{03c9}]+/8i + \x{03c9}\x{03a9}\x{2126} + 0: \x{3c9}\x{3a9}\x{2126} + +/[z\x{03a9}]+/8i + \x{03c9}\x{03a9}\x{2126} + 0: \x{3c9}\x{3a9}\x{2126} + +/[z\x{2126}]+/8i + \x{03c9}\x{03a9}\x{2126} + 0: \x{3c9}\x{3a9}\x{2126} + +/[z\x{1e60}]+/8i + \x{1e60}\x{1e61}\x{1e9b} + 0: \x{1e60}\x{1e61}\x{1e9b} + +/[z\x{1e61}]+/8i + \x{1e60}\x{1e61}\x{1e9b} + 0: \x{1e60}\x{1e61}\x{1e9b} + +/[z\x{1e9b}]+/8i + \x{1e60}\x{1e61}\x{1e9b} + 0: \x{1e60}\x{1e61}\x{1e9b} + +/-- Perl 5.12.4 gets these wrong, but 5.15.3 is OK --/ + +/[z\x{004b}]+/8i + \x{004b}\x{006b}\x{212a} + 0: Kk\x{212a} + +/[z\x{006b}]+/8i + \x{004b}\x{006b}\x{212a} + 0: Kk\x{212a} + +/[z\x{212a}]+/8i + \x{004b}\x{006b}\x{212a} + 0: Kk\x{212a} + +/[z\x{0053}]+/8i + \x{0053}\x{0073}\x{017f} + 0: Ss\x{17f} + +/[z\x{0073}]+/8i + \x{0053}\x{0073}\x{017f} + 0: Ss\x{17f} + +/[z\x{017f}]+/8i + \x{0053}\x{0073}\x{017f} + 0: Ss\x{17f} + +/-- --/ + +/(ΣΆΜΟΣ) \1/8i + ΣΆΜΟΣ ΣΆΜΟΣ + 0: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + 1: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + ΣΆΜΟΣ σάμος + 0: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + 1: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + σάμος σάμος + 0: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + 1: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + σάμος σάμοσ + 0: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c3} + 1: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + σάμος ΣΆΜΟΣ + 0: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + 1: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + +/(σάμος) \1/8i + ΣΆΜΟΣ ΣΆΜΟΣ + 0: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + 1: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + ΣΆΜΟΣ σάμος + 0: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + 1: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + σάμος σάμος + 0: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + 1: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + σάμος σάμοσ + 0: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c3} + 1: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + σάμος ΣΆΜΟΣ + 0: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + 1: \x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + +/(ΣΆΜΟΣ) \1*/8i + ΣΆΜΟΣ\x20 + 0: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + 1: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + ΣΆΜΟΣ ΣΆΜΟΣσάμοςσάμος + 0: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3}\x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2}\x{3c3}\x{3ac}\x{3bc}\x{3bf}\x{3c2} + 1: \x{3a3}\x{386}\x{39c}\x{39f}\x{3a3} + +/-- Perl matches these --/ + +/\x{00b5}+/8i + \x{00b5}\x{039c}\x{03bc} + 0: \x{b5}\x{39c}\x{3bc} + +/\x{039c}+/8i + \x{00b5}\x{039c}\x{03bc} + 0: \x{b5}\x{39c}\x{3bc} + +/\x{03bc}+/8i + \x{00b5}\x{039c}\x{03bc} + 0: \x{b5}\x{39c}\x{3bc} + + +/\x{00c5}+/8i + \x{00c5}\x{00e5}\x{212b} + 0: \x{c5}\x{e5}\x{212b} + +/\x{00e5}+/8i + \x{00c5}\x{00e5}\x{212b} + 0: \x{c5}\x{e5}\x{212b} + +/\x{212b}+/8i + \x{00c5}\x{00e5}\x{212b} + 0: \x{c5}\x{e5}\x{212b} + + +/\x{01c4}+/8i + \x{01c4}\x{01c5}\x{01c6} + 0: \x{1c4}\x{1c5}\x{1c6} + +/\x{01c5}+/8i + \x{01c4}\x{01c5}\x{01c6} + 0: \x{1c4}\x{1c5}\x{1c6} + +/\x{01c6}+/8i + \x{01c4}\x{01c5}\x{01c6} + 0: \x{1c4}\x{1c5}\x{1c6} + + +/\x{01c7}+/8i + \x{01c7}\x{01c8}\x{01c9} + 0: \x{1c7}\x{1c8}\x{1c9} + +/\x{01c8}+/8i + \x{01c7}\x{01c8}\x{01c9} + 0: \x{1c7}\x{1c8}\x{1c9} + +/\x{01c9}+/8i + \x{01c7}\x{01c8}\x{01c9} + 0: \x{1c7}\x{1c8}\x{1c9} + + +/\x{01ca}+/8i + \x{01ca}\x{01cb}\x{01cc} + 0: \x{1ca}\x{1cb}\x{1cc} + +/\x{01cb}+/8i + \x{01ca}\x{01cb}\x{01cc} + 0: \x{1ca}\x{1cb}\x{1cc} + +/\x{01cc}+/8i + \x{01ca}\x{01cb}\x{01cc} + 0: \x{1ca}\x{1cb}\x{1cc} + + +/\x{01f1}+/8i + \x{01f1}\x{01f2}\x{01f3} + 0: \x{1f1}\x{1f2}\x{1f3} + +/\x{01f2}+/8i + \x{01f1}\x{01f2}\x{01f3} + 0: \x{1f1}\x{1f2}\x{1f3} + +/\x{01f3}+/8i + \x{01f1}\x{01f2}\x{01f3} + 0: \x{1f1}\x{1f2}\x{1f3} + + +/\x{0345}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + +/\x{0399}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + +/\x{03b9}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + +/\x{1fbe}+/8i + \x{0345}\x{0399}\x{03b9}\x{1fbe} + 0: \x{345}\x{399}\x{3b9}\x{1fbe} + + +/\x{0392}+/8i + \x{0392}\x{03b2}\x{03d0} + 0: \x{392}\x{3b2}\x{3d0} + +/\x{03b2}+/8i + \x{0392}\x{03b2}\x{03d0} + 0: \x{392}\x{3b2}\x{3d0} + +/\x{03d0}+/8i + \x{0392}\x{03b2}\x{03d0} + 0: \x{392}\x{3b2}\x{3d0} + + +/\x{0395}+/8i + \x{0395}\x{03b5}\x{03f5} + 0: \x{395}\x{3b5}\x{3f5} + +/\x{03b5}+/8i + \x{0395}\x{03b5}\x{03f5} + 0: \x{395}\x{3b5}\x{3f5} + +/\x{03f5}+/8i + \x{0395}\x{03b5}\x{03f5} + 0: \x{395}\x{3b5}\x{3f5} + + +/\x{0398}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + +/\x{03b8}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + +/\x{03d1}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + +/\x{03f4}+/8i + \x{0398}\x{03b8}\x{03d1}\x{03f4} + 0: \x{398}\x{3b8}\x{3d1}\x{3f4} + + +/\x{039a}+/8i + \x{039a}\x{03ba}\x{03f0} + 0: \x{39a}\x{3ba}\x{3f0} + +/\x{03ba}+/8i + \x{039a}\x{03ba}\x{03f0} + 0: \x{39a}\x{3ba}\x{3f0} + +/\x{03f0}+/8i + \x{039a}\x{03ba}\x{03f0} + 0: \x{39a}\x{3ba}\x{3f0} + + +/\x{03a0}+/8i + \x{03a0}\x{03c0}\x{03d6} + 0: \x{3a0}\x{3c0}\x{3d6} + +/\x{03c0}+/8i + \x{03a0}\x{03c0}\x{03d6} + 0: \x{3a0}\x{3c0}\x{3d6} + +/\x{03d6}+/8i + \x{03a0}\x{03c0}\x{03d6} + 0: \x{3a0}\x{3c0}\x{3d6} + + +/\x{03a1}+/8i + \x{03a1}\x{03c1}\x{03f1} + 0: \x{3a1}\x{3c1}\x{3f1} + +/\x{03c1}+/8i + \x{03a1}\x{03c1}\x{03f1} + 0: \x{3a1}\x{3c1}\x{3f1} + +/\x{03f1}+/8i + \x{03a1}\x{03c1}\x{03f1} + 0: \x{3a1}\x{3c1}\x{3f1} + + +/\x{03a3}+/8i + \x{03A3}\x{03C2}\x{03C3} + 0: \x{3a3}\x{3c2}\x{3c3} + +/\x{03c2}+/8i + \x{03A3}\x{03C2}\x{03C3} + 0: \x{3a3}\x{3c2}\x{3c3} + +/\x{03c3}+/8i + \x{03A3}\x{03C2}\x{03C3} + 0: \x{3a3}\x{3c2}\x{3c3} + + +/\x{03a6}+/8i + \x{03a6}\x{03c6}\x{03d5} + 0: \x{3a6}\x{3c6}\x{3d5} + +/\x{03c6}+/8i + \x{03a6}\x{03c6}\x{03d5} + 0: \x{3a6}\x{3c6}\x{3d5} + +/\x{03d5}+/8i + \x{03a6}\x{03c6}\x{03d5} + 0: \x{3a6}\x{3c6}\x{3d5} + + +/\x{03c9}+/8i + \x{03c9}\x{03a9}\x{2126} + 0: \x{3c9}\x{3a9}\x{2126} + +/\x{03a9}+/8i + \x{03c9}\x{03a9}\x{2126} + 0: \x{3c9}\x{3a9}\x{2126} + +/\x{2126}+/8i + \x{03c9}\x{03a9}\x{2126} + 0: \x{3c9}\x{3a9}\x{2126} + + +/\x{1e60}+/8i + \x{1e60}\x{1e61}\x{1e9b} + 0: \x{1e60}\x{1e61}\x{1e9b} + +/\x{1e61}+/8i + \x{1e60}\x{1e61}\x{1e9b} + 0: \x{1e60}\x{1e61}\x{1e9b} + +/\x{1e9b}+/8i + \x{1e60}\x{1e61}\x{1e9b} + 0: \x{1e60}\x{1e61}\x{1e9b} + + +/\x{1e9e}+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + +/\x{00df}+/8i + \x{1e9e}\x{00df} + 0: \x{1e9e}\x{df} + + +/\x{1f88}+/8i + \x{1f88}\x{1f80} + 0: \x{1f88}\x{1f80} + +/\x{1f80}+/8i + \x{1f88}\x{1f80} + 0: \x{1f88}\x{1f80} + + +/-- Perl 5.12.4 gets these wrong, but 5.15.3 is OK --/ + +/\x{004b}+/8i + \x{004b}\x{006b}\x{212a} + 0: Kk\x{212a} + +/\x{006b}+/8i + \x{004b}\x{006b}\x{212a} + 0: Kk\x{212a} + +/\x{212a}+/8i + \x{004b}\x{006b}\x{212a} + 0: Kk\x{212a} + + +/\x{0053}+/8i + \x{0053}\x{0073}\x{017f} + 0: Ss\x{17f} + +/\x{0073}+/8i + \x{0053}\x{0073}\x{017f} + 0: Ss\x{17f} + +/\x{017f}+/8i + \x{0053}\x{0073}\x{017f} + 0: Ss\x{17f} + +/-- End of testinput6 --/ diff --git a/tools/pcre/testdata/testoutput7 b/tools/pcre/testdata/testoutput7 new file mode 100644 index 00000000..4f8b7b9b --- /dev/null +++ b/tools/pcre/testdata/testoutput7 @@ -0,0 +1,1473 @@ +/-- These tests for Unicode property support test PCRE's API and show some of + the compiled code. They are not Perl-compatible. --/ + +/[\p{L}]/DZ +------------------------------------------------------------------ + Bra + [\p{L}] + Ket + End +------------------------------------------------------------------ +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 + +/[\P{L}]/DZ +------------------------------------------------------------------ + Bra + [\P{L}] + Ket + End +------------------------------------------------------------------ +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 + +/[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 + +/[\p{Nd}]/8DZ +------------------------------------------------------------------ + Bra + [\p{Nd}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + 1234 + 0: 1 + +/[\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 + abcd +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{3bc}\x{1e9e}\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{3bc}\x{1e9e}\x{178}z-\x{101}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char + +/(?:[\PPa*]*){8,}/ + +/[\P{Any}]/BZ +------------------------------------------------------------------ + Bra + [\P{Any}] + Ket + End +------------------------------------------------------------------ + +/[\P{Any}\E]/BZ +------------------------------------------------------------------ + Bra + [\P{Any}] + Ket + End +------------------------------------------------------------------ + +/(\P{Yi}+\277)/ + +/(\P{Yi}+\277)?/ + +/(?<=\P{Yi}{3}A)X/ + +/\p{Yi}+(\P{Yi}+)(?1)/ + +/(\P{Yi}{2}\277)?/ + +/[\P{Yi}A]/ + +/[\P{Yi}\P{Yi}\P{Yi}A]/ + +/[^\P{Yi}A]/ + +/[^\P{Yi}\P{Yi}\P{Yi}A]/ + +/(\P{Yi}*\277)*/ + +/(\P{Yi}*?\277)*/ + +/(\p{Yi}*+\277)*/ + +/(\P{Yi}?\277)*/ + +/(\P{Yi}??\277)*/ + +/(\p{Yi}?+\277)*/ + +/(\P{Yi}{0,3}\277)*/ + +/(\P{Yi}{0,3}?\277)*/ + +/(\p{Yi}{0,3}+\277)*/ + +/\p{Zl}{2,3}+/8BZ +------------------------------------------------------------------ + Bra + prop Zl {2} + prop Zl ?+ + Ket + End +------------------------------------------------------------------ + 

 + 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} + +/-- 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 +------------------------------------------------------------------ + +/[[:cntrl:]]/WBZ +------------------------------------------------------------------ + Bra + [\x00-\x1f\x7f] + Ket + End +------------------------------------------------------------------ + +/[[:digit:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Nd}] + Ket + End +------------------------------------------------------------------ + +/[[:graph:]]/WBZ +------------------------------------------------------------------ + Bra + [!-~] + Ket + End +------------------------------------------------------------------ + +/[[:print:]]/WBZ +------------------------------------------------------------------ + Bra + [ -~] + Ket + End +------------------------------------------------------------------ + +/[[:punct:]]/WBZ +------------------------------------------------------------------ + Bra + [!-/:-@[-`{-~] + Ket + End +------------------------------------------------------------------ + +/[[:space:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Xps}] + Ket + End +------------------------------------------------------------------ + +/[[:word:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Xwd}] + Ket + End +------------------------------------------------------------------ + +/[[:xdigit:]]/WBZ +------------------------------------------------------------------ + Bra + [0-9A-Fa-f] + Ket + End +------------------------------------------------------------------ + +/-- Unicode properties for \b abd \B --/ + +/\b...\B/8W + abc_ + 0: abc + \x{37e}abc\x{376} + 0: abc + \x{37e}\x{376}\x{371}\x{393}\x{394} + 0: \x{376}\x{371}\x{393} + !\x{c0}++\x{c1}\x{c2} + 0: ++\x{c1} + !\x{c0}+++++ + 0: \x{c0}++ + +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ + +/\b...\B/8 + abc_ + 0: abc + ** Failers + 0: Fai + \x{37e}abc\x{376} +No match + \x{37e}\x{376}\x{371}\x{393}\x{394} +No match + !\x{c0}++\x{c1}\x{c2} +No match + !\x{c0}+++++ +No match + +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ + +/\b...\B/W + abc_ + 0: abc + !\x{c0}++\x{c1}\x{c2} + 0: ++\xc1 + !\x{c0}+++++ + 0: \xc0++ + +/-- Some of these are silly, but they check various combinations --/ + +/[[:^alpha:][:^cntrl:]]+/8WBZ +------------------------------------------------------------------ + Bra + [ -~\x80-\xff\P{L}]+ + Ket + End +------------------------------------------------------------------ + 123 + 0: 123 + abc + 0: abc + +/[[:^cntrl:][:^alpha:]]+/8WBZ +------------------------------------------------------------------ + Bra + [ -~\x80-\xff\P{L}]+ + Ket + End +------------------------------------------------------------------ + 123 + 0: 123 + abc + 0: abc + +/[[:alpha:]]+/8WBZ +------------------------------------------------------------------ + Bra + [\p{L}]+ + Ket + End +------------------------------------------------------------------ + abc + 0: abc + +/[[:^alpha:]\S]+/8WBZ +------------------------------------------------------------------ + Bra + [\P{L}\P{Xsp}]+ + Ket + End +------------------------------------------------------------------ + 123 + 0: 123 + abc + 0: abc + +/[^\d]+/8WBZ +------------------------------------------------------------------ + Bra + [^\p{Nd}]+ + Ket + End +------------------------------------------------------------------ + abc123 + 0: abc + abc\x{123} + 0: abc\x{123} + \x{660}abc + 0: abc + +/\p{Lu}+9\p{Lu}+B\p{Lu}+b/BZ +------------------------------------------------------------------ + Bra + prop Lu ++ + 9 + prop Lu + + B + prop Lu ++ + b + Ket + End +------------------------------------------------------------------ + +/\p{^Lu}+9\p{^Lu}+B\p{^Lu}+b/BZ +------------------------------------------------------------------ + Bra + notprop Lu + + 9 + notprop Lu ++ + B + notprop Lu + + b + Ket + End +------------------------------------------------------------------ + +/\P{Lu}+9\P{Lu}+B\P{Lu}+b/BZ +------------------------------------------------------------------ + Bra + notprop Lu + + 9 + notprop Lu ++ + B + notprop Lu + + b + Ket + End +------------------------------------------------------------------ + +/\p{Han}+X\p{Greek}+\x{370}/BZ8 +------------------------------------------------------------------ + Bra + prop Han ++ + X + prop Greek + + \x{370} + Ket + End +------------------------------------------------------------------ + +/\p{Xan}+!\p{Xan}+A/BZ +------------------------------------------------------------------ + Bra + prop Xan ++ + ! + prop Xan + + A + Ket + End +------------------------------------------------------------------ + +/\p{Xsp}+!\p{Xsp}\t/BZ +------------------------------------------------------------------ + Bra + prop Xsp ++ + ! + prop Xsp + \x09 + Ket + End +------------------------------------------------------------------ + +/\p{Xps}+!\p{Xps}\t/BZ +------------------------------------------------------------------ + Bra + prop Xps ++ + ! + prop Xps + \x09 + Ket + End +------------------------------------------------------------------ + +/\p{Xwd}+!\p{Xwd}_/BZ +------------------------------------------------------------------ + Bra + prop Xwd ++ + ! + prop Xwd + _ + Ket + End +------------------------------------------------------------------ + +/A+\p{N}A+\dB+\p{N}*B+\d*/WBZ +------------------------------------------------------------------ + Bra + A++ + prop N + A++ + prop Nd + B+ + prop N *+ + B+ + prop Nd * + Ket + End +------------------------------------------------------------------ + +/-- These behaved oddly in Perl, so they are kept in this test --/ + +/(\x{23a}\x{23a}\x{23a})?\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} +No match + +/(ȺȺȺ)?\1/8i + ȺȺȺⱥⱥ +No match + +/(\x{23a}\x{23a}\x{23a})?\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(ȺȺȺ)?\1/8i + ȺȺȺⱥⱥⱥ + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(\x{23a}\x{23a}\x{23a})\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} +No match + +/(ȺȺȺ)\1/8i + ȺȺȺⱥⱥ +No match + +/(\x{23a}\x{23a}\x{23a})\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(ȺȺȺ)\1/8i + ȺȺȺⱥⱥⱥ + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(\x{2c65}\x{2c65})\1/8i + \x{2c65}\x{2c65}\x{23a}\x{23a} + 0: \x{2c65}\x{2c65}\x{23a}\x{23a} + 1: \x{2c65}\x{2c65} + +/(ⱥⱥ)\1/8i + ⱥⱥȺȺ + 0: \x{2c65}\x{2c65}\x{23a}\x{23a} + 1: \x{2c65}\x{2c65} + +/(\x{23a}\x{23a}\x{23a})\1Y/8i + X\x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}YZ + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}Y + 1: \x{23a}\x{23a}\x{23a} + +/(\x{2c65}\x{2c65})\1Y/8i + X\x{2c65}\x{2c65}\x{23a}\x{23a}YZ + 0: \x{2c65}\x{2c65}\x{23a}\x{23a}Y + 1: \x{2c65}\x{2c65} + +/-- --/ + +/-- These scripts weren't yet in Perl when I added Unicode 6.0.0 to PCRE --/ + +/^[\p{Batak}]/8 + \x{1bc0} + 0: \x{1bc0} + \x{1bff} + 0: \x{1bff} + ** Failers +No match + \x{1bf4} +No match + +/^[\p{Brahmi}]/8 + \x{11000} + 0: \x{11000} + \x{1106f} + 0: \x{1106f} + ** Failers +No match + \x{1104e} +No match + +/^[\p{Mandaic}]/8 + \x{840} + 0: \x{840} + \x{85e} + 0: \x{85e} + ** Failers +No match + \x{85c} +No match + \x{85d} +No match + +/-- --/ + +/(\X*)(.)/s8 + A\x{300} + 0: A + 1: + 2: A + +/^S(\X*)e(\X*)$/8 + SteÌreÌo + 0: Ste\x{301}re\x{301}o + 1: te\x{301}r + 2: \x{301}o + +/^\X/8 + ÌreÌo + 0: \x{301} + +/^a\X41z/ + aX41z + 0: aX41z + *** Failers +No match + aAz +No match + +/(?<=ab\Cde)X/8 +Failed: \C not allowed in lookbehind assertion at offset 10 + +/\X/ + a\P + 0: a + a\P\P +Partial match: a + +/\Xa/ + aa\P + 0: aa + aa\P\P + 0: aa + +/\X{2}/ + aa\P + 0: aa + aa\P\P +Partial match: aa + +/\X+a/ + a\P +Partial match: a + aa\P + 0: aa + aa\P\P +Partial match: aa + +/\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. --/ + +/\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} + +/^\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 + +/A\x{3a3}B/8iDZ +------------------------------------------------------------------ + Bra + /i A + clist 03a3 03c2 03c3 + /i B + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +First char = 'A' (caseless) +Need char = 'B' (caseless) + +/\x{3a3}B/8iDZ +------------------------------------------------------------------ + Bra + clist 03a3 03c2 03c3 + /i B + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +No first char +Need char = 'B' (caseless) + +/[\x{3a3}]/8iBZ +------------------------------------------------------------------ + Bra + clist 03a3 03c2 03c3 + Ket + End +------------------------------------------------------------------ + +/[^\x{3a3}]/8iBZ +------------------------------------------------------------------ + Bra + not clist 03a3 03c2 03c3 + Ket + End +------------------------------------------------------------------ + +/[\x{3a3}]+/8iBZ +------------------------------------------------------------------ + Bra + clist 03a3 03c2 03c3 + + Ket + End +------------------------------------------------------------------ + +/[^\x{3a3}]+/8iBZ +------------------------------------------------------------------ + Bra + not clist 03a3 03c2 03c3 + + Ket + End +------------------------------------------------------------------ + +/a*\x{3a3}/8iBZ +------------------------------------------------------------------ + Bra + /i a*+ + clist 03a3 03c2 03c3 + Ket + End +------------------------------------------------------------------ + +/\x{3a3}+a/8iBZ +------------------------------------------------------------------ + Bra + clist 03a3 03c2 03c3 ++ + /i a + Ket + End +------------------------------------------------------------------ + +/\x{3a3}*\x{3c2}/8iBZ +------------------------------------------------------------------ + Bra + clist 03a3 03c2 03c3 * + clist 03a3 03c2 03c3 + Ket + End +------------------------------------------------------------------ + +/\x{3a3}{3}/8i+ + \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} + 0: \x{3a3}\x{3c3}\x{3c2} + 0+ \x{3a3}\x{3c3}\x{3c2} + +/\x{3a3}{2,4}/8i+ + \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} + 0: \x{3a3}\x{3c3}\x{3c2}\x{3a3} + 0+ \x{3c3}\x{3c2} + +/\x{3a3}{2,4}?/8i+ + \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} + 0: \x{3a3}\x{3c3} + 0+ \x{3c2}\x{3a3}\x{3c3}\x{3c2} + +/\x{3a3}+./8i+ + \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} + 0: \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} + 0+ + +/\x{3a3}++./8i+ + ** Failers +No match + \x{3a3}\x{3c3}\x{3c2}\x{3a3}\x{3c3}\x{3c2} +No match + +/\x{3a3}*\x{3c2}/8iBZ +------------------------------------------------------------------ + Bra + clist 03a3 03c2 03c3 * + clist 03a3 03c2 03c3 + Ket + End +------------------------------------------------------------------ + +/[^\x{3a3}]*\x{3c2}/8iBZ +------------------------------------------------------------------ + Bra + not clist 03a3 03c2 03c3 *+ + clist 03a3 03c2 03c3 + Ket + End +------------------------------------------------------------------ + +/[^a]*\x{3c2}/8iBZ +------------------------------------------------------------------ + Bra + /i [^a]* + clist 03a3 03c2 03c3 + Ket + End +------------------------------------------------------------------ + +/ist/8iBZ +------------------------------------------------------------------ + Bra + /i i + clist 0053 0073 017f + /i t + Ket + End +------------------------------------------------------------------ + ikt +No match + +/is+t/8i + iSs\x{17f}t + 0: iSs\x{17f}t + ikt +No match + +/is+?t/8i + ikt +No match + +/is?t/8i + ikt +No match + +/is{2}t/8i + iskt +No match + +/-- End of testinput7 --/ diff --git a/tools/pcre/testdata/testoutput8 b/tools/pcre/testdata/testoutput8 new file mode 100644 index 00000000..73e0eae8 --- /dev/null +++ b/tools/pcre/testdata/testoutput8 @@ -0,0 +1,8019 @@ +/-- 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: ab=a + +/^([^()]|\((?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 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 + +/b\z/ + +/b\Z/ + a\nb + 0: b + +/b\z/ + a\nb + 0: b + *** Failers +No match + +/(?>.*)(?<=(abcd|wxyz))/ + alphabetabcd + 0: alphabetabcd + endingwxyz + 0: endingwxyz + *** Failers +No match + a rather long string that doesn't end with one of them +No match + +/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark +No match + +/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 + +/(?<=\d{3}(?!999))foo/ + 999foo + 0: foo + 123999foo + 0: foo + *** Failers +No match + 123abcfoo +No match + +/(?<=(?!...999)\d{3})foo/ + 999foo + 0: foo + 123999foo + 0: foo + *** Failers +No match + 123abcfoo +No match + +/(?<=\d{3}(?!999)...)foo/ + 123abcfoo + 0: foo + 123456foo + 0: foo + *** Failers +No match + 123999foo +No match + +/(?<=\d{3}...)(?Z)+|A)*/ + ZABCDEFG + 0: ZA + 1: Z + 2: + +/((?>)+|A)*/ + ZABCDEFG + 0: + +/a*/g + abbab + 0: a + 1: + 0: + 0: + 0: a + 1: + 0: + 0: + +/^[a-\d]/ + abcde + 0: a + -things + 0: - + 0digit + 0: 0 + *** Failers +No match + bcdef +No match + +/^[\d-a]/ + abcde + 0: a + -things + 0: - + 0digit + 0: 0 + *** Failers +No match + bcdef +No match + +/[[:space:]]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d\x0b + 1: \x09\x0a\x0c\x0d + 2: \x09\x0a\x0c + 3: \x09\x0a + 4: \x09 + 5: + +/[[:blank:]]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09 + 1: + +/[\s]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d + 1: \x09\x0a\x0c + 2: \x09\x0a + 3: \x09 + 4: + +/\s+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d + 1: \x09\x0a\x0c + 2: \x09\x0a + 3: \x09 + 4: + +/a b/x + ab +No match + +/(?!\A)x/m + a\nxb\n + 0: x + +/(?!^)x/m + a\nxb\n +No match + +/abc\Qabc\Eabc/ + abcabcabc + 0: abcabcabc + +/abc\Q(*+|\Eabc/ + abc(*+|abc + 0: abc(*+|abc + +/ abc\Q abc\Eabc/x + abc abcabc + 0: abc abcabc + *** Failers +No match + abcabcabc +No match + +/abc#comment + \Q#not comment + literal\E/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal\E #more comment + /x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal\E #more comment/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/\Qabc\$xyz\E/ + abc\\\$xyz + 0: abc\$xyz + +/\Qabc\E\$\Qxyz\E/ + abc\$xyz + 0: abc$xyz + +/\Gabc/ + abc + 0: abc + *** Failers +No match + xyzabc +No match + +/\Gabc./g + abc1abc2xyzabc3 + 0: abc1 + 0: abc2 + +/abc./g + abc1abc2xyzabc3 + 0: abc1 + 0: abc2 + 0: abc3 + +/a(?x: b c )d/ + XabcdY + 0: abcd + *** Failers +No match + Xa b c d Y +No match + +/((?x)x y z | a b c)/ + XabcY + 0: abc + AxyzB + 0: xyz + +/(?i)AB(?-i)C/ + XabCY + 0: abC + *** Failers +No match + XabcY +No match + +/((?i)AB(?-i)C|D)E/ + abCE + 0: abCE + DE + 0: DE + *** Failers +No match + abcE +No match + abCe +No match + dE +No match + De +No match + +/[z\Qa-d]\E]/ + z + 0: z + a + 0: a + - + 0: - + d + 0: d + ] + 0: ] + *** Failers + 0: a + b +No match + +/[\z\C]/ + z + 0: z + C + 0: C + +/\M/ + M + 0: M + +/(a+)*b/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ + REGular + 0: REGular + regulaer + 0: regulaer + Regex + 0: Regex + regulär + 0: regul\xe4r + +/Åæåä[à-ÿÀ-ß]+/ + Åæåäà + 0: \xc5\xe6\xe5\xe4\xe0 + Åæåäÿ + 0: \xc5\xe6\xe5\xe4\xff + ÅæåäÀ + 0: \xc5\xe6\xe5\xe4\xc0 + Åæåäß + 0: \xc5\xe6\xe5\xe4\xdf + +/(?<=Z)X./ + \x84XAZXB + 0: XB + +/^(?(2)a|(1)(2))+$/ + 123a +Error -17 (backreference condition or recursion test not supported for DFA matching) + +/(?<=a|bbbb)c/ + ac + 0: c + bbbbc + 0: c + +/abc/SS>testsavedregex +Compiled pattern written to testsavedregex +testsavedregex +Compiled pattern written to testsavedregex +testsavedregex +Compiled pattern written to testsavedregex +Study data written to testsavedregex +testsavedregex +Compiled pattern written to testsavedregex +Study data written to testsavedregex + + 0: abc + xyz\r\nabc\ + 0: abc + xyz\rabc\ + 0: abc + xyz\r\nabc\ + 0: abc + ** Failers +No match + xyz\nabc\ +No match + xyz\r\nabc\ +No match + xyz\nabc\ +No match + xyz\rabc\ +No match + xyz\rabc\ +No match + +/abc$/m + xyzabc + 0: abc + xyzabc\n + 0: abc + xyzabc\npqr + 0: abc + xyzabc\r\ + 0: abc + xyzabc\rpqr\ + 0: abc + xyzabc\r\n\ + 0: abc + xyzabc\r\npqr\ + 0: abc + ** Failers +No match + xyzabc\r +No match + xyzabc\rpqr +No match + xyzabc\r\n +No match + xyzabc\r\npqr +No match + +/^abc/m + xyz\rabcdef + 0: abc + xyz\nabcdef\ + 0: abc + ** Failers +No match + xyz\nabcdef +No match + +/^abc/m + xyz\nabcdef + 0: abc + xyz\rabcdef\ + 0: abc + ** Failers +No match + xyz\rabcdef +No match + +/^abc/m + xyz\r\nabcdef + 0: abc + xyz\rabcdef\ + 0: abc + ** Failers +No match + xyz\rabcdef +No match + +/.*/ + abc\ndef + 0: abc + 1: ab + 2: a + 3: + abc\rdef + 0: abc\x0ddef + 1: abc\x0dde + 2: abc\x0dd + 3: abc\x0d + 4: abc + 5: ab + 6: a + 7: + abc\r\ndef + 0: abc\x0d + 1: abc + 2: ab + 3: a + 4: + \abc\ndef + 0: abc\x0adef + 1: abc\x0ade + 2: abc\x0ad + 3: abc\x0a + 4: abc + 5: ab + 6: a + 7: + \abc\rdef + 0: abc + 1: ab + 2: a + 3: + \abc\r\ndef + 0: abc + 1: ab + 2: a + 3: + \abc\ndef + 0: abc\x0adef + 1: abc\x0ade + 2: abc\x0ad + 3: abc\x0a + 4: abc + 5: ab + 6: a + 7: + \abc\rdef + 0: abc\x0ddef + 1: abc\x0dde + 2: abc\x0dd + 3: abc\x0d + 4: abc + 5: ab + 6: a + 7: + \abc\r\ndef + 0: abc + 1: ab + 2: a + 3: + +/\w+(.)(.)?def/s + abc\ndef + 0: abc\x0adef + abc\rdef + 0: abc\x0ddef + abc\r\ndef + 0: abc\x0d\x0adef + +/^\w+=.*(\\\n.*)*/ + abc=xyz\\\npqr + 0: abc=xyz\\x0apqr + 1: abc=xyz\\x0apq + 2: abc=xyz\\x0ap + 3: abc=xyz\\x0a + 4: abc=xyz\ + 5: abc=xyz + 6: abc=xy + 7: abc=x + 8: abc= + +/^(a()*)*/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + 4: + +/^(?:a(?:(?:))*)*/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + 4: + +/^(a()+)+/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/^(?:a(?:(?:))+)+/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/(a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?>a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?:a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/^a.b/ + a\rb + 0: a\x0db + a\nb\ + 0: a\x0ab + ** Failers +No match + a\nb +No match + a\nb\ +No match + a\rb\ +No match + a\rb\ +No match + +/^abc./mgx + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK + 0: abc1 + 0: abc2 + 0: abc3 + 0: abc4 + 0: abc5 + 0: abc6 + 0: abc7 + +/abc.$/mgx + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 + 0: abc1 + 0: abc2 + 0: abc3 + 0: abc4 + 0: abc5 + 0: abc6 + 0: abc9 + +/^a\Rb/ + a\nb + 0: a\x0ab + a\rb + 0: a\x0db + a\r\nb + 0: a\x0d\x0ab + a\x0bb + 0: a\x0bb + a\x0cb + 0: a\x0cb + a\x85b + 0: a\x85b + ** Failers +No match + a\n\rb +No match + +/^a\R*b/ + ab + 0: ab + a\nb + 0: a\x0ab + a\rb + 0: a\x0db + a\r\nb + 0: a\x0d\x0ab + a\x0bb + 0: a\x0bb + a\x0cb + 0: a\x0cb + a\x85b + 0: a\x85b + a\n\rb + 0: a\x0a\x0db + a\n\r\x85\x0cb + 0: a\x0a\x0d\x85\x0cb + +/^a\R+b/ + a\nb + 0: a\x0ab + a\rb + 0: a\x0db + a\r\nb + 0: a\x0d\x0ab + a\x0bb + 0: a\x0bb + a\x0cb + 0: a\x0cb + a\x85b + 0: a\x85b + a\n\rb + 0: a\x0a\x0db + a\n\r\x85\x0cb + 0: a\x0a\x0d\x85\x0cb + ** Failers +No match + ab +No match + +/^a\R{1,3}b/ + a\nb + 0: a\x0ab + a\n\rb + 0: a\x0a\x0db + a\n\r\x85b + 0: a\x0a\x0d\x85b + a\r\n\r\nb + 0: a\x0d\x0a\x0d\x0ab + a\r\n\r\n\r\nb + 0: a\x0d\x0a\x0d\x0a\x0d\x0ab + a\n\r\n\rb + 0: a\x0a\x0d\x0a\x0db + a\n\n\r\nb + 0: a\x0a\x0a\x0d\x0ab + ** Failers +No match + a\n\n\n\rb +No match + a\r +No match + +/^a[\R]b/ + aRb + 0: aRb + ** Failers +No match + a\nb +No match + +/.+foo/ + afoo + 0: afoo + ** Failers +No match + \r\nfoo +No match + \nfoo +No match + +/.+foo/ + afoo + 0: afoo + \nfoo + 0: \x0afoo + ** Failers +No match + \r\nfoo +No match + +/.+foo/ + afoo + 0: afoo + ** Failers +No match + \nfoo +No match + \r\nfoo +No match + +/.+foo/s + afoo + 0: afoo + \r\nfoo + 0: \x0d\x0afoo + \nfoo + 0: \x0afoo + +/^$/mg + abc\r\rxyz + 0: + abc\n\rxyz + 0: + ** Failers +No match + abc\r\nxyz +No match + +/^X/m + XABC + 0: X + ** Failers +No match + XABC\B +No match + +/(?m)^$/g+ + abc\r\n\r\n + 0: + 0+ \x0d\x0a + +/(?m)^$|^\r\n/g+ + abc\r\n\r\n + 0: \x0d\x0a + 0+ + 1: + +/(?m)$/g+ + abc\r\n\r\n + 0: + 0+ \x0d\x0a\x0d\x0a + 0: + 0+ \x0d\x0a + 0: + 0+ + +/(?|(abc)|(xyz))/ + >abc< + 0: abc + >xyz< + 0: xyz + +/(x)(?|(abc)|(xyz))(x)/ + xabcx + 0: xabcx + xxyzx + 0: xxyzx + +/(x)(?|(abc)(pqr)|(xyz))(x)/ + xabcpqrx + 0: xabcpqrx + xxyzx + 0: xxyzx + +/(?|(abc)|(xyz))(?1)/ + abcabc + 0: abcabc + xyzabc + 0: xyzabc + ** Failers +No match + xyzxyz +No match + +/\H\h\V\v/ + X X\x0a + 0: X X\x0a + X\x09X\x0b + 0: X\x09X\x0b + ** Failers +No match + \xa0 X\x0a +No match + +/\H*\h+\V?\v{3,4}/ + \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a + 0: \x09 \xa0X\x0a\x0b\x0c\x0d + 1: \x09 \xa0X\x0a\x0b\x0c + \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a + 0: \x09 \xa0\x0a\x0b\x0c\x0d + 1: \x09 \xa0\x0a\x0b\x0c + \x09\x20\xa0\x0a\x0b\x0c + 0: \x09 \xa0\x0a\x0b\x0c + ** Failers +No match + \x09\x20\xa0\x0a\x0b +No match + +/\H{3,4}/ + XY ABCDE + 0: ABCD + 1: ABC + XY PQR ST + 0: PQR + +/.\h{3,4}./ + XY AB PQRS + 0: B P + 1: B + +/\h*X\h?\H+Y\H?Z/ + >XNNNYZ + 0: XNNNYZ + > X NYQZ + 0: X NYQZ + ** Failers +No match + >XYZ +No match + > X NY Z +No match + +/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ + >XY\x0aZ\x0aA\x0bNN\x0c + 0: XY\x0aZ\x0aA\x0bNN\x0c + >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + 0: \x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + +/.+A/ + \r\nA +No match + +/\nA/ + \r\nA + 0: \x0aA + +/[\r\n]A/ + \r\nA + 0: \x0aA + +/(\r|\n)A/ + \r\nA + 0: \x0aA + +/a\Rb/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + ** Failers +No match + a\x85b +No match + a\x0bb +No match + +/a\Rb/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + a\x85b + 0: a\x85b + a\x0bb + 0: a\x0bb + ** Failers +No match + a\x85b\ +No match + a\x0bb\ +No match + +/a\R?b/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + ** Failers +No match + a\x85b +No match + a\x0bb +No match + +/a\R?b/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + a\x85b + 0: a\x85b + a\x0bb + 0: a\x0bb + ** Failers +No match + a\x85b\ +No match + a\x0bb\ +No match + +/a\R{2,4}b/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\r\n\nb + 0: a\x0d\x0a\x0ab + a\n\r\rb + 0: a\x0a\x0d\x0db + a\r\n\r\n\r\n\r\nb + 0: a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0ab + ** Failers +No match + a\x85\85b +No match + a\x0b\0bb +No match + +/a\R{2,4}b/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\r\rb + 0: a\x0d\x0db + a\n\n\nb + 0: a\x0a\x0a\x0ab + a\r\n\n\r\rb + 0: a\x0d\x0a\x0a\x0d\x0db + a\x85\85b +No match + a\x0b\0bb +No match + ** Failers +No match + a\r\r\r\r\rb +No match + a\x85\85b\ +No match + a\x0b\0bb\ +No match + +/a(?!)|\wbc/ + abc + 0: abc + +/a[]b/ + ** Failers +No match + ab +No match + +/a[]+b/ + ** Failers +No match + ab +No match + +/a[]*+b/ + ** Failers +No match + ab +No match + +/a[^]b/ + aXb + 0: aXb + a\nb + 0: a\x0ab + ** Failers +No match + ab +No match + +/a[^]+b/ + aXb + 0: aXb + a\nX\nXb + 0: a\x0aX\x0aXb + ** Failers +No match + ab +No match + +/X$/E + X + 0: X + ** Failers +No match + X\n +No match + +/X$/ + X + 0: X + X\n + 0: X + +/xyz/C + xyz +--->xyz + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +3 ^ ^ + 0: xyz + abcxyz +--->abcxyz + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +3 ^ ^ + 0: xyz + abcxyz\Y +--->abcxyz + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +3 ^ ^ + 0: xyz + ** Failers +No match + abc +No match + abc\Y +--->abc + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x +No match + abcxypqr +No match + abcxypqr\Y +--->abcxypqr + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x +No match + +/(*NO_START_OPT)xyz/C + abcxyz +--->abcxyz ++15 ^ x ++15 ^ x ++15 ^ x ++15 ^ x ++16 ^^ y ++17 ^ ^ z ++18 ^ ^ + 0: xyz + +/(?C)ab/ + ab +--->ab + 0 ^ a + 0: ab + \C-ab + 0: ab + +/ab/C + ab +--->ab + +0 ^ a + +1 ^^ b + +2 ^ ^ + 0: ab + \C-ab + 0: ab + +/^"((?(?=[a])[^"])|b)*"$/C + "ab" +--->"ab" + +0 ^ ^ + +1 ^ " + +2 ^^ ((?(?=[a])[^"])|b)* ++21 ^^ " + +3 ^^ (?(?=[a])[^"]) ++18 ^^ b + +5 ^^ (?=[a]) + +8 ^ [a] ++11 ^^ ) ++12 ^^ [^"] ++16 ^ ^ ) ++17 ^ ^ | ++21 ^ ^ " + +3 ^ ^ (?(?=[a])[^"]) ++18 ^ ^ b + +5 ^ ^ (?=[a]) + +8 ^ [a] ++19 ^ ^ ) ++21 ^ ^ " + +3 ^ ^ (?(?=[a])[^"]) ++18 ^ ^ b + +5 ^ ^ (?=[a]) + +8 ^ [a] ++17 ^ ^ | ++22 ^ ^ $ ++23 ^ ^ + 0: "ab" + \C-"ab" + 0: "ab" + +/\d+X|9+Y/ + ++++123999\P +Partial match: 123999 + ++++123999Y\P + 0: 999Y + +/Z(*F)/ + Z\P +No match + ZA\P +No match + +/Z(?!)/ + Z\P +No match + ZA\P +No match + +/dog(sbody)?/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/dog(sbody)??/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/dog|dogsbody/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/dogsbody|dog/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/Z(*F)Q|ZXY/ + Z\P +Partial match: Z + ZA\P +No match + X\P +No match + +/\bthe cat\b/ + the cat\P + 0: the cat + the cat\P\P +Partial match: the cat + +/dog(sbody)?/ + dogs\D\P + 0: dog + body\D\R + 0: body + +/dog(sbody)?/ + dogs\D\P\P +Partial match: dogs + body\D\R + 0: body + +/abc/ + abc\P + 0: abc + abc\P\P + 0: abc + +/abc\K123/ + xyzabc123pqr +Error -16 (item unsupported for DFA matching) + +/(?<=abc)123/ + xyzabc123pqr + 0: 123 + xyzabc12\P +Partial match: abc12 + xyzabc12\P\P +Partial match: abc12 + +/\babc\b/ + +++abc+++ + 0: abc + +++ab\P +Partial match: +ab + +++ab\P\P +Partial match: +ab + +/(?=C)/g+ + ABCDECBA + 0: + 0+ CDECBA + 0: + 0+ CBA + +/(abc|def|xyz)/I +Capturing subpattern count = 1 +No options +No first char +No need char + terhjk;abcdaadsfe + 0: abc + the quick xyz brown fox + 0: xyz + \Yterhjk;abcdaadsfe + 0: abc + \Ythe quick xyz brown fox + 0: xyz + ** Failers +No match + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + +/(abc|def|xyz)/SI +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 3 +Starting byte set: a d x + terhjk;abcdaadsfe + 0: abc + the quick xyz brown fox + 0: xyz + \Yterhjk;abcdaadsfe + 0: abc + \Ythe quick xyz brown fox + 0: xyz + ** Failers +No match + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + +/abcd*/+ + xxxxabcd\P + 0: abcd + 0+ + 1: abc + xxxxabcd\P\P +Partial match: abcd + dddxxx\R + 0: ddd + 0+ xxx + 1: dd + 2: d + 3: + xxxxabcd\P\P +Partial match: abcd + xxx\R + 0: + 0+ xxx + +/abcd*/i + xxxxabcd\P + 0: abcd + 1: abc + xxxxabcd\P\P +Partial match: abcd + XXXXABCD\P + 0: ABCD + 1: ABC + XXXXABCD\P\P +Partial match: ABCD + +/abc\d*/ + xxxxabc1\P + 0: abc1 + 1: abc + xxxxabc1\P\P +Partial match: abc1 + +/abc[de]*/ + xxxxabcde\P + 0: abcde + 1: abcd + 2: abc + xxxxabcde\P\P +Partial match: abcde + +/(?:(?1)|B)(A(*F)|C)/ + ABCD + 0: BC + CCD + 0: CC + ** Failers +No match + CAD +No match + +/^(?:(?1)|B)(A(*F)|C)/ + CCD + 0: CC + BCD + 0: BC + ** Failers +No match + ABCD +No match + CAD +No match + BAD +No match + +/^(?!a(*SKIP)b)/ + ac +Error -16 (item unsupported for DFA matching) + +/^(?=a(*SKIP)b|ac)/ + ** Failers +No match + ac +Error -16 (item unsupported for DFA matching) + +/^(?=a(*THEN)b|ac)/ + ac +Error -16 (item unsupported for DFA matching) + +/^(?=a(*PRUNE)b)/ + ab +Error -16 (item unsupported for DFA matching) + ** Failers +No match + ac +Error -16 (item unsupported for DFA matching) + +/^(?(?!a(*SKIP)b))/ + ac +Error -16 (item unsupported for DFA matching) + +/(?<=abc)def/ + abc\P\P +Partial match: abc + +/abc$/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc$/m + abc + 0: abc + abc\n + 0: abc + abc\P\P +Partial match: abc + abc\n\P\P + 0: abc + abc\P + 0: abc + abc\n\P + 0: abc + +/abc\z/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc\Z/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc\b/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc\B/ + abc +No match + abc\P +Partial match: abc + abc\P\P +Partial match: abc + +/.+/ + abc\>0 + 0: abc + 1: ab + 2: a + abc\>1 + 0: bc + 1: b + abc\>2 + 0: c + abc\>3 +No match + abc\>4 +Error -24 (bad offset value) + abc\>-4 +Error -24 (bad offset value) + +/^(?:a)++\w/ + aaaab + 0: aaaab + ** Failers +No match + aaaa +No match + bbb +No match + +/^(?:aa|(?:a)++\w)/ + aaaab + 0: aaaab + 1: aa + aaaa + 0: aa + ** Failers +No match + bbb +No match + +/^(?:a)*+\w/ + aaaab + 0: aaaab + bbb + 0: b + ** Failers +No match + aaaa +No match + +/^(a)++\w/ + aaaab + 0: aaaab + ** Failers +No match + aaaa +No match + bbb +No match + +/^(a|)++\w/ + aaaab + 0: aaaab + ** Failers +No match + aaaa +No match + bbb +No match + +/(?=abc){3}abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc)+abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc)++abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc){0}xyz/ + xyz + 0: xyz + +/(?=abc){1}xyz/ + ** Failers +No match + xyz +No match + +/(?=(a))?./ + ab + 0: a + bc + 0: b + +/(?=(a))??./ + ab + 0: a + bc + 0: b + +/^(?=(a)){0}b(?1)/ + backgammon + 0: ba + +/^(?=(?1))?[az]([abc])d/ + abd + 0: abd + zcdxx + 0: zcd + +/^(?!a){0}\w+/ + aaaaa + 0: aaaaa + 1: aaaa + 2: aaa + 3: aa + 4: a + +/(?<=(abc))?xyz/ + abcxyz + 0: xyz + pqrxyz + 0: xyz + +/((?2))((?1))/ + abc +Error -26 (nested recursion at the same subject position) + +/(?(R)a+|(?R)b)/ + aaaabcde + 0: aaaab + +/(?(R)a+|((?R))b)/ + aaaabcde + 0: aaaab + +/((?(R)a+|(?1)b))/ + aaaabcde + 0: aaaab + +/((?(R2)a+|(?1)b))/ + aaaabcde +Error -17 (backreference condition or recursion test not supported for DFA matching) + +/(?(R)a*(?1)|((?R))b)/ + aaaabcde +Error -26 (nested recursion at the same subject position) + +/(a+)/ + \O6aaaa +Matched, but too many subsidiary matches + 0: aaaa + 1: aaa + 2: aa + \O8aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/ab\Cde/ + abXde + 0: abXde + +/(?<=ab\Cde)X/ + abZdeX + 0: X + +/^\R/ + \r\P + 0: \x0d + \r\P\P +Partial match: \x0d + +/^\R{2,3}x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P +Partial match: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P +Partial match: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + \r\rx + 0: \x0d\x0dx + \r\r\rx + 0: \x0d\x0d\x0dx + +/^\R{2,3}?x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P +Partial match: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P +Partial match: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + \r\rx + 0: \x0d\x0dx + \r\r\rx + 0: \x0d\x0d\x0dx + +/^\R?x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + x + 0: x + \rx + 0: \x0dx + +/^\R+x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\n\P +Partial match: \x0d\x0a + \r\n\P\P +Partial match: \x0d\x0a + \rx + 0: \x0dx + +/^a$/ + a\r\P +Partial match: a\x0d + a\r\P\P +Partial match: a\x0d + +/^a$/m + a\r\P +Partial match: a\x0d + a\r\P\P +Partial match: a\x0d + +/^(a$|a\r)/ + a\r\P + 0: a\x0d + a\r\P\P +Partial match: a\x0d + +/^(a$|a\r)/m + a\r\P + 0: a\x0d + a\r\P\P +Partial match: a\x0d + +/./ + \r\P + 0: \x0d + \r\P\P +Partial match: \x0d + +/.{2,3}/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P + 0: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P + 0: \x0d\x0d\x0d + 1: \x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + +/.{2,3}?/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P + 0: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P + 0: \x0d\x0d\x0d + 1: \x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + +/-- Test simple validity check for restarts --/ + +/abcdef/ + abc\R +Error -30 (invalid data in workspace for DFA restart) + +/)(.)|(?R))++)*F>/ + text text xxxxx text F> text2 more text. + 0: text xxxxx text F> + +/^(?>.{4})abc|^\w\w.xabcd/ + xxxxabcd + 0: xxxxabcd + 1: xxxxabc + xx\xa0xabcd + 0: xx\xa0xabcd + 1: xx\xa0xabc + +/^(.{4}){2}+abc|^\w\w.x\w\w\w\wabcd/ + xxxxxxxxabcd + 0: xxxxxxxxabcd + 1: xxxxxxxxabc + xx\xa0xxxxxabcd + 0: xx\xa0xxxxxabcd + 1: xx\xa0xxxxxabc + +/-- End of testinput8 --/ diff --git a/tools/pcre/testdata/testoutput9 b/tools/pcre/testdata/testoutput9 new file mode 100644 index 00000000..95cd618d --- /dev/null +++ b/tools/pcre/testdata/testoutput9 @@ -0,0 +1,1371 @@ +/-- This set of tests checks UTF-8 support with the DFA matching functionality + of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running + it. --/ + +/\x{100}ab/8 + \x{100}ab + 0: \x{100}ab + +/a\x{100}*b/8 + ab + 0: ab + a\x{100}b + 0: a\x{100}b + a\x{100}\x{100}b + 0: a\x{100}\x{100}b + +/a\x{100}+b/8 + a\x{100}b + 0: a\x{100}b + a\x{100}\x{100}b + 0: a\x{100}\x{100}b + *** Failers +No match + ab +No match + +/\bX/8 + Xoanon + 0: X + +Xoanon + 0: X + \x{300}Xoanon + 0: X + *** Failers +No match + YXoanon +No match + +/\BX/8 + YXoanon + 0: X + *** Failers +No match + Xoanon +No match + +Xoanon +No match + \x{300}Xoanon +No match + +/X\b/8 + X+oanon + 0: X + ZX\x{300}oanon + 0: X + FAX + 0: X + *** Failers +No match + Xoanon +No match + +/X\B/8 + Xoanon + 0: X + *** Failers +No match + X+oanon +No match + ZX\x{300}oanon +No match + FAX +No match + +/[^a]/8 + abcd + 0: b + a\x{100} + 0: \x{100} + +/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 + ab99 + 0: ab9 + \x{123}\x{123}45 + 0: \x{123}\x{123}4 + \x{400}\x{401}\x{402}6 + 0: \x{400}\x{401}\x{402}6 + *** Failers +No match + d99 +No match + \x{123}\x{122}4 +No match + \x{400}\x{403}6 +No match + \x{400}\x{401}\x{402}\x{402}6 +No match + +/a.b/8 + acb + 0: acb + a\x7fb + 0: a\x{7f}b + a\x{100}b + 0: a\x{100}b + *** Failers +No match + a\nb +No match + +/a(.{3})b/8 + a\x{4000}xyb + 0: a\x{4000}xyb + a\x{4000}\x7fyb + 0: a\x{4000}\x{7f}yb + a\x{4000}\x{100}yb + 0: a\x{4000}\x{100}yb + *** Failers +No match + a\x{4000}b +No match + ac\ncb +No match + +/a(.*?)(.)/ + a\xc0\x88b + 0: a\xc0\x88b + 1: a\xc0\x88 + 2: a\xc0 + +/a(.*?)(.)/8 + a\x{100}b + 0: a\x{100}b + 1: a\x{100} + +/a(.*)(.)/ + a\xc0\x88b + 0: a\xc0\x88b + 1: a\xc0\x88 + 2: a\xc0 + +/a(.*)(.)/8 + a\x{100}b + 0: a\x{100}b + 1: a\x{100} + +/a(.)(.)/ + a\xc0\x92bcd + 0: a\xc0\x92 + +/a(.)(.)/8 + a\x{240}bcd + 0: a\x{240}b + +/a(.?)(.)/ + a\xc0\x92bcd + 0: a\xc0\x92 + 1: a\xc0 + +/a(.?)(.)/8 + a\x{240}bcd + 0: a\x{240}b + 1: a\x{240} + +/a(.??)(.)/ + a\xc0\x92bcd + 0: a\xc0\x92 + 1: a\xc0 + +/a(.??)(.)/8 + a\x{240}bcd + 0: a\x{240}b + 1: a\x{240} + +/a(.{3})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + *** Failers +No match + a\x{1234}b +No match + ac\ncb +No match + +/a(.{3,})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + 0: axxxxbcdefghijb + 1: axxxxb + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers +No match + a\x{1234}b +No match + +/a(.{3,}?)b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + 0: axxxxbcdefghijb + 1: axxxxb + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers +No match + a\x{1234}b +No match + +/a(.{3,5})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + 0: axxxxb + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + 0: axbxxb + axxxxxbcdefghijb + 0: axxxxxb + *** Failers +No match + a\x{1234}b +No match + axxxxxxbcdefghijb +No match + +/a(.{3,5}?)b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + 0: axxxxb + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + 0: axbxxb + axxxxxbcdefghijb + 0: axxxxxb + *** Failers +No match + a\x{1234}b +No match + axxxxxxbcdefghijb +No match + +/^[a\x{c0}]/8 + *** Failers +No match + \x{100} +No match + +/(?<=aXb)cd/8 + aXbcd + 0: cd + +/(?<=a\x{100}b)cd/8 + a\x{100}bcd + 0: cd + +/(?<=a\x{100000}b)cd/8 + a\x{100000}bcd + 0: cd + +/(?:\x{100}){3}b/8 + \x{100}\x{100}\x{100}b + 0: \x{100}\x{100}\x{100}b + *** Failers +No match + \x{100}\x{100}b +No match + +/\x{ab}/8 + \x{ab} + 0: \x{ab} + \xc2\xab + 0: \x{ab} + *** Failers +No match + \x00{ab} +No match + +/(?<=(.))X/8 + WXYZ + 0: X + \x{256}XYZ + 0: X + *** Failers +No match + XYZ +No match + +/[^a]+/8g + bcd + 0: bcd + 1: bc + 2: b + \x{100}aY\x{256}Z + 0: \x{100} + 0: Y\x{256}Z + 1: Y\x{256} + 2: Y + +/^[^a]{2}/8 + \x{100}bc + 0: \x{100}b + +/^[^a]{2,}/8 + \x{100}bcAa + 0: \x{100}bcA + 1: \x{100}bc + 2: \x{100}b + +/^[^a]{2,}?/8 + \x{100}bca + 0: \x{100}bc + 1: \x{100}b + +/[^a]+/8ig + bcd + 0: bcd + 1: bc + 2: b + \x{100}aY\x{256}Z + 0: \x{100} + 0: Y\x{256}Z + 1: Y\x{256} + 2: Y + +/^[^a]{2}/8i + \x{100}bc + 0: \x{100}b + +/^[^a]{2,}/8i + \x{100}bcAa + 0: \x{100}bc + 1: \x{100}b + +/^[^a]{2,}?/8i + \x{100}bca + 0: \x{100}bc + 1: \x{100}b + +/\x{100}{0,0}/8 + abcd + 0: + +/\x{100}?/8 + abcd + 0: + \x{100}\x{100} + 0: \x{100} + 1: + +/\x{100}{0,3}/8 + \x{100}\x{100} + 0: \x{100}\x{100} + 1: \x{100} + 2: + \x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100} + 1: \x{100}\x{100} + 2: \x{100} + 3: + +/\x{100}*/8 + abce + 0: + \x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100}\x{100} + 1: \x{100}\x{100}\x{100} + 2: \x{100}\x{100} + 3: \x{100} + 4: + +/\x{100}{1,1}/8 + abcd\x{100}\x{100}\x{100}\x{100} + 0: \x{100} + +/\x{100}{1,3}/8 + abcd\x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100} + 1: \x{100}\x{100} + 2: \x{100} + +/\x{100}+/8 + abcd\x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100}\x{100} + 1: \x{100}\x{100}\x{100} + 2: \x{100}\x{100} + 3: \x{100} + +/\x{100}{3}/8 + abcd\x{100}\x{100}\x{100}XX + 0: \x{100}\x{100}\x{100} + +/\x{100}{3,5}/8 + abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX + 0: \x{100}\x{100}\x{100}\x{100}\x{100} + 1: \x{100}\x{100}\x{100}\x{100} + 2: \x{100}\x{100}\x{100} + +/\x{100}{3,}/8 + abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX + 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 2: \x{100}\x{100}\x{100}\x{100}\x{100} + 3: \x{100}\x{100}\x{100}\x{100} + 4: \x{100}\x{100}\x{100} + +/(?<=a\x{100}{2}b)X/8 + Xyyya\x{100}\x{100}bXzzz + 0: X + +/\D*/8 + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +Matched, but too many subsidiary matches + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 3: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 4: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 6: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 7: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 8: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 9: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +10: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +11: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +12: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +13: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +14: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +15: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +16: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +17: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +18: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +19: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/\D*/8 + \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +Matched, but too many subsidiary matches + 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 2: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 3: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 4: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 5: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 6: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 7: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 8: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 9: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +10: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +11: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +12: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +13: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +14: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +15: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +16: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +17: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +18: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +19: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +20: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +21: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + +/\D/8 + 1X2 + 0: X + 1\x{100}2 + 0: \x{100} + +/>\S/8 + > >X Y + 0: >X + > >\x{100} Y + 0: >\x{100} + +/\d/8 + \x{100}3 + 0: 3 + +/\s/8 + \x{100} X + 0: + +/\D+/8 + 12abcd34 + 0: abcd + 1: abc + 2: ab + 3: a + *** Failers + 0: *** Failers + 1: *** Failer + 2: *** Faile + 3: *** Fail + 4: *** Fai + 5: *** Fa + 6: *** F + 7: *** + 8: *** + 9: ** +10: * + 1234 +No match + +/\D{2,3}/8 + 12abcd34 + 0: abc + 1: ab + 12ab34 + 0: ab + *** Failers + 0: *** + 1: ** + 1234 +No match + 12a34 +No match + +/\D{2,3}?/8 + 12abcd34 + 0: abc + 1: ab + 12ab34 + 0: ab + *** Failers + 0: *** + 1: ** + 1234 +No match + 12a34 +No match + +/\d+/8 + 12abcd34 + 0: 12 + 1: 1 + *** Failers +No match + +/\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 + +/\S{2,3}/8 + 12abcd34 + 0: 12a + 1: 12 + 1234abcd + 0: 123 + 1: 12 + *** Failers + 0: *** + 1: ** + \ \ +No match + +/\S{2,3}?/8 + 12abcd34 + 0: 12a + 1: 12 + 1234abcd + 0: 123 + 1: 12 + *** Failers + 0: *** + 1: ** + \ \ +No match + +/>\s+ <34 + 0: > < + *** Failers +No match + +/>\s{2,3} < + ab> < + *** Failers +No match + ab> \s{2,3}? < + ab> < + *** Failers +No match + ab> \xff< + 0: \xff + +/[\xff]/8 + >\x{ff}< + 0: \x{ff} + +/[^\xFF]/ + XYZ + 0: X + +/[^\xff]/8 + XYZ + 0: X + \x{123} + 0: \x{123} + +/^[ac]*b/8 + xb +No match + +/^[ac\x{100}]*b/8 + xb +No match + +/^[^x]*b/8i + xb +No match + +/^[^x]*b/8 + xb +No match + +/^\d*b/8 + xb +No match + +/(|a)/g8 + catac + 0: + 0: a + 1: + 0: + 0: a + 1: + 0: + 0: + a\x{256}a + 0: a + 1: + 0: + 0: a + 1: + 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 + \x{a0} X\x0a +No match + +/\H*\h+\V?\v{3,4}/8 + \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} + 1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c} + \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a + 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}\x{0d} + 1: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} + \x09\x20\x{a0}\x0a\x0b\x0c + 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} + ** Failers +No match + \x09\x20\x{a0}\x0a\x0b +No match + +/\H\h\V\v/8 + \x{3001}\x{3000}\x{2030}\x{2028} + 0: \x{3001}\x{3000}\x{2030}\x{2028} + X\x{180e}X\x{85} + 0: X\x{180e}X\x{85} + ** Failers +No match + \x{2009} X\x0a +No match + +/\H*\h+\V?\v{3,4}/8 + \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a + 0: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}\x{0d} + 1: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c} + \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a + 0: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c}\x{2028} + 1: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c} + \x09\x20\x{202f}\x0a\x0b\x0c + 0: \x{09} \x{202f}\x{0a}\x{0b}\x{0c} + ** Failers +No match + \x09\x{200a}\x{a0}\x{2028}\x0b +No match + +/a\Rb/I8 +Capturing subpattern count = 0 +Options: bsr_anycrlf utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + ** Failers +No match + a\x{85}b +No match + a\x0bb +No match + +/a\Rb/I8 +Capturing subpattern count = 0 +Options: bsr_unicode utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x{85}b + 0: a\x{85}b + a\x0bb + 0: a\x{0b}b + ** Failers +No match + a\x{85}b\ +No match + a\x0bb\ +No match + +/a\R?b/I8 +Capturing subpattern count = 0 +Options: bsr_anycrlf utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + ** Failers +No match + a\x{85}b +No match + a\x0bb +No match + +/a\R?b/I8 +Capturing subpattern count = 0 +Options: bsr_unicode utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x{85}b + 0: a\x{85}b + a\x0bb + 0: a\x{0b}b + ** Failers +No match + a\x{85}b\ +No match + a\x0bb\ +No match + +/X/8f + A\x{1ec5}ABCXYZ + 0: X + +/abcd*/8 + xxxxabcd\P + 0: abcd + 1: abc + xxxxabcd\P\P +Partial match: abcd + +/abcd*/i8 + xxxxabcd\P + 0: abcd + 1: abc + xxxxabcd\P\P +Partial match: abcd + XXXXABCD\P + 0: ABCD + 1: ABC + XXXXABCD\P\P +Partial match: ABCD + +/abc\d*/8 + xxxxabc1\P + 0: abc1 + 1: abc + xxxxabc1\P\P +Partial match: abc1 + +/abc[de]*/8 + xxxxabcde\P + 0: abcde + 1: abcd + 2: abc + xxxxabcde\P\P +Partial match: abcde + +/\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} + +/[^\x{100}]/8 + \x{100}\x{101}X + 0: \x{101} + +/[^\x{100}]+/8 + \x{100}\x{101}X + 0: \x{101}X + 1: \x{101} + +/-- End of testinput9 --/ diff --git a/tools/pcre/testdata/testoutputEBC b/tools/pcre/testdata/testoutputEBC new file mode 100644 index 00000000..abbfdc43 --- /dev/null +++ b/tools/pcre/testdata/testoutputEBC @@ -0,0 +1,182 @@ +/-- This is a specialized test for checking, when PCRE is compiled with the +EBCDIC option but in an ASCII environment, that newline and white space +functionality is working. It catches cases where explicit values such as 0x0a +have been used instead of names like CHAR_LF. Needless to say, it is not a +genuine EBCDIC test! In patterns, alphabetic characters that follow a backslash +must be in EBCDIC code. In data, newlines and other spacing characters must be +in EBCDIC, but can be specified as escapes. --/ + +/-- Test default newline and variations --/ + +/^A/m + ABC + 0: A + 12\x15ABC + 0: A + +/^A/m + 12\x15ABC + 0: A + 12\x0dABC + 0: A + 12\x0d\x15ABC + 0: A + 12\x25ABC + 0: A + +/^A/m + 12\x15ABC + 0: A + 12\x0dABC + 0: A + 12\x0d\x15ABC + 0: A + ** Fail +No match + 12\x25ABC +No match + +/-- Test \h --/ + +/^A\ˆ/ + A B + 0: A\x20 + +/-- Test \H --/ + +/^A\È/ + AB + 0: AB + ** Fail +No match + A B +No match + +/-- Test \R --/ + +/^A\Ù/ + A\x15B + 0: A\x15 + A\x0dB + 0: A\x0d + A\x25B + 0: A\x25 + A\x0bB + 0: A\x0b + A\x0cB + 0: A\x0c + ** Fail +No match + A B +No match + +/-- Test \v --/ + +/^A\¥/ + A\x15B + 0: A\x15 + A\x0dB + 0: A\x0d + A\x25B + 0: A\x25 + A\x0bB + 0: A\x0b + A\x0cB + 0: A\x0c + ** Fail +No match + A B +No match + +/-- Test \V --/ + +/^A\å/ + A B + 0: A\x20 + ** Fail +No match + A\x15B +No match + A\x0dB +No match + A\x25B +No match + A\x0bB +No match + A\x0cB +No match + +/-- For repeated items, use an atomic group so that the output is the same +for DFA matching (otherwise it may show multiple matches). --/ + +/-- Test \h+ --/ + +/^A(?>\ˆ+)/ + A B + 0: A\x20 + +/-- Test \H+ --/ + +/^A(?>\È+)/ + AB + 0: AB + ** Fail +No match + A B +No match + +/-- Test \R+ --/ + +/^A(?>\Ù+)/ + A\x15B + 0: A\x15 + A\x0dB + 0: A\x0d + A\x25B + 0: A\x25 + A\x0bB + 0: A\x0b + A\x0cB + 0: A\x0c + ** Fail +No match + A B +No match + +/-- Test \v+ --/ + +/^A(?>\¥+)/ + A\x15B + 0: A\x15 + A\x0dB + 0: A\x0d + A\x25B + 0: A\x25 + A\x0bB + 0: A\x0b + A\x0cB + 0: A\x0c + ** Fail +No match + A B +No match + +/-- Test \V+ --/ + +/^A(?>\å+)/ + A B + 0: A\x20B + ** Fail +No match + A\x15B +No match + A\x0dB +No match + A\x25B +No match + A\x0bB +No match + A\x0cB +No match + +/-- End --/ diff --git a/tools/pcre/testdata/wintestinput3 b/tools/pcre/testdata/wintestinput3 new file mode 100644 index 00000000..04e76a6d --- /dev/null +++ b/tools/pcre/testdata/wintestinput3 @@ -0,0 +1,91 @@ +/^[\w]+/ + *** Failers + École + +/^[\w]+/Lfrench + École + +/^[\w]+/ + *** Failers + École + +/^[\W]+/ + École + +/^[\W]+/Lfrench + *** Failers + École + +/[\b]/ + \b + *** Failers + a + +/[\b]/Lfrench + \b + *** Failers + a + +/^\w+/ + *** Failers + École + +/^\w+/Lfrench + École + +/(.+)\b(.+)/ + École + +/(.+)\b(.+)/Lfrench + *** Failers + École + +/École/i + École + *** Failers + école + +/École/iLfrench + École + école + +/\w/IS + +/\w/ISLfrench + +/^[\xc8-\xc9]/iLfrench + École + école + +/^[\xc8-\xc9]/Lfrench + École + *** Failers + école + +/\W+/Lfrench + >>>\xaa<<< + >>>\xba<<< + +/[\W]+/Lfrench + >>>\xaa<<< + >>>\xba<<< + +/[^[:alpha:]]+/Lfrench + >>>\xaa<<< + >>>\xba<<< + +/\w+/Lfrench + >>>\xaa<<< + >>>\xba<<< + +/[\w]+/Lfrench + >>>\xaa<<< + >>>\xba<<< + +/[[:alpha:]]+/Lfrench + >>>\xaa<<< + >>>\xba<<< + +/[[:alpha:]][[:lower:]][[:upper:]]/DZLfrench + +/ End of testinput3 / diff --git a/tools/pcre/testdata/wintestoutput3 b/tools/pcre/testdata/wintestoutput3 new file mode 100644 index 00000000..00880070 --- /dev/null +++ b/tools/pcre/testdata/wintestoutput3 @@ -0,0 +1,166 @@ +/^[\w]+/ + *** Failers +No match + École +No match + +/^[\w]+/Lfrench + École + 0: École + +/^[\w]+/ + *** Failers +No match + École +No match + +/^[\W]+/ + École + 0: \xc9 + +/^[\W]+/Lfrench + *** Failers + 0: *** + École +No match + +/[\b]/ + \b + 0: \x08 + *** Failers +No match + a +No match + +/[\b]/Lfrench + \b + 0: \x08 + *** Failers +No match + a +No match + +/^\w+/ + *** Failers +No match + École +No match + +/^\w+/Lfrench + École + 0: École + +/(.+)\b(.+)/ + École + 0: \xc9cole + 1: \xc9 + 2: cole + +/(.+)\b(.+)/Lfrench + *** Failers + 0: *** Failers + 1: *** + 2: Failers + École +No match + +/École/i + École + 0: \xc9cole + *** Failers +No match + école +No match + +/École/iLfrench + École + 0: École + école + 0: école + +/\w/IS +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P + Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z + +/\w/ISLfrench +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P + Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z + ƒ Š Œ Ž š œ ž Ÿ ª ² ³ µ ¹ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö + Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý + þ ÿ + +/^[\xc8-\xc9]/iLfrench + École + 0: É + école + 0: é + +/^[\xc8-\xc9]/Lfrench + École + 0: É + *** Failers +No match + école +No match + +/\W+/Lfrench + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/[\W]+/Lfrench + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/[^[:alpha:]]+/Lfrench + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/\w+/Lfrench + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[\w]+/Lfrench + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[[:alpha:]]+/Lfrench + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[[:alpha:]][[:lower:]][[:upper:]]/DZLfrench +------------------------------------------------------------------ + Bra + [A-Za-z\x83\x8a\x8c\x8e\x9a\x9c\x9e\x9f\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\xff] + [a-z\x83\x9a\x9c\x9e\xaa\xb5\xba\xdf-\xf6\xf8-\xff] + [A-Z\x8a\x8c\x8e\x9f\xc0-\xd6\xd8-\xde] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/ End of testinput3 / diff --git a/tools/pcre/ucp.h b/tools/pcre/ucp.h new file mode 100644 index 00000000..21039106 --- /dev/null +++ b/tools/pcre/ucp.h @@ -0,0 +1,197 @@ +/************************************************* +* Unicode Property Table handler * +*************************************************/ + +#ifndef _UCP_H +#define _UCP_H + +/* This file contains definitions of the property values that are returned by +the UCD access macros. New values that are added for new releases of Unicode +should always be at the end of each enum, for backwards compatibility. + +IMPORTANT: Note also that the specific numeric values of the enums have to be +the same as the values that are generated by the maint/MultiStage2.py script, +where the equivalent property descriptive names are listed in vectors. */ + +/* These are the general character categories. */ + +enum { + ucp_C, /* Other */ + ucp_L, /* Letter */ + ucp_M, /* Mark */ + ucp_N, /* Number */ + ucp_P, /* Punctuation */ + ucp_S, /* Symbol */ + ucp_Z /* Separator */ +}; + +/* These are the particular character categories. */ + +enum { + ucp_Cc, /* Control */ + ucp_Cf, /* Format */ + ucp_Cn, /* Unassigned */ + ucp_Co, /* Private use */ + ucp_Cs, /* Surrogate */ + ucp_Ll, /* Lower case letter */ + ucp_Lm, /* Modifier letter */ + ucp_Lo, /* Other letter */ + ucp_Lt, /* Title case letter */ + ucp_Lu, /* Upper case letter */ + ucp_Mc, /* Spacing mark */ + ucp_Me, /* Enclosing mark */ + ucp_Mn, /* Non-spacing mark */ + ucp_Nd, /* Decimal number */ + ucp_Nl, /* Letter number */ + ucp_No, /* Other number */ + ucp_Pc, /* Connector punctuation */ + ucp_Pd, /* Dash punctuation */ + ucp_Pe, /* Close punctuation */ + ucp_Pf, /* Final punctuation */ + ucp_Pi, /* Initial punctuation */ + ucp_Po, /* Other punctuation */ + ucp_Ps, /* Open punctuation */ + ucp_Sc, /* Currency symbol */ + ucp_Sk, /* Modifier symbol */ + ucp_Sm, /* Mathematical symbol */ + ucp_So, /* Other symbol */ + ucp_Zl, /* Line separator */ + ucp_Zp, /* Paragraph separator */ + ucp_Zs /* Space separator */ +}; + +/* These are grapheme break properties. Note that the code for processing them +assumes that the values are less than 16. If more values are added that take +the number to 16 or more, the code will have to be rewritten. */ + +enum { + ucp_gbCR, /* 0 */ + ucp_gbLF, /* 1 */ + ucp_gbControl, /* 2 */ + ucp_gbExtend, /* 3 */ + ucp_gbPrepend, /* 4 */ + ucp_gbSpacingMark, /* 5 */ + ucp_gbL, /* 6 Hangul syllable type L */ + ucp_gbV, /* 7 Hangul syllable type V */ + ucp_gbT, /* 8 Hangul syllable type T */ + ucp_gbLV, /* 9 Hangul syllable type LV */ + ucp_gbLVT, /* 10 Hangul syllable type LVT */ + ucp_gbRegionalIndicator, /* 11 */ + ucp_gbOther /* 12 */ +}; + +/* These are the script identifications. */ + +enum { + ucp_Arabic, + ucp_Armenian, + ucp_Bengali, + ucp_Bopomofo, + ucp_Braille, + ucp_Buginese, + ucp_Buhid, + ucp_Canadian_Aboriginal, + ucp_Cherokee, + ucp_Common, + ucp_Coptic, + ucp_Cypriot, + ucp_Cyrillic, + ucp_Deseret, + ucp_Devanagari, + ucp_Ethiopic, + ucp_Georgian, + ucp_Glagolitic, + ucp_Gothic, + ucp_Greek, + ucp_Gujarati, + ucp_Gurmukhi, + ucp_Han, + ucp_Hangul, + ucp_Hanunoo, + ucp_Hebrew, + ucp_Hiragana, + ucp_Inherited, + ucp_Kannada, + ucp_Katakana, + ucp_Kharoshthi, + ucp_Khmer, + ucp_Lao, + ucp_Latin, + ucp_Limbu, + ucp_Linear_B, + ucp_Malayalam, + ucp_Mongolian, + ucp_Myanmar, + ucp_New_Tai_Lue, + ucp_Ogham, + ucp_Old_Italic, + ucp_Old_Persian, + ucp_Oriya, + ucp_Osmanya, + ucp_Runic, + ucp_Shavian, + ucp_Sinhala, + ucp_Syloti_Nagri, + ucp_Syriac, + ucp_Tagalog, + ucp_Tagbanwa, + ucp_Tai_Le, + ucp_Tamil, + ucp_Telugu, + ucp_Thaana, + ucp_Thai, + ucp_Tibetan, + ucp_Tifinagh, + ucp_Ugaritic, + ucp_Yi, + /* New for Unicode 5.0: */ + ucp_Balinese, + ucp_Cuneiform, + ucp_Nko, + ucp_Phags_Pa, + ucp_Phoenician, + /* New for Unicode 5.1: */ + ucp_Carian, + ucp_Cham, + ucp_Kayah_Li, + ucp_Lepcha, + ucp_Lycian, + ucp_Lydian, + ucp_Ol_Chiki, + ucp_Rejang, + ucp_Saurashtra, + ucp_Sundanese, + ucp_Vai, + /* New for Unicode 5.2: */ + ucp_Avestan, + ucp_Bamum, + ucp_Egyptian_Hieroglyphs, + ucp_Imperial_Aramaic, + ucp_Inscriptional_Pahlavi, + ucp_Inscriptional_Parthian, + ucp_Javanese, + ucp_Kaithi, + ucp_Lisu, + ucp_Meetei_Mayek, + ucp_Old_South_Arabian, + ucp_Old_Turkic, + ucp_Samaritan, + ucp_Tai_Tham, + 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 + +/* End of ucp.h */ From 201a3003d9abff5196c7fbc91c4c5aae071c15a5 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Sat, 5 Jul 2014 00:32:40 +0200 Subject: [PATCH 02/18] Regex: Update compiled libraries. --- dlls/regex/lib_darwin/libpcre.a | Bin 186312 -> 423288 bytes dlls/regex/lib_linux/libpcre.a | Bin 288906 -> 317868 bytes dlls/regex/lib_linux64/libpcre.a | Bin 233818 -> 0 bytes dlls/regex/lib_win/pcre.lib | Bin 226088 -> 419730 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 dlls/regex/lib_linux64/libpcre.a diff --git a/dlls/regex/lib_darwin/libpcre.a b/dlls/regex/lib_darwin/libpcre.a index f511f0b1ffb3861e7dfd252b62008c873fa39cdc..ac0167bb5aa5856a9200337b59a701e2467893d6 100644 GIT binary patch literal 423288 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

wiO&I02UCS8suV@=SucuUTwBJdi`KHfK)!f= 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

  • `@j(mR>7Nhsa$Vw{=KUP)+->|UOj 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

    A!{B@LlK=di!4oy~6)F=pFdK5^nz2%uN3++=lm- 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 diff --git a/dlls/regex/lib_linux/libpcre.a b/dlls/regex/lib_linux/libpcre.a index e9c1da76eacba2d7c36f802887c604d71e446c56..29b06fce3338b5b5ef3bdf9aaab762fd691c4413 100755 GIT binary patch literal 317868 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

    HJS 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

    C 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 literal 288906 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

    >~Jf-<0e}bRk&yc6dv*cBi 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 Rsn?CxIUgjkb3NOX|1T!Nb~*q6 diff --git a/dlls/regex/lib_linux64/libpcre.a b/dlls/regex/lib_linux64/libpcre.a deleted file mode 100644 index f6f5ae2e6d9be11d155341e0d59b6ec1a31f1e84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 233818 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

    oEIvnrHTnt40|Z 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 Date: Sat, 5 Jul 2014 01:29:57 +0200 Subject: [PATCH 03/18] Regex: Add regex_compile_ex and regex_match_ex natives. Purpose is to use the PCRE flags and error num directly. Harcoding flags letters is really not readable and friendly. Also this makes error params optionnal. --- dlls/regex/CRegEx.cpp | 49 +++++++++++++++ dlls/regex/CRegEx.h | 33 ++++++++++ dlls/regex/module.cpp | 102 +++++++++++++++++++++++++++++- plugins/include/regex.inc | 128 +++++++++++++++++++++++++++++++++++--- 4 files changed, 302 insertions(+), 10 deletions(-) diff --git a/dlls/regex/CRegEx.cpp b/dlls/regex/CRegEx.cpp index 819fb774..efa374c4 100755 --- a/dlls/regex/CRegEx.cpp +++ b/dlls/regex/CRegEx.cpp @@ -1,3 +1,35 @@ +/* AMX Mod X + * Regular Expressions Module + * + * by the AMX Mod X Development Team + * + * This file is part of AMX Mod X. + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + */ #include "pcre.h" #include "CRegEx.h" #include @@ -97,6 +129,23 @@ int RegEx::Compile(const char *pattern, const char* flags) return 1; } +int RegEx::Compile(const char *pattern, int iFlags) +{ + if (!mFree) + Clear(); + + re = pcre_compile(pattern, iFlags, &mError, &mErrorOffset, NULL); + + if (re == NULL) + { + return 0; + } + + mFree = false; + + return 1; +} + int RegEx::Match(const char *str) { int rc = 0; diff --git a/dlls/regex/CRegEx.h b/dlls/regex/CRegEx.h index 542cd27c..498ab929 100755 --- a/dlls/regex/CRegEx.h +++ b/dlls/regex/CRegEx.h @@ -1,3 +1,35 @@ +/* AMX Mod X + * Regular Expressions Module + * + * by the AMX Mod X Development Team + * + * This file is part of AMX Mod X. + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + */ #ifndef _INCLUDE_CREGEX_H #define _INCLUDE_CREGEX_H @@ -10,6 +42,7 @@ public: void Clear(); int Compile(const char *pattern, const char* flags = NULL); + int Compile(const char *pattern, int iFlags); int Match(const char *str); void ClearMatch(); const char *GetSubstring(int s, char buffer[], int max); diff --git a/dlls/regex/module.cpp b/dlls/regex/module.cpp index 411cb62c..48c58bd4 100755 --- a/dlls/regex/module.cpp +++ b/dlls/regex/module.cpp @@ -1,3 +1,35 @@ +/* AMX Mod X +* Regular Expressions Module +* +* by the AMX Mod X Development Team +* +* This file is part of AMX Mod X. +* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +*/ #include #include "pcre.h" #include "amxxmodule.h" @@ -19,6 +51,7 @@ int GetPEL() return (int)PEL.size() - 1; } + // native Regex:regex_compile(const pattern[], &ret, error[], maxLen, const flags[]=""); static cell AMX_NATIVE_CALL regex_compile(AMX *amx, cell *params) { @@ -39,7 +72,30 @@ static cell AMX_NATIVE_CALL regex_compile(AMX *amx, cell *params) } return id+1; -}// 1.8 includes the last parameter +} + +// native Regex:regex_compile_ex(const pattern[], flags = 0, error[] = "", maxLen = 0, &RegexError:errcode = REGEX_ERROR_NONE); +static cell AMX_NATIVE_CALL regex_compile_ex(AMX *amx, cell *params) +{ + int len; + const char *regex = MF_GetAmxString(amx, params[1], 0, &len); + + int id = GetPEL(); + RegEx *x = PEL[id]; + + if (x->Compile(regex, params[2]) == 0) + { + cell *eOff = MF_GetAmxAddr(amx, params[5]); + const char *err = x->mError; + *eOff = x->mErrorOffset; + MF_SetAmxString(amx, params[3], err ? err : "unknown", params[4]); + return -1; + } + + return id + 1; +} + +// 1.8 includes the last parameter // Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); static cell AMX_NATIVE_CALL regex_match(AMX *amx, cell *params) { @@ -86,6 +142,7 @@ static cell AMX_NATIVE_CALL regex_match(AMX *amx, cell *params) return id+1; } + // native regex_match_c(const string[], Regex:id, &ret); static cell AMX_NATIVE_CALL regex_match_c(AMX *amx, cell *params) { @@ -125,6 +182,47 @@ static cell AMX_NATIVE_CALL regex_match_c(AMX *amx, cell *params) } } +// native regex_match_ex(Regex:id, const string[], &RegexError:ret = REGEX_ERROR_NONE); +static cell AMX_NATIVE_CALL regex_match_ex(AMX *amx, cell *params) +{ + int id = params[1] - 1; + + if (id >= (int)PEL.size() || id < 0 || PEL[id]->isFree()) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id); + return 0; + } + + int len; + const char *str = MF_GetAmxString(amx, params[2], 0, &len); + + RegEx *x = PEL[id]; + + int e = x->Match(str); + if (e == -1) + { + /* there was a match error. move on. */ + cell *res = MF_GetAmxAddr(amx, params[3]); + *res = x->mErrorOffset; + + /* only clear the match results, since the regex object + may still be referenced later */ + x->ClearMatch(); + return -2; + } + else if (e == 0) + { + /* only clear the match results, since the regex object + may still be referenced later */ + x->ClearMatch(); + return 0; + } + else + { + return x->mSubStrings; + } +} + static cell AMX_NATIVE_CALL regex_substr(AMX *amx, cell *params) { int id = params[1]-1; @@ -168,8 +266,10 @@ static cell AMX_NATIVE_CALL regex_free(AMX *amx, cell *params) AMX_NATIVE_INFO regex_Natives[] = { {"regex_compile", regex_compile}, + {"regex_compile_ex", regex_compile_ex}, {"regex_match", regex_match}, {"regex_match_c", regex_match_c}, + {"regex_match_ex", regex_match_ex}, {"regex_substr", regex_substr}, {"regex_free", regex_free}, {NULL, NULL}, diff --git a/plugins/include/regex.inc b/plugins/include/regex.inc index c56cfe66..62b616da 100755 --- a/plugins/include/regex.inc +++ b/plugins/include/regex.inc @@ -18,6 +18,7 @@ #pragma library regex #endif + enum Regex { REGEX_MATCH_FAIL = -2, @@ -26,6 +27,70 @@ enum Regex REGEX_OK }; + +/** + * @section Flags for compiling regex expressions. + * These come directly from the pcre library and can be used in MatchRegex and CompileRegex. + * + * @note To be used with regex_compile_ex. + * Only available in 1.8.3 and above. + */ +#define PCRE_CASELESS 0x00000001 /* Ignore Case */ +#define PCRE_MULTILINE 0x00000002 /* Multilines (affects ^ and $ so that they match the start/end of a line rather than matching the start/end of the string). */ +#define PCRE_DOTALL 0x00000004 /* Single line (affects . so that it matches any character, even new line characters). */ +#define PCRE_EXTENDED 0x00000008 /* Pattern extension (ignore whitespace and # comments). */ +#define PCRE_ANCHORED 0x00000010 /* Force pattern anchoring. */ +#define PCRE_DOLLAR_ENDONLY 0x00000020 /* $ not to match newline at end. */ +#define PCRE_UNGREEDY 0x00000200 /* Invert greediness of quantifiers */ +#define PCRE_NOTEMPTY 0x00000400 /* An empty string is not a valid match. */ +#define PCRE_UTF8 0x00000800 /* Use UTF-8 Chars */ +#define PCRE_NO_UTF8_CHECK 0x00002000 /* Do not check the pattern for UTF-8 validity (only relevant if PCRE_UTF8 is set) */ +#define PCRE_UCP 0x20000000 /* Use Unicode properties for \ed, \ew, etc. */ + +/** + * Regex expression error codes. + * + * @note To be used with regex_compile_ex and regex_match_ex natives. + * Only available in 1.8.3 and above. + */ +enum RegexError +{ + REGEX_ERROR_NONE = 0, /* No error */ + REGEX_ERROR_NOMATCH = -1, /* No match was found */ + REGEX_ERROR_NULL = -2, + REGEX_ERROR_BADOPTION = -3, + REGEX_ERROR_BADMAGIC = -4, + REGEX_ERROR_UNKNOWN_OPCODE = -5, + REGEX_ERROR_NOMEMORY = -6, + REGEX_ERROR_NOSUBSTRING = -7, + REGEX_ERROR_MATCHLIMIT = -8, + REGEX_ERROR_CALLOUT = -9, /* Never used by PCRE itself */ + REGEX_ERROR_BADUTF8 = -10, + REGEX_ERROR_BADUTF8_OFFSET = -11, + REGEX_ERROR_PARTIAL = -12, + REGEX_ERROR_BADPARTIAL = -13, + REGEX_ERROR_INTERNAL = -14, + REGEX_ERROR_BADCOUNT = -15, + REGEX_ERROR_DFA_UITEM = -16, + REGEX_ERROR_DFA_UCOND = -17, + REGEX_ERROR_DFA_UMLIMIT = -18, + REGEX_ERROR_DFA_WSSIZE = -19, + REGEX_ERROR_DFA_RECURSE = -20, + REGEX_ERROR_RECURSIONLIMIT = -21, + REGEX_ERROR_NULLWSLIMIT = -22, /* No longer actually used */ + REGEX_ERROR_BADNEWLINE = -23, + REGEX_ERROR_BADOFFSET = -24, + REGEX_ERROR_SHORTUTF8 = -25, + REGEX_ERROR_RECURSELOOP = -26, + REGEX_ERROR_JIT_STACKLIMIT = -27, + REGEX_ERROR_BADMODE = -28, + REGEX_ERROR_BADENDIANNESS = -29, + REGEX_ERROR_DFA_BADRESTART = -30, + REGEX_ERROR_JIT_BADOPTION = -31, + REGEX_ERROR_BADLENGTH = -32, +}; + + /** * Precompile a regular expression. Use this if you intend on using the * same expression multiple times. Pass the regex handle returned here to @@ -72,6 +137,49 @@ native Regex:regex_compile(const pattern[], &ret, error[], maxLen, const flags[] */ native regex_match_c(const string[], Regex:pattern, &ret); +/** + * Precompile a regular expression. + * + * @note Use this if you intend on using the ame expression multiple times. + * Pass the regex handle returned here to regex_match_ex to check for matches. + * + * @note Unlike regex_compile, this allows you to use directly PCRE flags, and + * to get a more complete set of regular expression error codes. + * Only available in 1.8.3 and above. + * + * @param pattern The regular expression pattern. + * @param flags General flags for the regular expression, see PCRE_* defines. + * @param error Error message encountered, if applicable. + * @param maxLen Maximum string length of the error buffer. + * @param errcode Regex type error code encountered, if applicable. + * + * @return Valid regex handle (> 0) on success, or -1 on failure. + */ +native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = 0, &RegexError:errcode = REGEX_ERROR_NONE); + +/** + * Matches a string against a pre-compiled regular expression pattern. + * + * @note Use the regex handle passed to this function to extract + * matches with regex_substr(). + * + * @note You should free the returned handle with regex_free() + * when you are done with this pattern. + * + * @note Unlike regex_match_c(), this allows you to get a more complete + * set of regular expression error codes and parameter is optional. + * Only available in 1.8.3 and above. + * + * @param str The string to check. + * @param regex Regex Handle from regex_compile_ex() + * @param ret Error code, if applicable. + * + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. + */ +native regex_match_ex(Handle:regex, const str[], &RegexError:ret = REGEX_ERROR_NONE); + /** * Matches a string against a regular expression pattern. * @@ -106,29 +214,31 @@ native Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, /** * Returns a matched substring from a regex handle. - * Substring ids start at 0 and end at ret-1, where ret is from the corresponding - * regex_match or regex_match_c function call. + * + * @note Substring ids start at 0 and end at ret - 1, where ret is from the corresponding + * regex_match, regex_match_c or regex_match_ex function call. * * @param id The regex handle to extract data from. * @param str_id The index of the expression to get - starts at 0, and ends at ret - 1. * @param buffer The buffer to set to the matching substring. * @param maxLen The maximum string length of the buffer. * + * @return 1 on success, otherwise 0 on failure. */ native regex_substr(Regex:id, str_id, buffer[], maxLen); /** * Frees the memory associated with a regex result, and sets the handle to 0. - * This must be called on all results from regex_match() when you are done extracting - * the results with regex_substr(). - * The results of regex_compile() (and subsequently, regex_match_c()) only need to be freed - * when you are done using the pattern. + * + * @note This must be called on all results from regex_match() when you are done extracting + * the results with regex_substr(). * + * @note The results of regex_compile() or regex_compile_ex() (and subsequently, regex_match_c() or regex_match_ex()) + * only need to be freed when you are done using the pattern. + * + * @note Do not use the handle again after freeing it! * * @param id The regex handle to free. - * * @noreturn - * - * @note Do not use the handle again after freeing it! */ native regex_free(&Regex:id); From d1153b8049bca682b3541bf9852edb67dc6e3b1e Mon Sep 17 00:00:00 2001 From: Arkshine Date: Sat, 5 Jul 2014 13:51:08 +0200 Subject: [PATCH 04/18] Regex: Update pcre.h. --- dlls/regex/pcre.h | 705 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 550 insertions(+), 155 deletions(-) diff --git a/dlls/regex/pcre.h b/dlls/regex/pcre.h index 52b48033..04477284 100755 --- a/dlls/regex/pcre.h +++ b/dlls/regex/pcre.h @@ -2,25 +2,25 @@ * Perl-Compatible Regular Expressions * *************************************************/ -/* In its original form, this is the .in file that is transformed by -"configure" into pcre.h. +/* This is the public header file for the PCRE library, to be #included by +applications that call the PCRE functions. - Copyright (c) 1997-2005 University of Cambridge +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 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. +* 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. +* 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 @@ -39,34 +39,48 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef _PCRE_H #define _PCRE_H -/* The file pcre.h is build by "configure". Do not edit it; instead -make changes to pcre.in. */ +/* The current PCRE version information. */ -#define PCRE_MAJOR 6 -#define PCRE_MINOR 4 -#define PCRE_DATE 05-Sep-2005 +#define PCRE_MAJOR 8 +#define PCRE_MINOR 32 +#define PCRE_PRERELEASE +#define PCRE_DATE 2012-11-30 -/* Win32 uses DLL by default; it needs special stuff for exported functions. */ +/* 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 +export setting is defined in pcre_internal.h, which includes this file. So we +don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ -#ifdef _WIN32 -# ifdef PCRE_DEFINITION -# ifdef DLL_EXPORT -# define PCRE_DATA_SCOPE __declspec(dllexport) +#if defined(_WIN32) && !defined(PCRE_STATIC) +# ifndef PCRE_EXP_DECL +# define PCRE_EXP_DECL extern __declspec(dllimport) +# endif +# ifdef __cplusplus +# ifndef PCRECPP_EXP_DECL +# define PCRECPP_EXP_DECL extern __declspec(dllimport) # endif -# else -# ifndef PCRE_STATIC -# define PCRE_DATA_SCOPE extern __declspec(dllimport) +# ifndef PCRECPP_EXP_DEFN +# define PCRECPP_EXP_DEFN __declspec(dllimport) # endif # endif #endif -/* For other operating systems, we use the standard "extern". */ +/* By default, we use the standard "extern" declarations. */ -#ifndef PCRE_DATA_SCOPE +#ifndef PCRE_EXP_DECL # ifdef __cplusplus -# define PCRE_DATA_SCOPE extern "C" +# define PCRE_EXP_DECL extern "C" # else -# define PCRE_DATA_SCOPE extern +# define PCRE_EXP_DECL extern +# endif +#endif + +#ifdef __cplusplus +# ifndef PCRECPP_EXP_DECL +# define PCRECPP_EXP_DECL extern +# endif +# ifndef PCRECPP_EXP_DEFN +# define PCRECPP_EXP_DEFN # endif #endif @@ -81,52 +95,153 @@ it is needed here for malloc. */ extern "C" { #endif -/* Options */ + /* Public options. Some are compile-time only, some are run-time only, and some + are both, so we keep them all distinct. However, almost all the bits in the + options word are now used. In the long run, we may have to re-use some of the + compile-time only bits for runtime options, or vice versa. Any of the + compile-time options may be inspected during studying (and therefore JIT + compiling). -#define PCRE_CASELESS 0x00000001 -#define PCRE_MULTILINE 0x00000002 -#define PCRE_DOTALL 0x00000004 -#define PCRE_EXTENDED 0x00000008 -#define PCRE_ANCHORED 0x00000010 -#define PCRE_DOLLAR_ENDONLY 0x00000020 -#define PCRE_EXTRA 0x00000040 -#define PCRE_NOTBOL 0x00000080 -#define PCRE_NOTEOL 0x00000100 -#define PCRE_UNGREEDY 0x00000200 -#define PCRE_NOTEMPTY 0x00000400 -#define PCRE_UTF8 0x00000800 -#define PCRE_NO_AUTO_CAPTURE 0x00001000 -#define PCRE_NO_UTF8_CHECK 0x00002000 -#define PCRE_AUTO_CALLOUT 0x00004000 -#define PCRE_PARTIAL 0x00008000 -#define PCRE_DFA_SHORTEST 0x00010000 -#define PCRE_DFA_RESTART 0x00020000 -#define PCRE_FIRSTLINE 0x00040000 + Some options for pcre_compile() change its behaviour but do not affect the + behaviour of the execution functions. Other options are passed through to the + execution functions and affect their behaviour, with or without affecting the + behaviour of pcre_compile(). -/* Exec-time and get/set-time error codes */ + Options that can be passed to pcre_compile() are tagged Cx below, with these + variants: -#define PCRE_ERROR_NOMATCH (-1) -#define PCRE_ERROR_NULL (-2) -#define PCRE_ERROR_BADOPTION (-3) -#define PCRE_ERROR_BADMAGIC (-4) -#define PCRE_ERROR_UNKNOWN_NODE (-5) -#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) + C1 Affects compile only + C2 Does not affect compile; affects exec, dfa_exec + C3 Affects compile, exec, dfa_exec + C4 Affects compile, exec, dfa_exec, study + C5 Affects compile, exec, study -/* Request types for pcre_fullinfo() */ + Options that can be set for pcre_exec() and/or pcre_dfa_exec() are flagged with + E and D, respectively. They take precedence over C3, C4, and C5 settings passed + from pcre_compile(). Those that are compatible with JIT execution are flagged + with J. */ + +#define PCRE_CASELESS 0x00000001 /* C1 */ +#define PCRE_MULTILINE 0x00000002 /* C1 */ +#define PCRE_DOTALL 0x00000004 /* C1 */ +#define PCRE_EXTENDED 0x00000008 /* C1 */ +#define PCRE_ANCHORED 0x00000010 /* C4 E D */ +#define PCRE_DOLLAR_ENDONLY 0x00000020 /* C2 */ +#define PCRE_EXTRA 0x00000040 /* C1 */ +#define PCRE_NOTBOL 0x00000080 /* E D J */ +#define PCRE_NOTEOL 0x00000100 /* E D J */ +#define PCRE_UNGREEDY 0x00000200 /* C1 */ +#define PCRE_NOTEMPTY 0x00000400 /* E D J */ +#define PCRE_UTF8 0x00000800 /* C4 ) */ +#define PCRE_UTF16 0x00000800 /* C4 ) Synonyms */ +#define PCRE_UTF32 0x00000800 /* C4 ) */ +#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* C1 */ +#define PCRE_NO_UTF8_CHECK 0x00002000 /* C1 E D J ) */ +#define PCRE_NO_UTF16_CHECK 0x00002000 /* C1 E D J ) Synonyms */ +#define PCRE_NO_UTF32_CHECK 0x00002000 /* C1 E D J ) */ +#define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */ +#define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */ +#define PCRE_PARTIAL 0x00008000 /* E D J ) */ +#define PCRE_DFA_SHORTEST 0x00010000 /* D */ +#define PCRE_DFA_RESTART 0x00020000 /* D */ +#define PCRE_FIRSTLINE 0x00040000 /* C3 */ +#define PCRE_DUPNAMES 0x00080000 /* C1 */ +#define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */ +#define PCRE_NEWLINE_LF 0x00200000 /* C3 E D */ +#define PCRE_NEWLINE_CRLF 0x00300000 /* C3 E D */ +#define PCRE_NEWLINE_ANY 0x00400000 /* C3 E D */ +#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* C3 E D */ +#define PCRE_BSR_ANYCRLF 0x00800000 /* C3 E D */ +#define PCRE_BSR_UNICODE 0x01000000 /* C3 E D */ +#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* C5 */ +#define PCRE_NO_START_OPTIMIZE 0x04000000 /* C2 E D ) Synonyms */ +#define PCRE_NO_START_OPTIMISE 0x04000000 /* C2 E D ) */ +#define PCRE_PARTIAL_HARD 0x08000000 /* E D J */ +#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* E D J */ +#define PCRE_UCP 0x20000000 /* C3 */ + + /* 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) /* Same for 8/16/32 */ +#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16/32 */ +#define PCRE_ERROR_BADUTF32 (-10) /* Same for 8/16/32 */ +#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) +#define PCRE_ERROR_JIT_BADOPTION (-31) +#define PCRE_ERROR_BADLENGTH (-32) + + /* 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 +#define PCRE_UTF8_ERR22 22 + + /* 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 + + /* Specific error codes for UTF-32 validity checks */ + +#define PCRE_UTF32_ERR0 0 +#define PCRE_UTF32_ERR1 1 +#define PCRE_UTF32_ERR2 2 +#define PCRE_UTF32_ERR3 3 + + /* Request types for pcre_fullinfo() */ #define PCRE_INFO_OPTIONS 0 #define PCRE_INFO_SIZE 1 @@ -141,8 +256,20 @@ extern "C" { #define PCRE_INFO_NAMETABLE 9 #define PCRE_INFO_STUDYSIZE 10 #define PCRE_INFO_DEFAULT_TABLES 11 +#define PCRE_INFO_OKPARTIAL 12 +#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 +#define PCRE_INFO_FIRSTCHARACTER 19 +#define PCRE_INFO_FIRSTCHARACTERFLAGS 20 +#define PCRE_INFO_REQUIREDCHAR 21 +#define PCRE_INFO_REQUIREDCHARFLAGS 22 -/* Request types for pcre_config() */ + /* Request types for pcre_config(). Do not re-arrange, in order to remain + compatible. */ #define PCRE_CONFIG_UTF8 0 #define PCRE_CONFIG_NEWLINE 1 @@ -151,105 +278,373 @@ extern "C" { #define PCRE_CONFIG_MATCH_LIMIT 4 #define PCRE_CONFIG_STACKRECURSE 5 #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 +#define PCRE_CONFIG_UTF32 12 -/* Bit flags for the pcre_extra structure */ + /* Request types for pcre_study(). Do not re-arrange, in order to remain + compatible. */ -#define PCRE_EXTRA_STUDY_DATA 0x0001 -#define PCRE_EXTRA_MATCH_LIMIT 0x0002 -#define PCRE_EXTRA_CALLOUT_DATA 0x0004 -#define PCRE_EXTRA_TABLES 0x0008 +#define PCRE_STUDY_JIT_COMPILE 0x0001 +#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002 +#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004 +#define PCRE_STUDY_EXTRA_NEEDED 0x0008 -/* Types */ + /* Bit flags for the pcre[16|32]_extra structure. Do not re-arrange or redefine + these bits, just add new ones on the end, in order to remain compatible. */ -struct real_pcre; /* declaration; the definition is private */ -typedef struct real_pcre pcre; +#define PCRE_EXTRA_STUDY_DATA 0x0001 +#define PCRE_EXTRA_MATCH_LIMIT 0x0002 +#define PCRE_EXTRA_CALLOUT_DATA 0x0004 +#define PCRE_EXTRA_TABLES 0x0008 +#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 +#define PCRE_EXTRA_MARK 0x0020 +#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040 -/* The structure for passing additional data to pcre_exec(). This is defined in -such as way as to be extensible. Always add new fields at the end, in order to -remain compatible. */ + /* Types */ -typedef struct pcre_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 */ -} pcre_extra; + struct real_pcre; /* declaration; the definition is private */ + typedef struct real_pcre pcre; -/* 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 -without modification. */ + struct real_pcre16; /* declaration; the definition is private */ + typedef struct real_pcre16 pcre16; -typedef struct pcre_callout_block { - int version; /* Identifies version of block */ - /* ------------------------ Version 0 ------------------------------- */ - int callout_number; /* Number compiled into pattern */ - int *offset_vector; /* The offset vector */ - const char *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 */ - /* ------------------------------------------------------------------ */ -} pcre_callout_block; + struct real_pcre32; /* declaration; the definition is private */ + typedef struct real_pcre32 pcre32; -/* 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 -that is triggered by the (?) regex item. For Virtual Pascal, these definitions -have to take another form. */ + 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; + + struct real_pcre32_jit_stack; /* declaration; the definition is private */ + typedef struct real_pcre32_jit_stack pcre32_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 + + /* If PCRE is compiled with 32 bit character support, PCRE_UCHAR32 must contain + a 32 bit wide signed data type. Otherwise it can be a dummy data type since + pcre32 functions are not implemented. There is a check for this in pcre_internal.h. */ +#ifndef PCRE_UCHAR32 +#define PCRE_UCHAR32 unsigned int +#endif + +#ifndef PCRE_SPTR32 +#define PCRE_SPTR32 const PCRE_UCHAR32 * +#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 *. */ + +#ifndef PCRE_SPTR +#define PCRE_SPTR const char * +#endif + + /* The structure for passing additional data to pcre_exec(). This is defined in + such as way as to be extensible. Always add new fields at the end, in order to + remain compatible. */ + + typedef struct pcre_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() */ + 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; + + /* Same structure as above, but with 32 bit char pointers. */ + + typedef struct pcre32_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_UCHAR32 **mark; /* For passing back a mark pointer */ + void *executable_jit; /* Contains a pointer to a compiled jit code */ + } pcre32_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 + without modification. */ + + typedef struct pcre_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + PCRE_SPTR 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 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; + + /* Same structure as above, but with 32 bit char pointers. */ + + typedef struct pcre32_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + PCRE_SPTR32 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_UCHAR32 *mark; /* Pointer to current mark or NULL */ + /* ------------------------------------------------------------------ */ + } pcre32_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 + that is triggered by the (?) regex item. For Virtual Pascal, these definitions + have to take another form. */ #ifndef VPCOMPAT -PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t); -PCRE_DATA_SCOPE void (*pcre_free)(void *); -PCRE_DATA_SCOPE void *(*pcre_stack_malloc)(size_t); -PCRE_DATA_SCOPE void (*pcre_stack_free)(void *); -PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *); + 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 *); + + PCRE_EXP_DECL void *(*pcre32_malloc)(size_t); + PCRE_EXP_DECL void(*pcre32_free)(void *); + PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t); + PCRE_EXP_DECL void(*pcre32_stack_free)(void *); + PCRE_EXP_DECL int(*pcre32_callout)(pcre32_callout_block *); #else /* VPCOMPAT */ -PCRE_DATA_SCOPE void *pcre_malloc(size_t); -PCRE_DATA_SCOPE void pcre_free(void *); -PCRE_DATA_SCOPE void *pcre_stack_malloc(size_t); -PCRE_DATA_SCOPE void pcre_stack_free(void *); -PCRE_DATA_SCOPE int pcre_callout(pcre_callout_block *); + 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 *); + + PCRE_EXP_DECL void *pcre32_malloc(size_t); + PCRE_EXP_DECL void pcre32_free(void *); + PCRE_EXP_DECL void *pcre32_stack_malloc(size_t); + PCRE_EXP_DECL void pcre32_stack_free(void *); + PCRE_EXP_DECL int pcre32_callout(pcre32_callout_block *); #endif /* VPCOMPAT */ -/* Exported PCRE functions */ + /* User defined callback which provides a stack just before the match starts. */ -PCRE_DATA_SCOPE pcre *pcre_compile(const char *, int, const char **, int *, - const unsigned char *); -PCRE_DATA_SCOPE pcre *pcre_compile2(const char *, int, int *, const char **, - int *, const unsigned char *); -PCRE_DATA_SCOPE int pcre_config(int, void *); -PCRE_DATA_SCOPE int pcre_copy_named_substring(const pcre *, const char *, - int *, int, const char *, char *, int); -PCRE_DATA_SCOPE int pcre_copy_substring(const char *, int *, int, int, char *, - int); -PCRE_DATA_SCOPE int pcre_dfa_exec(const pcre *, const pcre_extra *, - const char *, int, int, int, int *, int , int *, int); -PCRE_DATA_SCOPE int pcre_exec(const pcre *, const pcre_extra *, const char *, - int, int, int, int *, int); -PCRE_DATA_SCOPE void pcre_free_substring(const char *); -PCRE_DATA_SCOPE void pcre_free_substring_list(const char **); -PCRE_DATA_SCOPE int pcre_fullinfo(const pcre *, const pcre_extra *, int, - void *); -PCRE_DATA_SCOPE int pcre_get_named_substring(const pcre *, const char *, - int *, int, const char *, const char **); -PCRE_DATA_SCOPE int pcre_get_stringnumber(const pcre *, const char *); -PCRE_DATA_SCOPE int pcre_get_substring(const char *, int *, int, int, - const char **); -PCRE_DATA_SCOPE int pcre_get_substring_list(const char *, int *, int, - const char ***); -PCRE_DATA_SCOPE int pcre_info(const pcre *, int *, int *); -PCRE_DATA_SCOPE const unsigned char *pcre_maketables(void); -PCRE_DATA_SCOPE int pcre_refcount(pcre *, int); -PCRE_DATA_SCOPE pcre_extra *pcre_study(const pcre *, int, const char **); -PCRE_DATA_SCOPE const char *pcre_version(void); + typedef pcre_jit_stack *(*pcre_jit_callback)(void *); + typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *); + typedef pcre32_jit_stack *(*pcre32_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 pcre32 *pcre32_compile(PCRE_SPTR32, 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 pcre32 *pcre32_compile2(PCRE_SPTR32, 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 pcre32_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 pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16, + int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int); + PCRE_EXP_DECL int pcre32_copy_named_substring(const pcre32 *, PCRE_SPTR32, + int *, int, PCRE_SPTR32, PCRE_UCHAR32 *, 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 pcre32_copy_substring(PCRE_SPTR32, int *, int, int, + PCRE_UCHAR32 *, 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 pcre32_dfa_exec(const pcre32 *, const pcre32_extra *, + PCRE_SPTR32, 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 int pcre32_exec(const pcre32 *, const pcre32_extra *, + PCRE_SPTR32, int, int, int, int *, int); + PCRE_EXP_DECL int pcre_jit_exec(const pcre *, const pcre_extra *, + PCRE_SPTR, int, int, int, int *, int, + pcre_jit_stack *); + PCRE_EXP_DECL int pcre16_jit_exec(const pcre16 *, const pcre16_extra *, + PCRE_SPTR16, int, int, int, int *, int, + pcre16_jit_stack *); + PCRE_EXP_DECL int pcre32_jit_exec(const pcre32 *, const pcre32_extra *, + PCRE_SPTR32, int, int, int, int *, int, + pcre32_jit_stack *); + PCRE_EXP_DECL void pcre_free_substring(const char *); + PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16); + PCRE_EXP_DECL void pcre32_free_substring(PCRE_SPTR32); + PCRE_EXP_DECL void pcre_free_substring_list(const char **); + PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *); + PCRE_EXP_DECL void pcre32_free_substring_list(PCRE_SPTR32 *); + 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 pcre32_fullinfo(const pcre32 *, const pcre32_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 pcre32_get_named_substring(const pcre32 *, PCRE_SPTR32, + int *, int, PCRE_SPTR32, PCRE_SPTR32 *); + 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 pcre32_get_stringnumber(const pcre32 *, PCRE_SPTR32); + 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 pcre32_get_stringtable_entries(const pcre32 *, PCRE_SPTR32, + PCRE_UCHAR32 **, PCRE_UCHAR32 **); + 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 pcre32_get_substring(PCRE_SPTR32, int *, int, int, + PCRE_SPTR32 *); + PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, + const char ***); + PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int, + PCRE_SPTR16 **); + PCRE_EXP_DECL int pcre32_get_substring_list(PCRE_SPTR32, int *, int, + PCRE_SPTR32 **); + PCRE_EXP_DECL const unsigned char *pcre_maketables(void); + PCRE_EXP_DECL const unsigned char *pcre16_maketables(void); + PCRE_EXP_DECL const unsigned char *pcre32_maketables(void); + PCRE_EXP_DECL int pcre_refcount(pcre *, int); + PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int); + PCRE_EXP_DECL int pcre32_refcount(pcre32 *, 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 pcre32_extra *pcre32_study(const pcre32 *, int, const char **); + PCRE_EXP_DECL void pcre_free_study(pcre_extra *); + PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *); + PCRE_EXP_DECL void pcre32_free_study(pcre32_extra *); + PCRE_EXP_DECL const char *pcre_version(void); + PCRE_EXP_DECL const char *pcre16_version(void); + PCRE_EXP_DECL const char *pcre32_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 pcre32_pattern_to_host_byte_order(pcre32 *, pcre32_extra *, + const unsigned char *); + PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *, + PCRE_SPTR16, int, int *, int); + PCRE_EXP_DECL int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *, + PCRE_SPTR32, 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 pcre32_jit_stack *pcre32_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 pcre32_jit_stack_free(pcre32_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 *); + PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *, + pcre32_jit_callback, void *); #ifdef __cplusplus } /* extern "C" */ From d4de0e6f1e922720dcc36da25e7fca3ddac9da8b Mon Sep 17 00:00:00 2001 From: Arkshine Date: Sat, 5 Jul 2014 13:53:30 +0200 Subject: [PATCH 05/18] Regex: Update PCRE to v8.35. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I was über lazy at first, so took libs from SM. But actually it's quite easy to compile, so let's update to latest version \o/. --- tools/pcre/132html | 8 +- tools/pcre/AUTHORS | 6 +- tools/pcre/CMakeLists.txt | 58 +- tools/pcre/ChangeLog | 500 +- tools/pcre/CheckMan | 4 +- tools/pcre/HACKING | 269 +- tools/pcre/INSTALL | 12 +- tools/pcre/LICENCE | 6 +- tools/pcre/Makefile.am | 57 +- tools/pcre/Makefile.in | 870 +- tools/pcre/NEWS | 84 +- tools/pcre/NON-AUTOTOOLS-BUILD | 217 +- tools/pcre/PrepareRelease | 11 +- tools/pcre/README | 132 +- tools/pcre/RunGrepTest | 690 +- tools/pcre/RunTest | 197 +- tools/pcre/RunTest.bat | 2 +- tools/pcre/aclocal.m4 | 769 +- tools/pcre/ar-lib | 270 + tools/pcre/compile | 10 +- tools/pcre/config-cmake.h.in | 3 + tools/pcre/config.guess | 100 +- tools/pcre/config.h.generic | 154 +- tools/pcre/config.h.in | 47 +- tools/pcre/config.sub | 111 +- tools/pcre/configure | 2144 +++- tools/pcre/configure.ac | 91 +- tools/pcre/depcomp | 457 +- tools/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt | 764 ++ tools/pcre/doc/html/README.txt | 991 ++ tools/pcre/doc/html/index.html | 27 +- tools/pcre/doc/html/pcre-config.html | 4 +- tools/pcre/doc/html/pcre.html | 39 +- tools/pcre/doc/html/pcre16.html | 167 +- tools/pcre/doc/html/pcre32.html | 382 + .../pcre/doc/html/pcre_assign_jit_stack.html | 14 +- tools/pcre/doc/html/pcre_compile.html | 23 +- tools/pcre/doc/html/pcre_compile2.html | 29 +- tools/pcre/doc/html/pcre_config.html | 1 + .../doc/html/pcre_copy_named_substring.html | 26 +- tools/pcre/doc/html/pcre_copy_substring.html | 20 +- tools/pcre/doc/html/pcre_dfa_exec.html | 35 +- tools/pcre/doc/html/pcre_exec.html | 29 +- tools/pcre/doc/html/pcre_fullinfo.html | 14 +- .../doc/html/pcre_get_named_substring.html | 26 +- .../pcre/doc/html/pcre_get_stringnumber.html | 14 +- .../html/pcre_get_stringtable_entries.html | 14 +- tools/pcre/doc/html/pcre_get_substring.html | 20 +- .../doc/html/pcre_get_substring_list.html | 14 +- tools/pcre/doc/html/pcre_jit_exec.html | 26 +- tools/pcre/doc/html/pcre_jit_stack_alloc.html | 14 +- .../html/pcre_pattern_to_host_byte_order.html | 14 +- tools/pcre/doc/html/pcre_study.html | 14 +- .../html/pcre_utf16_to_host_byte_order.html | 4 +- .../html/pcre_utf32_to_host_byte_order.html | 57 + tools/pcre/doc/html/pcreapi.html | 728 +- tools/pcre/doc/html/pcrebuild.html | 143 +- tools/pcre/doc/html/pcrecallout.html | 103 +- tools/pcre/doc/html/pcrecompat.html | 63 +- tools/pcre/doc/html/pcregrep.html | 8 +- tools/pcre/doc/html/pcrejit.html | 16 +- tools/pcre/doc/html/pcrelimits.html | 18 +- tools/pcre/doc/html/pcrematching.html | 11 +- tools/pcre/doc/html/pcrepartial.html | 91 +- tools/pcre/doc/html/pcrepattern.html | 836 +- tools/pcre/doc/html/pcreposix.html | 22 +- tools/pcre/doc/html/pcreprecompile.html | 19 +- tools/pcre/doc/html/pcresyntax.html | 105 +- tools/pcre/doc/html/pcretest.html | 204 +- tools/pcre/doc/html/pcreunicode.html | 20 +- tools/pcre/doc/index.html.src | 27 +- tools/pcre/doc/pcre-config.1 | 8 +- tools/pcre/doc/pcre-config.txt | 6 +- tools/pcre/doc/pcre.3 | 48 +- tools/pcre/doc/pcre.txt | 4030 +++--- tools/pcre/doc/pcre16.3 | 159 +- tools/pcre/doc/pcre32.3 | 158 +- tools/pcre/doc/pcre_assign_jit_stack.3 | 16 +- tools/pcre/doc/pcre_compile.3 | 30 +- tools/pcre/doc/pcre_compile2.3 | 39 +- tools/pcre/doc/pcre_config.3 | 3 +- tools/pcre/doc/pcre_copy_named_substring.3 | 34 +- tools/pcre/doc/pcre_copy_substring.3 | 25 +- tools/pcre/doc/pcre_dfa_exec.3 | 45 +- tools/pcre/doc/pcre_exec.3 | 36 +- tools/pcre/doc/pcre_fullinfo.3 | 16 +- tools/pcre/doc/pcre_get_named_substring.3 | 34 +- tools/pcre/doc/pcre_get_stringnumber.3 | 16 +- tools/pcre/doc/pcre_get_stringtable_entries.3 | 16 +- tools/pcre/doc/pcre_get_substring.3 | 25 +- tools/pcre/doc/pcre_get_substring_list.3 | 16 +- tools/pcre/doc/pcre_jit_exec.3 | 34 +- tools/pcre/doc/pcre_jit_stack_alloc.3 | 16 +- .../doc/pcre_pattern_to_host_byte_order.3 | 16 +- tools/pcre/doc/pcre_study.3 | 16 +- .../pcre/doc/pcre_utf16_to_host_byte_order.3 | 9 +- .../pcre/doc/pcre_utf32_to_host_byte_order.3 | 9 +- tools/pcre/doc/pcreapi.3 | 722 +- tools/pcre/doc/pcrebuild.3 | 66 +- tools/pcre/doc/pcrecallout.3 | 103 +- tools/pcre/doc/pcrecompat.3 | 61 +- tools/pcre/doc/pcredemo.3 | 424 + tools/pcre/doc/pcregrep.1 | 12 +- tools/pcre/doc/pcregrep.txt | 713 +- tools/pcre/doc/pcrejit.3 | 18 +- tools/pcre/doc/pcrelimits.3 | 20 +- tools/pcre/doc/pcrematching.3 | 12 +- tools/pcre/doc/pcrepartial.3 | 89 +- tools/pcre/doc/pcrepattern.3 | 750 +- tools/pcre/doc/pcreposix.3 | 21 +- tools/pcre/doc/pcreprecompile.3 | 20 +- tools/pcre/doc/pcresyntax.3 | 85 +- tools/pcre/doc/pcretest.1 | 145 +- tools/pcre/doc/pcretest.txt | 239 +- tools/pcre/doc/pcreunicode.3 | 20 +- tools/pcre/install-sh | 14 +- tools/pcre/ltmain.sh | 95 +- tools/pcre/m4/libtool.m4 | 280 +- tools/pcre/m4/ltoptions.m4 | 19 +- tools/pcre/m4/ltversion.m4 | 10 +- tools/pcre/m4/pcre_visibility.m4 | 2 +- tools/pcre/makevp_c.txt | 3 +- tools/pcre/makevp_l.txt | 3 +- tools/pcre/missing | 412 +- tools/pcre/pcre.h.generic | 56 +- tools/pcre/pcre.h.in | 52 +- tools/pcre/pcre16_valid_utf16.c | 25 +- tools/pcre/pcre32_valid_utf32.c | 13 +- tools/pcre/pcre_byte_order.c | 23 +- tools/pcre/pcre_chartables.c.dist | 2 +- tools/pcre/pcre_compile.c | 3732 ++++-- tools/pcre/pcre_config.c | 4 + tools/pcre/pcre_dfa_exec.c | 297 +- tools/pcre/pcre_exec.c | 1057 +- tools/pcre/pcre_fullinfo.c | 16 +- tools/pcre/pcre_globals.c | 4 +- tools/pcre/pcre_internal.h | 559 +- tools/pcre/pcre_jit_compile.c | 5325 +++++--- tools/pcre/pcre_jit_test.c | 175 +- tools/pcre/pcre_maketables.c | 27 +- tools/pcre/pcre_printint.c | 116 +- tools/pcre/pcre_string_utils.c | 14 +- tools/pcre/pcre_study.c | 156 +- tools/pcre/pcre_tables.c | 15 +- tools/pcre/pcre_ucd.c | 771 +- tools/pcre/pcre_valid_utf8.c | 15 +- tools/pcre/pcre_xclass.c | 106 +- tools/pcre/pcregrep.c | 155 +- tools/pcre/pcreposix.c | 16 +- tools/pcre/pcretest.c | 451 +- tools/pcre/perltest.pl | 27 +- tools/pcre/sljit/sljitConfig.h | 12 +- tools/pcre/sljit/sljitConfigInternal.h | 59 +- tools/pcre/sljit/sljitExecAllocator.c | 23 + tools/pcre/sljit/sljitLir.c | 266 +- tools/pcre/sljit/sljitLir.h | 80 +- tools/pcre/sljit/sljitNativeARM_32.c | 2524 ++++ tools/pcre/sljit/sljitNativeARM_64.c | 1902 +++ tools/pcre/sljit/sljitNativeARM_T2_32.c | 2007 +++ tools/pcre/sljit/sljitNativeMIPS_32.c | 122 +- tools/pcre/sljit/sljitNativeMIPS_64.c | 469 + tools/pcre/sljit/sljitNativeMIPS_common.c | 331 +- tools/pcre/sljit/sljitNativePPC_32.c | 2 +- tools/pcre/sljit/sljitNativePPC_64.c | 4 +- tools/pcre/sljit/sljitNativePPC_common.c | 624 +- tools/pcre/sljit/sljitNativeSPARC_common.c | 123 +- tools/pcre/sljit/sljitNativeTILEGX-encoder.c | 10159 ++++++++++++++++ tools/pcre/sljit/sljitNativeTILEGX_64.c | 2580 ++++ tools/pcre/sljit/sljitNativeX86_32.c | 50 +- tools/pcre/sljit/sljitNativeX86_64.c | 50 +- tools/pcre/sljit/sljitNativeX86_common.c | 515 +- tools/pcre/sljit/sljitUtils.c | 8 +- tools/pcre/test-driver | 139 + tools/pcre/testdata/grepoutput | 38 + tools/pcre/testdata/saved16 | Bin 70 -> 86 bytes tools/pcre/testdata/saved16BE-1 | Bin 402 -> 418 bytes tools/pcre/testdata/saved16BE-2 | Bin 336 -> 344 bytes tools/pcre/testdata/saved16LE-1 | Bin 402 -> 418 bytes tools/pcre/testdata/saved16LE-2 | Bin 336 -> 344 bytes tools/pcre/testdata/saved32 | Bin 100 -> 108 bytes tools/pcre/testdata/saved32BE-1 | Bin 544 -> 560 bytes tools/pcre/testdata/saved32BE-2 | Bin 448 -> 456 bytes tools/pcre/testdata/saved32LE-1 | Bin 544 -> 560 bytes tools/pcre/testdata/saved32LE-2 | Bin 448 -> 456 bytes tools/pcre/testdata/saved8 | Bin 61 -> 77 bytes tools/pcre/testdata/testinput1 | 467 +- tools/pcre/testdata/testinput10 | 108 +- tools/pcre/testdata/testinput12 | 9 +- tools/pcre/testdata/testinput14 | 20 +- tools/pcre/testdata/testinput15 | 82 +- tools/pcre/testdata/testinput17 | 11 + tools/pcre/testdata/testinput18 | 14 +- tools/pcre/testdata/testinput2 | 472 +- tools/pcre/testdata/testinput21 | 16 +- tools/pcre/testdata/testinput22 | 12 +- tools/pcre/testdata/testinput23 | 4 + tools/pcre/testdata/testinput24 | 68 +- tools/pcre/testdata/testinput25 | 12 + tools/pcre/testdata/testinput26 | 74 +- tools/pcre/testdata/testinput3 | 11 +- tools/pcre/testdata/testinput4 | 101 + tools/pcre/testdata/testinput5 | 21 + tools/pcre/testdata/testinput6 | 189 +- tools/pcre/testdata/testinput7 | 172 +- tools/pcre/testdata/testinput8 | 89 +- tools/pcre/testdata/testinput9 | 24 +- tools/pcre/testdata/testoutput1 | 676 +- tools/pcre/testdata/testoutput10 | 579 +- tools/pcre/testdata/testoutput11-16 | 29 +- tools/pcre/testdata/testoutput11-32 | 29 +- tools/pcre/testdata/testoutput11-8 | 29 +- tools/pcre/testdata/testoutput12 | 46 +- tools/pcre/testdata/testoutput13 | 3 +- tools/pcre/testdata/testoutput14 | 72 +- tools/pcre/testdata/testoutput15 | 202 +- tools/pcre/testdata/testoutput16 | 8 +- tools/pcre/testdata/testoutput17 | 81 +- tools/pcre/testdata/testoutput18-16 | 74 +- tools/pcre/testdata/testoutput18-32 | 76 +- tools/pcre/testdata/testoutput19 | 2 +- tools/pcre/testdata/testoutput2 | 2330 +++- tools/pcre/testdata/testoutput20 | 3 - tools/pcre/testdata/testoutput21-16 | 24 +- tools/pcre/testdata/testoutput21-32 | 24 +- tools/pcre/testdata/testoutput22-16 | 20 +- tools/pcre/testdata/testoutput22-32 | 20 +- tools/pcre/testdata/testoutput23 | 40 +- tools/pcre/testdata/testoutput24 | 134 +- tools/pcre/testdata/testoutput25 | 48 +- tools/pcre/testdata/testoutput26 | 143 +- tools/pcre/testdata/testoutput3 | 15 +- tools/pcre/testdata/testoutput3A | 174 + tools/pcre/testdata/testoutput3B | 174 + tools/pcre/testdata/testoutput4 | 180 + tools/pcre/testdata/testoutput5 | 95 +- tools/pcre/testdata/testoutput6 | 351 +- tools/pcre/testdata/testoutput7 | 863 +- tools/pcre/testdata/testoutput8 | 453 +- tools/pcre/testdata/testoutput9 | 114 +- tools/pcre/testdata/wintestoutput3 | 4 +- tools/pcre/ucp.h | 5 +- 241 files changed, 51074 insertions(+), 15011 deletions(-) create mode 100644 tools/pcre/ar-lib create mode 100644 tools/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt create mode 100644 tools/pcre/doc/html/README.txt create mode 100644 tools/pcre/doc/html/pcre32.html create mode 100644 tools/pcre/doc/html/pcre_utf32_to_host_byte_order.html create mode 100644 tools/pcre/doc/pcredemo.3 create mode 100644 tools/pcre/sljit/sljitNativeARM_32.c create mode 100644 tools/pcre/sljit/sljitNativeARM_64.c create mode 100644 tools/pcre/sljit/sljitNativeARM_T2_32.c create mode 100644 tools/pcre/sljit/sljitNativeMIPS_64.c create mode 100644 tools/pcre/sljit/sljitNativeTILEGX-encoder.c create mode 100644 tools/pcre/sljit/sljitNativeTILEGX_64.c create mode 100644 tools/pcre/test-driver create mode 100644 tools/pcre/testdata/testoutput3A create mode 100644 tools/pcre/testdata/testoutput3B diff --git a/tools/pcre/132html b/tools/pcre/132html index ccfbfd91..e1b70cd9 100644 --- a/tools/pcre/132html +++ b/tools/pcre/132html @@ -108,9 +108,9 @@ while () # Handling .sp is subtle. If it is inside a literal section, do nothing if # the next line is a non literal text line; similarly, if not inside a - # literal section, do nothing if a literal follows. The point being that - # the

     and 
    that delimit literal sections will do the spacing. - # Always skip if no previous output. + # literal section, do nothing if a literal follows, unless we are inside + # a .nf/.ne section. The point being that the
     and 
    that delimit + # literal sections will do the spacing. Always skip if no previous output. elsif (/^\.sp/) { @@ -123,7 +123,7 @@ while () } else { - print TEMP "
    \n
    \n" if (!/^[\s.]/); + print TEMP "
    \n
    \n" if ($innf || !/^[\s.]/); } redo; # Now process the lookahead line we just read } diff --git a/tools/pcre/AUTHORS b/tools/pcre/AUTHORS index ba4753d8..5eee1af4 100644 --- a/tools/pcre/AUTHORS +++ b/tools/pcre/AUTHORS @@ -8,7 +8,7 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2012 University of Cambridge +Copyright (c) 1997-2014 University of Cambridge All rights reserved @@ -19,7 +19,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2010-2012 Zoltan Herczeg +Copyright(c) 2010-2014 Zoltan Herczeg All rights reserved. @@ -30,7 +30,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2009-2012 Zoltan Herczeg +Copyright(c) 2009-2014 Zoltan Herczeg All rights reserved. diff --git a/tools/pcre/CMakeLists.txt b/tools/pcre/CMakeLists.txt index 17d50b7a..846241d6 100644 --- a/tools/pcre/CMakeLists.txt +++ b/tools/pcre/CMakeLists.txt @@ -60,6 +60,11 @@ # 2012-09-06 PH added support for PCRE_EBCDIC_NL25 # 2012-09-08 ChPe added PCRE32 support # 2012-10-23 PH added support for VALGRIND and GCOV +# 2012-12-08 PH added patch from Daniel Richard G to quash some MSVC warnings +# 2013-07-01 PH realized that the "support" for GCOV was a total nonsense and +# so it has been removed. +# 2013-10-08 PH got rid of the "source" command, which is a bash-ism (use ".") +# 2013-11-05 PH added support for PARENS_NEST_LIMIT PROJECT(PCRE C CXX) @@ -128,6 +133,9 @@ SET(PCRE_EBCDIC_NL25 OFF CACHE BOOL SET(PCRE_LINK_SIZE "2" CACHE STRING "Internal link size (2, 3 or 4 allowed). See LINK_SIZE in config.h.in for details.") +SET(PCRE_PARENS_NEST_LIMIT "250" CACHE STRING + "Default nested parentheses limit. See PARENS_NEST_LIMIT in config.h.in for details.") + SET(PCRE_MATCH_LIMIT "10000000" CACHE STRING "Default limit on internal looping. See MATCH_LIMIT in config.h.in for details.") @@ -164,9 +172,6 @@ SET(PCRE_SUPPORT_BSR_ANYCRLF OFF CACHE BOOL SET(PCRE_SUPPORT_VALGRIND OFF CACHE BOOL "Enable Valgrind support.") -SET(PCRE_SUPPORT_COVERAGE OFF CACHE BOOL - "Enable code coverage support using gcov.") - OPTION(PCRE_SHOW_REPORT "Show the final configuration report" ON) OPTION(PCRE_BUILD_PCREGREP "Build pcregrep" ON) OPTION(PCRE_BUILD_TESTS "Build the tests" ON) @@ -181,6 +186,12 @@ IF (MINGW) OFF) ENDIF(MINGW) +IF(MSVC) + OPTION(INSTALL_MSVC_PDB + "ON=Install .pdb files built by MSVC, if generated" + OFF) +ENDIF(MSVC) + # bzip2 lib IF(BZIP2_FOUND) OPTION (PCRE_SUPPORT_LIBBZ2 "Enable support for linking pcregrep with libbz2." ON) @@ -296,13 +307,6 @@ IF(PCRE_SUPPORT_VALGRIND) SET(SUPPORT_VALGRIND 1) ENDIF(PCRE_SUPPORT_VALGRIND) -IF(PCRE_SUPPORT_COVERAGE) - SET(SUPPORT_GCOV 1) - IF(NOT CMAKE_COMPILER_IS_GNUCC) - MESSAGE(FATAL_ERROR "Code coverage reports can only be generated when using GCC") - ENDIF(NOT CMAKE_COMPILER_IS_GNUCC) -ENDIF(PCRE_SUPPORT_COVERAGE) - # This next one used to contain # SET(PCRETEST_LIBS ${READLINE_LIBRARY}) # but I was advised to add the NCURSES test as well, along with @@ -552,6 +556,17 @@ SET(PCREPOSIX_SOURCES ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcreposix.rc) ENDIF(MINGW AND NOT PCRE_STATIC) +IF(MSVC AND NOT PCRE_STATIC) +IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre.rc) +SET(PCRE_SOURCES + ${PCRE_SOURCES} pcre.rc) +ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcre.rc) +IF (EXISTS ${PROJECT_SOURCE_DIR}/pcreposix.rc) +SET(PCREPOSIX_SOURCES + ${PCREPOSIX_SOURCES} pcreposix.rc) +ENDIF (EXISTS ${PROJECT_SOURCE_DIR}/pcreposix.rc) +ENDIF(MSVC AND NOT PCRE_STATIC) + SET(PCRECPP_HEADERS pcrecpp.h pcre_scanner.h @@ -570,7 +585,7 @@ SET(PCRECPP_SOURCES ADD_DEFINITIONS(-DHAVE_CONFIG_H) IF(MSVC) - ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE) + ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS) ENDIF(MSVC) SET(CMAKE_INCLUDE_CURRENT_DIR 1) @@ -772,7 +787,7 @@ MESSAGE(\" \") # This is a generated file. srcdir=${PROJECT_SOURCE_DIR} pcretest=${PCRETEST_EXE} -source ${PROJECT_SOURCE_DIR}/RunTest +. ${PROJECT_SOURCE_DIR}/RunTest if test \"$?\" != \"0\"; then exit 1; fi # End ") @@ -788,7 +803,7 @@ if test \"$?\" != \"0\"; then exit 1; fi srcdir=${PROJECT_SOURCE_DIR} pcregrep=${PCREGREP_EXE} pcretest=${PCRETEST_EXE} -source ${PROJECT_SOURCE_DIR}/RunGrepTest +. ${PROJECT_SOURCE_DIR}/RunGrepTest if test \"$?\" != \"0\"; then exit 1; fi # End ") @@ -877,6 +892,17 @@ INSTALL(FILES ${man1} DESTINATION man/man1) INSTALL(FILES ${man3} DESTINATION man/man3) INSTALL(FILES ${html} DESTINATION share/doc/pcre/html) +IF(MSVC AND INSTALL_MSVC_PDB) + INSTALL(FILES ${PROJECT_BINARY_DIR}/pcre.pdb + ${PROJECT_BINARY_DIR}/pcreposix.pdb + DESTINATION bin + CONFIGURATIONS RelWithDebInfo) + INSTALL(FILES ${PROJECT_BINARY_DIR}/pcred.pdb + ${PROJECT_BINARY_DIR}/pcreposixd.pdb + DESTINATION bin + CONFIGURATIONS Debug) +ENDIF(MSVC AND INSTALL_MSVC_PDB) + # help, only for nice output IF(BUILD_SHARED_LIBS) SET(BUILD_STATIC_LIBS OFF) @@ -917,6 +943,7 @@ IF(PCRE_SHOW_REPORT) MESSAGE(STATUS " No stack recursion .............. : ${PCRE_NO_RECURSE}") MESSAGE(STATUS " POSIX mem threshold ............. : ${PCRE_POSIX_MALLOC_THRESHOLD}") MESSAGE(STATUS " Internal link size .............. : ${PCRE_LINK_SIZE}") + MESSAGE(STATUS " Parentheses nest limit .......... : ${PCRE_PARENS_NEST_LIMIT}") MESSAGE(STATUS " Match limit ..................... : ${PCRE_MATCH_LIMIT}") MESSAGE(STATUS " Match limit recursion ........... : ${PCRE_MATCH_LIMIT_RECURSION}") MESSAGE(STATUS " Build shared libs ............... : ${BUILD_SHARED_LIBS}") @@ -953,6 +980,11 @@ IF(PCRE_SHOW_REPORT) MESSAGE(STATUS " Non-standard dll names (prefix) . : ${NON_STANDARD_LIB_PREFIX}") MESSAGE(STATUS " Non-standard dll names (suffix) . : ${NON_STANDARD_LIB_SUFFIX}") ENDIF(MINGW AND NOT PCRE_STATIC) + + IF(MSVC) + MESSAGE(STATUS " Install MSVC .pdb files ..........: ${INSTALL_MSVC_PDB}") + ENDIF(MSVC) + MESSAGE(STATUS "") ENDIF(PCRE_SHOW_REPORT) diff --git a/tools/pcre/ChangeLog b/tools/pcre/ChangeLog index 1b016ece..7801ef84 100644 --- a/tools/pcre/ChangeLog +++ b/tools/pcre/ChangeLog @@ -1,6 +1,501 @@ ChangeLog for PCRE ------------------ +Version 8.35 04-April-2014 +-------------------------- + +1. A new flag is set, when property checks are present in an XCLASS. + When this flag is not set, PCRE can perform certain optimizations + such as studying these XCLASS-es. + +2. The auto-possessification of character sets were improved: a normal + and an extended character set can be compared now. Furthermore + the JIT compiler optimizes more character set checks. + +3. Got rid of some compiler warnings for potentially uninitialized variables + that show up only when compiled with -O2. + +4. A pattern such as (?=ab\K) that uses \K in an assertion can set the start + of a match later then the end of the match. The pcretest program was not + handling the case sensibly - it was outputting from the start to the next + binary zero. It now reports this situation in a message, and outputs the + text from the end to the start. + +5. Fast forward search is improved in JIT. Instead of the first three + characters, any three characters with fixed position can be searched. + Search order: first, last, middle. + +6. Improve character range checks in JIT. Characters are read by an inprecise + function now, which returns with an unknown value if the character code is + above a certain treshold (e.g: 256). The only limitation is that the value + must be bigger than the treshold as well. This function is useful, when + the characters above the treshold are handled in the same way. + +7. The macros whose names start with RAWUCHAR are placeholders for a future + mode in which only the bottom 21 bits of 32-bit data items are used. To + make this more memorable for those maintaining the code, the names have + been changed to start with UCHAR21, and an extensive comment has been added + to their definition. + +8. Add missing (new) files sljitNativeTILEGX.c and sljitNativeTILEGX-encoder.c + to the export list in Makefile.am (they were accidentally omitted from the + 8.34 tarball). + +9. The informational output from pcretest used the phrase "starting byte set" + which is inappropriate for the 16-bit and 32-bit libraries. As the output + for "first char" and "need char" really means "non-UTF-char", I've changed + "byte" to "char", and slightly reworded the output. The documentation about + these values has also been (I hope) clarified. + +10. Another JIT related optimization: use table jumps for selecting the correct + backtracking path, when more than four alternatives are present inside a + bracket. + +11. Empty match is not possible, when the minimum length is greater than zero, + and there is no \K in the pattern. JIT should avoid empty match checks in + such cases. + +12. In a caseless character class with UCP support, when a character with more + than one alternative case was not the first character of a range, not all + the alternative cases were added to the class. For example, s and \x{17f} + are both alternative cases for S: the class [RST] was handled correctly, + but [R-T] was not. + +13. The configure.ac file always checked for pthread support when JIT was + enabled. This is not used in Windows, so I have put this test inside a + check for the presence of windows.h (which was already tested for). + +14. Improve pattern prefix search by a simplified Boyer-Moore algorithm in JIT. + The algorithm provides a way to skip certain starting offsets, and usually + faster than linear prefix searches. + +15. Change 13 for 8.20 updated RunTest to check for the 'fr' locale as well + as for 'fr_FR' and 'french'. For some reason, however, it then used the + Windows-specific input and output files, which have 'french' screwed in. + So this could never have worked. One of the problems with locales is that + they aren't always the same. I have now updated RunTest so that it checks + the output of the locale test (test 3) against three different output + files, and it allows the test to pass if any one of them matches. With luck + this should make the test pass on some versions of Solaris where it was + failing. Because of the uncertainty, the script did not used to stop if + test 3 failed; it now does. If further versions of a French locale ever + come to light, they can now easily be added. + +16. If --with-pcregrep-bufsize was given a non-integer value such as "50K", + there was a message during ./configure, but it did not stop. This now + provokes an error. The invalid example in README has been corrected. + If a value less than the minimum is given, the minimum value has always + been used, but now a warning is given. + +17. If --enable-bsr-anycrlf was set, the special 16/32-bit test failed. This + was a bug in the test system, which is now fixed. Also, the list of various + configurations that are tested for each release did not have one with both + 16/32 bits and --enable-bar-anycrlf. It now does. + +18. pcretest was missing "-C bsr" for displaying the \R default setting. + +19. Little endian PowerPC systems are supported now by the JIT compiler. + +20. The fast forward newline mechanism could enter to an infinite loop on + certain invalid UTF-8 input. Although we don't support these cases + this issue can be fixed by a performance optimization. + +21. Change 33 of 8.34 is not sufficient to ensure stack safety because it does + not take account if existing stack usage. There is now a new global + variable called pcre_stack_guard that can be set to point to an external + function to check stack availability. It is called at the start of + processing every parenthesized group. + +22. A typo in the code meant that in ungreedy mode the max/min qualifier + behaved like a min-possessive qualifier, and, for example, /a{1,3}b/U did + not match "ab". + +23. When UTF was disabled, the JIT program reported some incorrect compile + errors. These messages are silenced now. + +24. Experimental support for ARM-64 and MIPS-64 has been added to the JIT + compiler. + +25. Change all the temporary files used in RunGrepTest to be different to those + used by RunTest so that the tests can be run simultaneously, for example by + "make -j check". + + +Version 8.34 15-December-2013 +----------------------------- + +1. Add pcre[16|32]_jit_free_unused_memory to forcibly free unused JIT + executable memory. Patch inspired by Carsten Klein. + +2. ./configure --enable-coverage defined SUPPORT_GCOV in config.h, although + this macro is never tested and has no effect, because the work to support + coverage involves only compiling and linking options and special targets in + the Makefile. The comment in config.h implied that defining the macro would + enable coverage support, which is totally false. There was also support for + setting this macro in the CMake files (my fault, I just copied it from + configure). SUPPORT_GCOV has now been removed. + +3. Make a small performance improvement in strlen16() and strlen32() in + pcretest. + +4. Change 36 for 8.33 left some unreachable statements in pcre_exec.c, + detected by the Solaris compiler (gcc doesn't seem to be able to diagnose + these cases). There was also one in pcretest.c. + +5. Cleaned up a "may be uninitialized" compiler warning in pcre_exec.c. + +6. In UTF mode, the code for checking whether a group could match an empty + string (which is used for indefinitely repeated groups to allow for + breaking an infinite loop) was broken when the group contained a repeated + negated single-character class with a character that occupied more than one + data item and had a minimum repetition of zero (for example, [^\x{100}]* in + UTF-8 mode). The effect was undefined: the group might or might not be + deemed as matching an empty string, or the program might have crashed. + +7. The code for checking whether a group could match an empty string was not + recognizing that \h, \H, \v, \V, and \R must match a character. + +8. Implemented PCRE_INFO_MATCH_EMPTY, which yields 1 if the pattern can match + an empty string. If it can, pcretest shows this in its information output. + +9. Fixed two related bugs that applied to Unicode extended grapheme clusters + that were repeated with a maximizing qualifier (e.g. \X* or \X{2,5}) when + matched by pcre_exec() without using JIT: + + (a) If the rest of the pattern did not match after a maximal run of + grapheme clusters, the code for backing up to try with fewer of them + did not always back up over a full grapheme when characters that do not + have the modifier quality were involved, e.g. Hangul syllables. + + (b) If the match point in a subject started with modifier character, and + there was no match, the code could incorrectly back up beyond the match + point, and potentially beyond the first character in the subject, + leading to a segfault or an incorrect match result. + +10. A conditional group with an assertion condition could lead to PCRE + recording an incorrect first data item for a match if no other first data + item was recorded. For example, the pattern (?(?=ab)ab) recorded "a" as a + first data item, and therefore matched "ca" after "c" instead of at the + start. + +11. Change 40 for 8.33 (allowing pcregrep to find empty strings) showed up a + bug that caused the command "echo a | ./pcregrep -M '|a'" to loop. + +12. The source of pcregrep now includes z/OS-specific code so that it can be + compiled for z/OS as part of the special z/OS distribution. + +13. Added the -T and -TM options to pcretest. + +14. The code in pcre_compile.c for creating the table of named capturing groups + has been refactored. Instead of creating the table dynamically during the + actual compiling pass, the information is remembered during the pre-compile + pass (on the stack unless there are more than 20 named groups, in which + case malloc() is used) and the whole table is created before the actual + compile happens. This has simplified the code (it is now nearly 150 lines + shorter) and prepared the way for better handling of references to groups + with duplicate names. + +15. A back reference to a named subpattern when there is more than one of the + same name now checks them in the order in which they appear in the pattern. + The first one that is set is used for the reference. Previously only the + first one was inspected. This change makes PCRE more compatible with Perl. + +16. Unicode character properties were updated from Unicode 6.3.0. + +17. The compile-time code for auto-possessification has been refactored, based + on a patch by Zoltan Herczeg. It now happens after instead of during + compilation. The code is cleaner, and more cases are handled. The option + PCRE_NO_AUTO_POSSESS is added for testing purposes, and the -O and /O + options in pcretest are provided to set it. It can also be set by + (*NO_AUTO_POSSESS) at the start of a pattern. + +18. The character VT has been added to the default ("C" locale) set of + characters that match \s and are generally treated as white space, + following this same change in Perl 5.18. There is now no difference between + "Perl space" and "POSIX space". Whether VT is treated as white space in + other locales depends on the locale. + +19. The code for checking named groups as conditions, either for being set or + for being recursed, has been refactored (this is related to 14 and 15 + above). Processing unduplicated named groups should now be as fast at + numerical groups, and processing duplicated groups should be faster than + before. + +20. Two patches to the CMake build system, by Alexander Barkov: + + (1) Replace the "source" command by "." in CMakeLists.txt because + "source" is a bash-ism. + + (2) Add missing HAVE_STDINT_H and HAVE_INTTYPES_H to config-cmake.h.in; + without these the CMake build does not work on Solaris. + +21. Perl has changed its handling of \8 and \9. If there is no previously + encountered capturing group of those numbers, they are treated as the + literal characters 8 and 9 instead of a binary zero followed by the + literals. PCRE now does the same. + +22. Following Perl, added \o{} to specify codepoints in octal, making it + possible to specify values greater than 0777 and also making them + unambiguous. + +23. Perl now gives an error for missing closing braces after \x{... instead of + treating the string as literal. PCRE now does the same. + +24. RunTest used to grumble if an inappropriate test was selected explicitly, + but just skip it when running all tests. This make it awkward to run ranges + of tests when one of them was inappropriate. Now it just skips any + inappropriate tests, as it always did when running all tests. + +25. If PCRE_AUTO_CALLOUT and PCRE_UCP were set for a pattern that contained + character types such as \d or \w, too many callouts were inserted, and the + data that they returned was rubbish. + +26. In UCP mode, \s was not matching two of the characters that Perl matches, + namely NEL (U+0085) and MONGOLIAN VOWEL SEPARATOR (U+180E), though they + were matched by \h. The code has now been refactored so that the lists of + the horizontal and vertical whitespace characters used for \h and \v (which + are defined only in one place) are now also used for \s. + +27. Add JIT support for the 64 bit TileGX architecture. + Patch by Jiong Wang (Tilera Corporation). + +28. Possessive quantifiers for classes (both explicit and automatically + generated) now use special opcodes instead of wrapping in ONCE brackets. + +29. Whereas an item such as A{4}+ ignored the possessivenes of the quantifier + (because it's meaningless), this was not happening when PCRE_CASELESS was + set. Not wrong, but inefficient. + +30. Updated perltest.pl to add /u (force Unicode mode) when /W (use Unicode + properties for \w, \d, etc) is present in a test regex. Otherwise if the + test contains no characters greater than 255, Perl doesn't realise it + should be using Unicode semantics. + +31. Upgraded the handling of the POSIX classes [:graph:], [:print:], and + [:punct:] when PCRE_UCP is set so as to include the same characters as Perl + does in Unicode mode. + +32. Added the "forbid" facility to pcretest so that putting tests into the + wrong test files can sometimes be quickly detected. + +33. There is now a limit (default 250) on the depth of nesting of parentheses. + This limit is imposed to control the amount of system stack used at compile + time. It can be changed at build time by --with-parens-nest-limit=xxx or + the equivalent in CMake. + +34. Character classes such as [A-\d] or [a-[:digit:]] now cause compile-time + errors. Perl warns for these when in warning mode, but PCRE has no facility + for giving warnings. + +35. Change 34 for 8.13 allowed quantifiers on assertions, because Perl does. + However, this was not working for (?!) because it is optimized to (*FAIL), + for which PCRE does not allow quantifiers. The optimization is now disabled + when a quantifier follows (?!). I can't see any use for this, but it makes + things uniform. + +36. Perl no longer allows group names to start with digits, so I have made this + change also in PCRE. It simplifies the code a bit. + +37. In extended mode, Perl ignores spaces before a + that indicates a + possessive quantifier. PCRE allowed a space before the quantifier, but not + before the possessive +. It now does. + +38. The use of \K (reset reported match start) within a repeated possessive + group such as (a\Kb)*+ was not working. + +40. Document that the same character tables must be used at compile time and + run time, and that the facility to pass tables to pcre_exec() and + pcre_dfa_exec() is for use only with saved/restored patterns. + +41. Applied Jeff Trawick's patch CMakeLists.txt, which "provides two new + features for Builds with MSVC: + + 1. Support pcre.rc and/or pcreposix.rc (as is already done for MinGW + builds). The .rc files can be used to set FileDescription and many other + attributes. + + 2. Add an option (-DINSTALL_MSVC_PDB) to enable installation of .pdb files. + This allows higher-level build scripts which want .pdb files to avoid + hard-coding the exact files needed." + +42. Added support for [[:<:]] and [[:>:]] as used in the BSD POSIX library to + mean "start of word" and "end of word", respectively, as a transition aid. + +43. A minimizing repeat of a class containing codepoints greater than 255 in + non-UTF 16-bit or 32-bit modes caused an internal error when PCRE was + compiled to use the heap for recursion. + +44. Got rid of some compiler warnings for unused variables when UTF but not UCP + is configured. + + +Version 8.33 28-May-2013 +------------------------ + +1. Added 'U' to some constants that are compared to unsigned integers, to + avoid compiler signed/unsigned warnings. Added (int) casts to unsigned + variables that are added to signed variables, to ensure the result is + signed and can be negated. + +2. Applied patch by Daniel Richard G for quashing MSVC warnings to the + CMake config files. + +3. Revise the creation of config.h.generic so that all boolean macros are + #undefined, whereas non-boolean macros are #ifndef/#endif-ed. This makes + overriding via -D on the command line possible. + +4. Changing the definition of the variable "op" in pcre_exec.c from pcre_uchar + to unsigned int is reported to make a quite noticeable speed difference in + a specific Windows environment. Testing on Linux did also appear to show + some benefit (and it is clearly not harmful). Also fixed the definition of + Xop which should be unsigned. + +5. Related to (4), changing the definition of the intermediate variable cc + in repeated character loops from pcre_uchar to pcre_uint32 also gave speed + improvements. + +6. Fix forward search in JIT when link size is 3 or greater. Also removed some + unnecessary spaces. + +7. Adjust autogen.sh and configure.ac to lose warnings given by automake 1.12 + and later. + +8. Fix two buffer over read issues in 16 and 32 bit modes. Affects JIT only. + +9. Optimizing fast_forward_start_bits in JIT. + +10. Adding support for callouts in JIT, and fixing some issues revealed + during this work. Namely: + + (a) Unoptimized capturing brackets incorrectly reset on backtrack. + + (b) Minimum length was not checked before the matching is started. + +11. The value of capture_last that is passed to callouts was incorrect in some + cases when there was a capture on one path that was subsequently abandoned + after a backtrack. Also, the capture_last value is now reset after a + recursion, since all captures are also reset in this case. + +12. The interpreter no longer returns the "too many substrings" error in the + case when an overflowing capture is in a branch that is subsequently + abandoned after a backtrack. + +13. In the pathological case when an offset vector of size 2 is used, pcretest + now prints out the matched string after a yield of 0 or 1. + +14. Inlining subpatterns in recursions, when certain conditions are fulfilled. + Only supported by the JIT compiler at the moment. + +15. JIT compiler now supports 32 bit Macs thanks to Lawrence Velazquez. + +16. Partial matches now set offsets[2] to the "bumpalong" value, that is, the + offset of the starting point of the matching process, provided the offsets + vector is large enough. + +17. The \A escape now records a lookbehind value of 1, though its execution + does not actually inspect the previous character. This is to ensure that, + in partial multi-segment matching, at least one character from the old + segment is retained when a new segment is processed. Otherwise, if there + are no lookbehinds in the pattern, \A might match incorrectly at the start + of a new segment. + +18. Added some #ifdef __VMS code into pcretest.c to help VMS implementations. + +19. Redefined some pcre_uchar variables in pcre_exec.c as pcre_uint32; this + gives some modest performance improvement in 8-bit mode. + +20. Added the PCRE-specific property \p{Xuc} for matching characters that can + be expressed in certain programming languages using Universal Character + Names. + +21. Unicode validation has been updated in the light of Unicode Corrigendum #9, + which points out that "non characters" are not "characters that may not + appear in Unicode strings" but rather "characters that are reserved for + internal use and have only local meaning". + +22. When a pattern was compiled with automatic callouts (PCRE_AUTO_CALLOUT) and + there was a conditional group that depended on an assertion, if the + assertion was false, the callout that immediately followed the alternation + in the condition was skipped when pcre_exec() was used for matching. + +23. Allow an explicit callout to be inserted before an assertion that is the + condition for a conditional group, for compatibility with automatic + callouts, which always insert a callout at this point. + +24. In 8.31, (*COMMIT) was confined to within a recursive subpattern. Perl also + confines (*SKIP) and (*PRUNE) in the same way, and this has now been done. + +25. (*PRUNE) is now supported by the JIT compiler. + +26. Fix infinite loop when /(?<=(*SKIP)ac)a/ is matched against aa. + +27. Fix the case where there are two or more SKIPs with arguments that may be + ignored. + +28. (*SKIP) is now supported by the JIT compiler. + +29. (*THEN) is now supported by the JIT compiler. + +30. Update RunTest with additional test selector options. + +31. The way PCRE handles backtracking verbs has been changed in two ways. + + (1) Previously, in something like (*COMMIT)(*SKIP), COMMIT would override + SKIP. Now, PCRE acts on whichever backtracking verb is reached first by + backtracking. In some cases this makes it more Perl-compatible, but Perl's + rather obscure rules do not always do the same thing. + + (2) Previously, backtracking verbs were confined within assertions. This is + no longer the case for positive assertions, except for (*ACCEPT). Again, + this sometimes improves Perl compatibility, and sometimes does not. + +32. A number of tests that were in test 2 because Perl did things differently + have been moved to test 1, because either Perl or PCRE has changed, and + these tests are now compatible. + +32. Backtracking control verbs are now handled in the same way in JIT and + interpreter. + +33. An opening parenthesis in a MARK/PRUNE/SKIP/THEN name in a pattern that + contained a forward subroutine reference caused a compile error. + +34. Auto-detect and optimize limited repetitions in JIT. + +35. Implement PCRE_NEVER_UTF to lock out the use of UTF, in particular, + blocking (*UTF) etc. + +36. In the interpreter, maximizing pattern repetitions for characters and + character types now use tail recursion, which reduces stack usage. + +37. The value of the max lookbehind was not correctly preserved if a compiled + and saved regex was reloaded on a host of different endianness. + +38. Implemented (*LIMIT_MATCH) and (*LIMIT_RECURSION). As part of the extension + of the compiled pattern block, expand the flags field from 16 to 32 bits + because it was almost full. + +39. Try madvise first before posix_madvise. + +40. Change 7 for PCRE 7.9 made it impossible for pcregrep to find empty lines + with a pattern such as ^$. It has taken 4 years for anybody to notice! The + original change locked out all matches of empty strings. This has been + changed so that one match of an empty string per line is recognized. + Subsequent searches on the same line (for colouring or for --only-matching, + for example) do not recognize empty strings. + +41. Applied a user patch to fix a number of spelling mistakes in comments. + +42. Data lines longer than 65536 caused pcretest to crash. + +43. Clarified the data type for length and startoffset arguments for pcre_exec + and pcre_dfa_exec in the function-specific man pages, where they were + explicitly stated to be in bytes, never having been updated. I also added + some clarification to the pcreapi man page. + +44. A call to pcre_dfa_exec() with an output vector size less than 2 caused + a segmentation fault. + + Version 8.32 30-November-2012 ----------------------------- @@ -1508,7 +2003,8 @@ Version 7.9 11-Apr-09 7. A pattern that could match an empty string could cause pcregrep to loop; it doesn't make sense to accept an empty string match in pcregrep, so I have locked it out (using PCRE's PCRE_NOTEMPTY option). By experiment, this - seems to be how GNU grep behaves. + seems to be how GNU grep behaves. [But see later change 40 for release + 8.33.] 8. The pattern (?(?=.*b)b|^) was incorrectly compiled as "match must be at start or after a newline", because the conditional assertion was not being @@ -1751,7 +2247,7 @@ Version 7.7 07-May-08 containing () gave an internal compiling error instead of "reference to non-existent subpattern". Fortunately, when the pattern did exist, the compiled code was correct. (When scanning forwards to check for the - existencd of the subpattern, it was treating the data ']' as terminating + existence of the subpattern, it was treating the data ']' as terminating the class, so got the count wrong. When actually compiling, the reference was subsequently set up correctly.) diff --git a/tools/pcre/CheckMan b/tools/pcre/CheckMan index de013347..480d7354 100644 --- a/tools/pcre/CheckMan +++ b/tools/pcre/CheckMan @@ -29,9 +29,9 @@ while (scalar(@ARGV) > 0) ^\.TH\s\S| ^\.SH\s\S| ^\.SS\s\S| - ^\.TP(?:\s\d+)?\s*$| - ^\.ti\s\S| + ^\.TP(?:\s?\d+)?\s*$| ^\.SM\s*$| + ^\.br\s*$| ^\.rs\s*$| ^\.sp\s*$| ^\.nf\s*$| diff --git a/tools/pcre/HACKING b/tools/pcre/HACKING index a90ddf87..691b7a14 100644 --- a/tools/pcre/HACKING +++ b/tools/pcre/HACKING @@ -54,12 +54,12 @@ Support for 16-bit and 32-bit data strings From release 8.30, PCRE supports 16-bit as well as 8-bit data strings; and from release 8.32, PCRE supports 32-bit data strings. The library can be compiled -in any combination of 8-bit, 16-bit or 32-bit modes, creating different -libraries. In the description that follows, the word "short" is -used for a 16-bit data quantity, and the word "unit" is used for a quantity -that is a byte in 8-bit mode, a short in 16-bit mode and a 32-bit unsigned -integer in 32-bit mode. However, so as not to over-complicate the text, the -names of PCRE functions are given in 8-bit form only. +in any combination of 8-bit, 16-bit or 32-bit modes, creating up to three +different libraries. In the description that follows, the word "short" is used +for a 16-bit data quantity, and the word "unit" is used for a quantity that is +a byte in 8-bit mode, a short in 16-bit mode and a 32-bit word in 32-bit mode. +However, so as not to over-complicate the text, the names of PCRE functions are +given in 8-bit form only. Computing the memory requirement: how it was @@ -94,6 +94,11 @@ runs more slowly than before (30% or more, depending on the pattern) because it is doing a full analysis of the pattern. My hope was that this would not be a big issue, and in the event, nobody has commented on it. +At release 8.34, a limit on the nesting depth of parentheses was re-introduced +(default 250, settable at build time) so as to put a limit on the amount of +system stack used by pcre_compile(). This is a safety feature for environments +with small stacks where the patterns are provided by users. + Traditional matching function ----------------------------- @@ -120,29 +125,30 @@ facilities are available, and those that are do not always work in quite the same way. See the user documentation for details. The algorithm that is used for pcre_dfa_exec() is not a traditional FSM, -because it may have a number of states active at one time. More work would be -needed at compile time to produce a traditional FSM where only one state is -ever active at once. I believe some other regex matchers work this way. +because it may have a number of states active at one time. More work would be +needed at compile time to produce a traditional FSM where only one state is +ever active at once. I believe some other regex matchers work this way. JIT +support is not available for this kind of matching. Changeable options ------------------ -The /i, /m, or /s options (PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL) may -change in the middle of patterns. From PCRE 8.13, their processing is handled -entirely at compile time by generating different opcodes for the different -settings. The runtime functions do not need to keep track of an options state -any more. +The /i, /m, or /s options (PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and some +others) may change in the middle of patterns. From PCRE 8.13, their processing +is handled entirely at compile time by generating different opcodes for the +different settings. The runtime functions do not need to keep track of an +options state any more. Format of compiled patterns --------------------------- -The compiled form of a pattern is a vector of units (bytes in 8-bit mode, or -shorts in 16-bit mode, 32-bit unsigned integers in 32-bit mode), containing -items of variable length. The first unit in an item contains an opcode, and -the length of the item is either implicit in the opcode or contained in the -data that follows it. +The compiled form of a pattern is a vector of unsigned units (bytes in 8-bit +mode, shorts in 16-bit mode, 32-bit words in 32-bit mode), containing items of +variable length. The first unit in an item contains an opcode, and the length +of the item is either implicit in the opcode or contained in the data that +follows it. In many cases listed below, LINK_SIZE data values are specified for offsets within the compiled pattern. LINK_SIZE always specifies a number of bytes. The @@ -151,8 +157,10 @@ default value for LINK_SIZE is 2, but PCRE can be compiled to use 3-byte or LINK_SIZE values are available only in 8-bit mode.) Specifing a LINK_SIZE larger than 2 is necessary only when patterns whose compiled length is greater than 64K are going to be processed. In this description, we assume the "normal" -compilation options. Data values that are counts (e.g. for quantifiers) are -always just two bytes long (one short in 16-bit mode). +compilation options. Data values that are counts (e.g. quantifiers) are two +bytes long in 8-bit mode (most significant byte first), or one unit in 16-bit +and 32-bit modes. + Opcodes with no following data ------------------------------ @@ -162,7 +170,7 @@ These items are all just one unit long OP_END end of pattern OP_ANY match any one character other than newline OP_ALLANY match any one character, including newline - OP_ANYBYTE match any single byte, even in UTF-8 mode + OP_ANYBYTE match any single unit, even in UTF-8/16 mode OP_SOD match start of data: \A OP_SOM, start of match (subject + offset): \G OP_SET_SOM, set start of match (\K) @@ -180,28 +188,33 @@ These items are all just one unit long OP_VSPACE \v OP_NOT_WORDCHAR \W OP_WORDCHAR \w - OP_EODN match end of data or \n at end: \Z + OP_EODN match end of data or newline at end: \Z OP_EOD match end of data: \z OP_DOLL $ (end of data, or before final newline) OP_DOLLM $ multiline mode (end of data or before newline) - OP_EXTUNI match an extended Unicode character + OP_EXTUNI match an extended Unicode grapheme cluster OP_ANYNL match any Unicode newline sequence + OP_ASSERT_ACCEPT ) OP_ACCEPT ) These are Perl 5.10's "backtracking control OP_COMMIT ) verbs". If OP_ACCEPT is inside capturing OP_FAIL ) parentheses, it may be preceded by one or more - OP_PRUNE ) OP_CLOSE, followed by a 2-byte number, - OP_SKIP ) indicating which parentheses must be closed. + OP_PRUNE ) OP_CLOSE, each followed by a count that + OP_SKIP ) indicates which parentheses must be closed. + OP_THEN ) + +OP_ASSERT_ACCEPT is used when (*ACCEPT) is encountered within an assertion. +This ends the assertion, not the entire pattern match. -Backtracking control verbs with (optional) data ------------------------------------------------ +Backtracking control verbs with optional data +--------------------------------------------- (*THEN) without an argument generates the opcode OP_THEN and no following data. OP_MARK is followed by the mark name, preceded by a one-unit length, and followed by a binary zero. For (*PRUNE), (*SKIP), and (*THEN) with arguments, the opcodes OP_PRUNE_ARG, OP_SKIP_ARG, and OP_THEN_ARG are used, with the name -following in the same format. +following in the same format as OP_MARK. Matching literal characters @@ -212,6 +225,10 @@ casefully. For caseless matching, OP_CHARI is used. In UTF-8 or UTF-16 modes, the character may be more than one unit long. In UTF-32 mode, characters are always exactly one unit long. +If there is only one character in a character class, OP_CHAR or OP_CHARI is +used for a positive class, and OP_NOT or OP_NOTI for a negative one (that is, +for something like [^a]). + Repeating single characters --------------------------- @@ -232,10 +249,9 @@ following opcodes, which come in caseful and caseless versions: Each opcode is followed by the character that is to be repeated. In ASCII mode, these are two-unit items; in UTF-8 or UTF-16 modes, the length is variable; in -UTF-32 mode these are one-unit items. -Those with "MIN" in their names are the minimizing versions. Those with "POS" -in their names are possessive versions. Other repeats make use of these -opcodes: +UTF-32 mode these are one-unit items. Those with "MIN" in their names are the +minimizing versions. Those with "POS" in their names are possessive versions. +Other repeats make use of these opcodes: Caseful Caseless OP_UPTO OP_UPTOI @@ -243,10 +259,15 @@ opcodes: OP_POSUPTO OP_POSUPTOI OP_EXACT OP_EXACTI -Each of these is followed by a two-byte (one short) count (most significant -byte first in 8-bit mode) and then the repeated character. OP_UPTO matches from -0 to the given number. A repeat with a non-zero minimum and a fixed maximum is -coded as an OP_EXACT followed by an OP_UPTO (or OP_MINUPTO or OPT_POSUPTO). +Each of these is followed by a count and then the repeated character. OP_UPTO +matches from 0 to the given number. A repeat with a non-zero minimum and a +fixed maximum is coded as an OP_EXACT followed by an OP_UPTO (or OP_MINUPTO or +OPT_POSUPTO). + +Another set of matching repeating opcodes (called OP_NOTSTAR, OP_NOTSTARI, +etc.) are used for repeated, negated, single-character classes such as [^a]*. +The normal single-character opcodes (OP_STAR, etc.) are used for repeated +positive single-character classes. Repeating character types @@ -277,7 +298,10 @@ Match by Unicode property OP_PROP and OP_NOTPROP are used for positive and negative matches of a character by testing its Unicode property (the \p and \P escape sequences). Each is followed by two units that encode the desired property as a type and a -value. +value. The types are a set of #defines of the form PT_xxx, and the values are +enumerations of the form ucp_xx, defined in the ucp.h source file. The value is +relevant only for PT_GC (General Category), PT_PC (Particular Category), and +PT_SC (Script). Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by three units: OP_PROP or OP_NOTPROP, and then the desired property type and @@ -287,67 +311,88 @@ value. Character classes ----------------- -If there is only one character in the class, OP_CHAR or OP_CHARI is used for a +If there is only one character in a class, OP_CHAR or OP_CHARI is used for a positive class, and OP_NOT or OP_NOTI for a negative one (that is, for something like [^a]). -Another set of 13 repeating opcodes (called OP_NOTSTAR etc.) are used for -repeated, negated, single-character classes. The normal single-character -opcodes (OP_STAR, etc.) are used for repeated positive single-character -classes. +A set of repeating opcodes (called OP_NOTSTAR etc.) are used for repeated, +negated, single-character classes. The normal single-character opcodes +(OP_STAR, etc.) are used for repeated positive single-character classes. -When there is more than one character in a class and all the characters are +When there is more than one character in a class, and all the code points are less than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a -negative one. In either case, the opcode is followed by a 32-byte (16-short) -bit map containing a 1 bit for every character that is acceptable. The bits are -counted from the least significant end of each unit. In caseless mode, bits for -both cases are set. +negative one. In either case, the opcode is followed by a 32-byte (16-short, +8-word) bit map containing a 1 bit for every character that is acceptable. The +bits are counted from the least significant end of each unit. In caseless mode, +bits for both cases are set. -The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8/16/32 mode, -subject characters with values greater than 255 can be handled correctly. For -OP_CLASS they do not match, whereas for OP_NCLASS they do. +The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8/16/32 +mode, subject characters with values greater than 255 can be handled correctly. +For OP_CLASS they do not match, whereas for OP_NCLASS they do. -For classes containing characters with values greater than 255, 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. +For classes containing characters with values greater than 255 or that contain +\p or \P, OP_XCLASS is used. It optionally uses a bit map if any code points +are less than 256, followed by a list of pairs (for a range) and single +characters. In caseless mode, both cases are explicitly listed. + +OP_XCLASS is followed by a unit containing flag bits: XCL_NOT indicates that +this is a negative class, and XCL_MAP indicates that a bit map is present. +There follows the bit map, if XCL_MAP is set, and then a sequence of items +coded as follows: + + XCL_END marks the end of the list + XCL_SINGLE one character follows + XCL_RANGE two characters follow + XCL_PROP a Unicode property (type, value) follows + XCL_NOTPROP a Unicode property (type, value) follows + +If a range starts with a code point less than 256 and ends with one greater +than 256, an XCL_RANGE item is used, without setting any bits in the bit map. +This means that if no other items in the class set bits in the map, a map is +not needed. Back references --------------- -OP_REF (caseful) or OP_REFI (caseless) is followed by two bytes (one short) -containing the reference number. +OP_REF (caseful) or OP_REFI (caseless) is followed by a count containing the +reference number if the reference is to a unique capturing group (either by +number or by name). When named groups are used, there may be more than one +group with the same name. In this case, a reference by name generates OP_DNREF +or OP_DNREFI. These are followed by two counts: the index (not the byte offset) +in the group name table of the first entry for the requred name, followed by +the number of groups with the same name. Repeating character classes and back references ----------------------------------------------- Single-character classes are handled specially (see above). This section -applies to OP_CLASS and OP_REF[I]. In both cases, the repeat information -follows the base item. The matching code looks at the following opcode to see -if it is one of +applies to other classes and also to back references. In both cases, the repeat +information follows the base item. The matching code looks at the following +opcode to see if it is one of OP_CRSTAR OP_CRMINSTAR + OP_CRPOSSTAR OP_CRPLUS OP_CRMINPLUS + OP_CRPOSPLUS OP_CRQUERY OP_CRMINQUERY + OP_CRPOSQUERY OP_CRRANGE OP_CRMINRANGE + OP_CRPOSRANGE -All but the last two are just single-unit items. The others are followed by -four bytes (two shorts) of data, comprising the minimum and maximum repeat -counts. There are no special possessive opcodes for these repeats; a possessive -repeat is compiled into an atomic group. +All but the last three are single-unit items, with no data. The others are +followed by the minimum and maximum repeat counts. Brackets and alternation ------------------------ -A pair of non-capturing (round) brackets is wrapped round each expression at +A pair of non-capturing round brackets is wrapped round each expression at compile time, so alternation always happens in the context of brackets. [Note for North Americans: "bracket" to some English speakers, including @@ -364,20 +409,20 @@ A bracket opcode is followed by LINK_SIZE bytes which give the offset to the next alternative OP_ALT or, if there aren't any branches, to the matching OP_KET opcode. Each OP_ALT is followed by LINK_SIZE bytes giving the offset to the next one, or to the OP_KET opcode. For capturing brackets, the bracket -number immediately follows the offset, always as a 2-byte (one short) item. +number is a count that immediately follows the offset. -OP_KET is used for subpatterns that do not repeat indefinitely, and -OP_KETRMIN and OP_KETRMAX are used for indefinite repetitions, minimally or -maximally respectively (see below for possessive repetitions). All three are -followed by LINK_SIZE bytes giving (as a positive number) the offset back to -the matching bracket opcode. +OP_KET is used for subpatterns that do not repeat indefinitely, and OP_KETRMIN +and OP_KETRMAX are used for indefinite repetitions, minimally or maximally +respectively (see below for possessive repetitions). All three are followed by +LINK_SIZE bytes giving (as a positive number) the offset back to the matching +bracket opcode. If a subpattern is quantified such that it is permitted to match zero times, it is preceded by one of OP_BRAZERO, OP_BRAMINZERO, or OP_SKIPZERO. These are single-unit opcodes that tell the matcher that skipping the following subpattern entirely is a valid branch. In the case of the first two, not skipping the pattern is also valid (greedy and non-greedy). The third is used -when a pattern has the quantifier {0,0}. It cannot be entirely discarded, +when a pattern has the quantifier {0,0}. It cannot be entirely discarded, because it may be called as a subroutine from elsewhere in the regex. A subpattern with an indefinite maximum repetition is replicated in the @@ -397,6 +442,7 @@ final replication is changed to OP_SBRA or OP_SCBRA. This tells the matcher that it needs to check for matching an empty string when it hits OP_KETRMIN or OP_KETRMAX, and if so, to break the loop. + Possessive brackets ------------------- @@ -407,26 +453,34 @@ of OP_SCBRA. The end of such a group is marked by OP_KETRPOS. If the minimum repetition is zero, the group is preceded by OP_BRAPOSZERO. +Once-only (atomic) groups +------------------------- + +These are just like other subpatterns, but they start with the opcode +OP_ONCE or OP_ONCE_NC. The former is used when there are no capturing brackets +within the atomic group; the latter when there are. The distinction is needed +for when there is a backtrack to before the group - any captures within the +group must be reset, so it is necessary to retain backtracking points inside +the group even after it is complete in order to do this. When there are no +captures in an atomic group, all the backtracking can be discarded when it is +complete. This is more efficient, and also uses less stack. + +The check for matching an empty string in an unbounded repeat is handled +entirely at runtime, so there are just these two opcodes for atomic groups. + + Assertions ---------- -Forward assertions are just like other subpatterns, but starting with one of -the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes +Forward assertions are also just like other subpatterns, but starting with one +of the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion -is OP_REVERSE, followed by a two byte (one short) count of the number of -characters to move back the pointer in the subject string. In ASCII mode, the -count is a number of units, but in UTF-8/16 mode each character may occupy more -than one unit; in UTF-32 mode each character occupies exactly one unit. -A separate count is present in each alternative of a lookbehind -assertion, allowing them to have different fixed lengths. - - -Once-only (atomic) subpatterns ------------------------------- - -These are also just like other subpatterns, but they start with the opcode -OP_ONCE. The check for matching an empty string in an unbounded repeat is -handled entirely at runtime, so there is just this one opcode. +is OP_REVERSE, followed by a count of the number of characters to move back the +pointer in the subject string. In ASCII mode, the count is a number of units, +but in UTF-8/16 mode each character may occupy more than one unit; in UTF-32 +mode each character occupies exactly one unit. A separate count is present in +each alternative of a lookbehind assertion, allowing them to have different +fixed lengths. Conditional subpatterns @@ -435,28 +489,29 @@ Conditional subpatterns These are like other subpatterns, but they start with the opcode OP_COND, or OP_SCOND for one that might match an empty string in an unbounded repeat. If the condition is a back reference, this is stored at the start of the -subpattern using the opcode OP_CREF followed by two bytes (one short) -containing the reference number. OP_NCREF is used instead if the reference was -generated by name (so that the runtime code knows to check for duplicate -names). +subpattern using the opcode OP_CREF followed by a count containing the +reference number, provided that the reference is to a unique capturing group. +If the reference was by name and there is more than one group with that name, +OP_DNCREF is used instead. It is followed by two counts: the index in the group +names table, and the number of groups with the same name. If the condition is "in recursion" (coded as "(?(R)"), or "in recursion of group x" (coded as "(?(Rx)"), the group number is stored at the start of the -subpattern using the opcode OP_RREF or OP_NRREF (cf OP_NCREF), and a value of -zero for "the whole pattern". For a DEFINE condition, just the single unit -OP_DEF is used (it has no associated data). Otherwise, a conditional subpattern -always starts with one of the assertions. +subpattern using the opcode OP_RREF (with a value of zero for "the whole +pattern") or OP_DNRREF (with data as for OP_DNCREF). For a DEFINE condition, +just the single unit OP_DEF is used (it has no associated data). Otherwise, a +conditional subpattern always starts with one of the assertions. Recursion --------- Recursion either matches the current regex, or some subexpression. The opcode -OP_RECURSE is followed by an value which is the offset to the starting bracket -from the start of the whole pattern. From release 6.5, OP_RECURSE is -automatically wrapped inside OP_ONCE brackets (because otherwise some patterns -broke it). OP_RECURSE is also used for "subroutine" calls, even though they -are not strictly a recursion. +OP_RECURSE is followed by aLINK_SIZE value that is the offset to the starting +bracket from the start of the whole pattern. From release 6.5, OP_RECURSE is +automatically wrapped inside OP_ONCE brackets, because otherwise some patterns +broke it. OP_RECURSE is also used for "subroutine" calls, even though they are +not strictly a recursion. Callout @@ -464,10 +519,10 @@ Callout OP_CALLOUT is followed by one unit of data that holds a callout number in the range 0 to 254 for manual callouts, or 255 for an automatic callout. In both -cases there follows a two-byte (one short) value giving the offset in the -pattern to the start of the following item, and another two-byte (one short) -item giving the length of the next item. - +cases there follows a count giving the offset in the pattern string to the +start of the following item, and another count giving the length of this item. +These values make is possible for pcretest to output useful tracing information +using automatic callouts. Philip Hazel -February 2012 +November 2013 diff --git a/tools/pcre/INSTALL b/tools/pcre/INSTALL index a1e89e18..20998407 100644 --- a/tools/pcre/INSTALL +++ b/tools/pcre/INSTALL @@ -1,7 +1,7 @@ Installation Instructions ************************* -Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, @@ -12,8 +12,8 @@ without warranty of any kind. Basic Installation ================== - Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following + Briefly, the shell command `./configure && make && make install' +should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented @@ -309,9 +309,10 @@ causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: +an Autoconf limitation. Until the limitation is lifted, you can use +this workaround: - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== @@ -367,4 +368,3 @@ operates. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. - diff --git a/tools/pcre/LICENCE b/tools/pcre/LICENCE index 5ce31a82..602e4ae6 100644 --- a/tools/pcre/LICENCE +++ b/tools/pcre/LICENCE @@ -24,7 +24,7 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2012 University of Cambridge +Copyright (c) 1997-2014 University of Cambridge All rights reserved. @@ -35,7 +35,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2010-2012 Zoltan Herczeg +Copyright(c) 2010-2014 Zoltan Herczeg All rights reserved. @@ -46,7 +46,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2009-2012 Zoltan Herczeg +Copyright(c) 2009-2014 Zoltan Herczeg All rights reserved. diff --git a/tools/pcre/Makefile.am b/tools/pcre/Makefile.am index 5d9928a4..5f640b00 100644 --- a/tools/pcre/Makefile.am +++ b/tools/pcre/Makefile.am @@ -14,11 +14,16 @@ dist_doc_DATA = \ NEWS \ README +# Note that pcrecpp.html is not in this list; it is listed separately below. + dist_html_DATA = \ + doc/html/NON-AUTOTOOLS-BUILD.txt \ + doc/html/README.txt \ doc/html/index.html \ + doc/html/pcre-config.html \ doc/html/pcre.html \ doc/html/pcre16.html \ - doc/html/pcre-config.html \ + doc/html/pcre32.html \ doc/html/pcre_assign_jit_stack.html \ doc/html/pcre_compile.html \ doc/html/pcre_compile2.html \ @@ -44,6 +49,7 @@ dist_html_DATA = \ doc/html/pcre_refcount.html \ doc/html/pcre_study.html \ doc/html/pcre_utf16_to_host_byte_order.html \ + doc/html/pcre_utf32_to_host_byte_order.html \ doc/html/pcre_version.html \ doc/html/pcreapi.html \ doc/html/pcrebuild.html \ @@ -65,10 +71,6 @@ dist_html_DATA = \ doc/html/pcretest.html \ doc/html/pcreunicode.html -# doc/html/pcre32.html \ -# doc/html/pcre_utf32_to_host_byte_order.html \ -# - pcrecpp_html = doc/html/pcrecpp.html dist_noinst_DATA = $(pcrecpp_html) @@ -140,14 +142,16 @@ pcre.h.generic: pcre.h.in configure.ac cp -p pcre.h $@ # It is more complicated for config.h.generic. We need the version that results -# from a default configuration. We can get this by doing a configure in a -# temporary directory. However, some trickery is needed, -# because the source directory may already be configured. If you -# just try running configure in a new directory, it complains. For this reason, -# we move config.status out of the way while doing the default configuration. -# The resulting config.h is munged by perl to put #ifdefs round any #defines -# and to get rid of any gcc-specific visibility settings. Make sure that -# PCRE_EXP_DEFN is unset (in case it has visibility settings). +# from a default configuration so as to get all the default values for PCRE +# configuration macros such as MATCH_LIMIT and NEWLINE. We can get this by +# doing a configure in a temporary directory. However, some trickery is needed, +# because the source directory may already be configured. If you just try +# running configure in a new directory, it complains. For this reason, we move +# config.status out of the way while doing the default configuration. The +# resulting config.h is munged by perl to put #ifdefs round any #defines for +# macros with values, and to #undef all boolean macros such as HAVE_xxx and +# SUPPORT_xxx. We also get rid of any gcc-specific visibility settings. Make +# sure that PCRE_EXP_DEFN is unset (in case it has visibility settings). config.h.generic: configure.ac rm -rf $@ _generic mkdir _generic @@ -160,8 +164,10 @@ config.h.generic: configure.ac -e 'if(/PCRE_EXP_DEFN/){print"/* #undef PCRE_EXP_DEFN */\n";$$blank=0;next;}' \ -e 'if(/to make a symbol visible/){next;}' \ -e 'if(/__attribute__ \(\(visibility/){next;}' \ - -e 'if(/^#define\s(?!PACKAGE)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;}' \ - -e 'else {if(/^\s*$$/){print unless $$blank; $$blank=1;} else{print;$$blank=0;}}' \ + -e 'if(/LT_OBJDIR/){print"/* This is ignored unless you are using libtool. */\n";}' \ + -e 'if(/^#define\s((?:HAVE|SUPPORT|STDC)_\w+)/){print"/* #undef $$1 */\n";$$blank=0;next;}' \ + -e 'if(/^#define\s(?!PACKAGE|VERSION)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;next;}' \ + -e 'if(/^\s*$$/){print unless $$blank; $$blank=1;} else{print;$$blank=0;}' \ _generic/config.h >$@ rm -rf _generic @@ -344,15 +350,19 @@ EXTRA_DIST += \ sljit/sljitExecAllocator.c \ sljit/sljitLir.c \ sljit/sljitLir.h \ - sljit/sljitNativeARM_Thumb2.c \ - sljit/sljitNativeARM_v5.c \ + sljit/sljitNativeARM_32.c \ + sljit/sljitNativeARM_64.c \ + sljit/sljitNativeARM_T2_32.c \ sljit/sljitNativeMIPS_32.c \ + sljit/sljitNativeMIPS_64.c \ sljit/sljitNativeMIPS_common.c \ sljit/sljitNativePPC_32.c \ sljit/sljitNativePPC_64.c \ sljit/sljitNativePPC_common.c \ sljit/sljitNativeSPARC_32.c \ sljit/sljitNativeSPARC_common.c \ + sljit/sljitNativeTILEGX_64.c \ + sljit/sljitNativeTILEGX-encoder.c \ sljit/sljitNativeX86_32.c \ sljit/sljitNativeX86_64.c \ sljit/sljitNativeX86_common.c \ @@ -572,6 +582,8 @@ EXTRA_DIST += \ testdata/testoutput1 \ testdata/testoutput2 \ testdata/testoutput3 \ + testdata/testoutput3A \ + testdata/testoutput3B \ testdata/testoutput4 \ testdata/testoutput5 \ testdata/testoutput6 \ @@ -610,8 +622,10 @@ CLEANFILES += \ teststderr \ testtemp* \ testtry \ - testNinput - + testNinput \ + testtrygrep \ + teststderrgrep \ + testNinputgrep # PCRE demonstration program. No longer built automatcally. The point is that # the users should build it themselves. So just distribute the source. @@ -659,11 +673,13 @@ if WITH_PCRE_CPP pkgconfig_DATA += libpcrecpp.pc endif +# Note that pcrecpp.3 is not in this list, but is included separately below. + dist_man_MANS = \ + doc/pcre-config.1 \ doc/pcre.3 \ doc/pcre16.3 \ doc/pcre32.3 \ - doc/pcre-config.1 \ doc/pcre_assign_jit_stack.3 \ doc/pcre_compile.3 \ doc/pcre_compile2.3 \ @@ -695,6 +711,7 @@ dist_man_MANS = \ doc/pcrebuild.3 \ doc/pcrecallout.3 \ doc/pcrecompat.3 \ + doc/pcredemo.3 \ doc/pcregrep.1 \ doc/pcrejit.3 \ doc/pcrelimits.3 \ diff --git a/tools/pcre/Makefile.in b/tools/pcre/Makefile.in index d026bea5..75cfe6da 100644 --- a/tools/pcre/Makefile.in +++ b/tools/pcre/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in 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. @@ -20,23 +19,51 @@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -124,18 +151,18 @@ noinst_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3) $(am__EXEEXT_4) @WITH_PCRE32_TRUE@am__append_44 = libpcre32.pc @WITH_PCRE_CPP_TRUE@am__append_45 = libpcrecpp.pc subdir = . -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) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/config.h.in \ - $(srcdir)/libpcre.pc.in $(srcdir)/libpcre16.pc.in \ - $(srcdir)/libpcre32.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 $(top_srcdir)/configure AUTHORS \ - COPYING ChangeLog INSTALL NEWS compile config.guess config.sub \ - depcomp install-sh ltmain.sh missing +DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/config.h.in $(srcdir)/libpcre.pc.in \ + $(srcdir)/libpcre16.pc.in $(srcdir)/libpcre32.pc.in \ + $(srcdir)/libpcreposix.pc.in $(srcdir)/libpcrecpp.pc.in \ + $(srcdir)/pcre-config.in $(srcdir)/pcre.h.in \ + $(srcdir)/pcre_stringpiece.h.in $(srcdir)/pcrecpparg.h.in \ + $(am__dist_noinst_SCRIPTS_DIST) depcomp $(dist_man_MANS) \ + $(dist_doc_DATA) $(dist_html_DATA) $(dist_noinst_DATA) \ + $(am__include_HEADERS_DIST) test-driver COPYING ar-lib compile \ + config.guess config.sub install-sh missing ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ @@ -222,6 +249,7 @@ libpcre_la_OBJECTS = $(am_libpcre_la_OBJECTS) \ AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent +am__v_lt_1 = libpcre_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpcre_la_CFLAGS) \ $(CFLAGS) $(libpcre_la_LDFLAGS) $(LDFLAGS) -o $@ @@ -412,6 +440,18 @@ pcretest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__dist_noinst_SCRIPTS_DIST = RunTest RunGrepTest SCRIPTS = $(bin_SCRIPTS) $(dist_noinst_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -424,17 +464,16 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) 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_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ @@ -443,17 +482,16 @@ LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = CXXLD = $(CXX) 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_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = SOURCES = $(libpcre_la_SOURCES) $(nodist_libpcre_la_SOURCES) \ $(libpcre16_la_SOURCES) $(nodist_libpcre16_la_SOURCES) \ $(libpcre32_la_SOURCES) $(nodist_libpcre32_la_SOURCES) \ @@ -486,10 +524,204 @@ DATA = $(dist_doc_DATA) $(dist_html_DATA) $(dist_noinst_DATA) \ $(html_DATA) $(pkgconfig_DATA) am__include_HEADERS_DIST = pcreposix.h pcrecpp.h pcre_scanner.h HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__tty_colors = \ -red=; grn=; lgn=; blu=; std= +CSCOPE = cscope +AM_RECURSIVE_TARGETS = cscope check recheck +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -499,8 +731,10 @@ am__remove_distdir = \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi +am__post_remove_distdir = $(am__remove_distdir) DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip GZIP_ENV = --best +DIST_TARGETS = dist-bzip2 dist-gzip dist-zip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' @@ -678,11 +912,16 @@ dist_doc_DATA = \ NEWS \ README + +# Note that pcrecpp.html is not in this list; it is listed separately below. dist_html_DATA = \ + doc/html/NON-AUTOTOOLS-BUILD.txt \ + doc/html/README.txt \ doc/html/index.html \ + doc/html/pcre-config.html \ doc/html/pcre.html \ doc/html/pcre16.html \ - doc/html/pcre-config.html \ + doc/html/pcre32.html \ doc/html/pcre_assign_jit_stack.html \ doc/html/pcre_compile.html \ doc/html/pcre_compile2.html \ @@ -708,6 +947,7 @@ dist_html_DATA = \ doc/html/pcre_refcount.html \ doc/html/pcre_study.html \ doc/html/pcre_utf16_to_host_byte_order.html \ + doc/html/pcre_utf32_to_host_byte_order.html \ doc/html/pcre_version.html \ doc/html/pcreapi.html \ doc/html/pcrebuild.html \ @@ -729,10 +969,6 @@ dist_html_DATA = \ doc/html/pcretest.html \ doc/html/pcreunicode.html - -# doc/html/pcre32.html \ -# doc/html/pcre_utf32_to_host_byte_order.html \ -# pcrecpp_html = doc/html/pcrecpp.html dist_noinst_DATA = $(pcrecpp_html) @WITH_PCRE_CPP_TRUE@html_DATA = $(pcrecpp_html) @@ -745,7 +981,7 @@ dist_noinst_SCRIPTS = RunTest $(am__append_39) # Additional files to delete on 'make clean' and 'make maintainer-clean'. CLEANFILES = pcre_chartables.c testsavedregex teststderr testtemp* \ - testtry testNinput + testtry testNinput testtrygrep teststderrgrep testNinputgrep MAINTAINERCLEANFILES = pcre.h.generic config.h.generic # Additional files to bundle with the distribution, over and above what @@ -781,11 +1017,13 @@ EXTRA_DIST = m4/ax_pthread.m4 m4/pcre_visibility.m4 doc/perltest.txt \ 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/sljitNativeARM_32.c sljit/sljitNativeARM_64.c \ + sljit/sljitNativeARM_T2_32.c sljit/sljitNativeMIPS_32.c \ + sljit/sljitNativeMIPS_64.c sljit/sljitNativeMIPS_common.c \ sljit/sljitNativePPC_32.c sljit/sljitNativePPC_64.c \ sljit/sljitNativePPC_common.c sljit/sljitNativeSPARC_32.c \ - sljit/sljitNativeSPARC_common.c sljit/sljitNativeX86_32.c \ + sljit/sljitNativeSPARC_common.c sljit/sljitNativeTILEGX_64.c \ + sljit/sljitNativeTILEGX-encoder.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 \ @@ -805,9 +1043,10 @@ EXTRA_DIST = m4/ax_pthread.m4 m4/pcre_visibility.m4 doc/perltest.txt \ testdata/testinput21 testdata/testinput22 testdata/testinput23 \ testdata/testinput24 testdata/testinput25 testdata/testinput26 \ testdata/testinputEBC testdata/testoutput1 \ - testdata/testoutput2 testdata/testoutput3 testdata/testoutput4 \ - testdata/testoutput5 testdata/testoutput6 testdata/testoutput7 \ - testdata/testoutput8 testdata/testoutput9 \ + testdata/testoutput2 testdata/testoutput3 \ + testdata/testoutput3A testdata/testoutput3B \ + testdata/testoutput4 testdata/testoutput5 testdata/testoutput6 \ + testdata/testoutput7 testdata/testoutput8 testdata/testoutput9 \ testdata/testoutput10 testdata/testoutput11-8 \ testdata/testoutput11-16 testdata/testoutput11-32 \ testdata/testoutput12 testdata/testoutput13 \ @@ -987,11 +1226,13 @@ DLL_OBJS = pcre_byte_order.o pcre_compile.o pcre_config.o \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libpcre.pc libpcreposix.pc $(am__append_43) \ $(am__append_44) $(am__append_45) + +# Note that pcrecpp.3 is not in this list, but is included separately below. dist_man_MANS = \ + doc/pcre-config.1 \ doc/pcre.3 \ doc/pcre16.3 \ doc/pcre32.3 \ - doc/pcre-config.1 \ doc/pcre_assign_jit_stack.3 \ doc/pcre_compile.3 \ doc/pcre_compile2.3 \ @@ -1023,6 +1264,7 @@ dist_man_MANS = \ doc/pcrebuild.3 \ doc/pcrecallout.3 \ doc/pcrecompat.3 \ + doc/pcredemo.3 \ doc/pcregrep.1 \ doc/pcrejit.3 \ doc/pcrelimits.3 \ @@ -1068,7 +1310,7 @@ all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: -.SUFFIXES: .c .cc .lo .o .obj +.SUFFIXES: .c .cc .lo .log .o .obj .test .test$(EXEEXT) .trs am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @@ -1105,8 +1347,8 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): config.h: stamp-h1 - @if test ! -f $@; then rm -f stamp-h1; else :; fi - @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 @@ -1136,6 +1378,7 @@ pcre_stringpiece.h: $(top_builddir)/config.status $(srcdir)/pcre_stringpiece.h.i cd $(top_builddir) && $(SHELL) ./config.status $@ pcrecpparg.h: $(top_builddir)/config.status $(srcdir)/pcrecpparg.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ + install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ @@ -1162,20 +1405,27 @@ uninstall-libLTLIBRARIES: clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + libpcre.la: $(libpcre_la_OBJECTS) $(libpcre_la_DEPENDENCIES) $(EXTRA_libpcre_la_DEPENDENCIES) $(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) $(EXTRA_libpcre16_la_DEPENDENCIES) $(AM_V_CCLD)$(libpcre16_la_LINK) $(am_libpcre16_la_rpath) $(libpcre16_la_OBJECTS) $(libpcre16_la_LIBADD) $(LIBS) + libpcre32.la: $(libpcre32_la_OBJECTS) $(libpcre32_la_DEPENDENCIES) $(EXTRA_libpcre32_la_DEPENDENCIES) $(AM_V_CCLD)$(libpcre32_la_LINK) $(am_libpcre32_la_rpath) $(libpcre32_la_OBJECTS) $(libpcre32_la_LIBADD) $(LIBS) + libpcrecpp.la: $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_DEPENDENCIES) $(EXTRA_libpcrecpp_la_DEPENDENCIES) $(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) $(EXTRA_libpcreposix_la_DEPENDENCIES) $(AM_V_CCLD)$(libpcreposix_la_LINK) $(am_libpcreposix_la_rpath) $(libpcreposix_la_OBJECTS) $(libpcreposix_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @@ -1187,10 +1437,12 @@ install-binPROGRAMS: $(bin_PROGRAMS) fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p || test -f $$p1; \ - then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -1211,7 +1463,8 @@ uninstall-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ + -e 's/$$/$(EXEEXT)/' \ + `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files @@ -1233,24 +1486,31 @@ clean-noinstPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list + dftables$(EXEEXT): $(dftables_OBJECTS) $(dftables_DEPENDENCIES) $(EXTRA_dftables_DEPENDENCIES) @rm -f dftables$(EXEEXT) $(AM_V_CCLD)$(LINK) $(dftables_OBJECTS) $(dftables_LDADD) $(LIBS) + pcre_jit_test$(EXEEXT): $(pcre_jit_test_OBJECTS) $(pcre_jit_test_DEPENDENCIES) $(EXTRA_pcre_jit_test_DEPENDENCIES) @rm -f pcre_jit_test$(EXEEXT) $(AM_V_CCLD)$(pcre_jit_test_LINK) $(pcre_jit_test_OBJECTS) $(pcre_jit_test_LDADD) $(LIBS) + pcre_scanner_unittest$(EXEEXT): $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_DEPENDENCIES) $(EXTRA_pcre_scanner_unittest_DEPENDENCIES) @rm -f pcre_scanner_unittest$(EXEEXT) $(AM_V_CXXLD)$(pcre_scanner_unittest_LINK) $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_LDADD) $(LIBS) + pcre_stringpiece_unittest$(EXEEXT): $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_DEPENDENCIES) $(EXTRA_pcre_stringpiece_unittest_DEPENDENCIES) @rm -f pcre_stringpiece_unittest$(EXEEXT) $(AM_V_CXXLD)$(pcre_stringpiece_unittest_LINK) $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_LDADD) $(LIBS) + pcrecpp_unittest$(EXEEXT): $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_DEPENDENCIES) $(EXTRA_pcrecpp_unittest_DEPENDENCIES) @rm -f pcrecpp_unittest$(EXEEXT) $(AM_V_CXXLD)$(pcrecpp_unittest_LINK) $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_LDADD) $(LIBS) + pcregrep$(EXEEXT): $(pcregrep_OBJECTS) $(pcregrep_DEPENDENCIES) $(EXTRA_pcregrep_DEPENDENCIES) @rm -f pcregrep$(EXEEXT) $(AM_V_CCLD)$(pcregrep_LINK) $(pcregrep_OBJECTS) $(pcregrep_LDADD) $(LIBS) + pcretest$(EXEEXT): $(pcretest_OBJECTS) $(pcretest_DEPENDENCIES) $(EXTRA_pcretest_DEPENDENCIES) @rm -f pcretest$(EXEEXT) $(AM_V_CCLD)$(pcretest_LINK) $(pcretest_OBJECTS) $(pcretest_LDADD) $(LIBS) @@ -1383,14 +1643,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @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 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -2264,26 +2524,15 @@ uninstall-nodist_includeHEADERS: files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -2295,15 +2544,11 @@ TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -2312,117 +2557,231 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - $(am__tty_colors); \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - col=$$red; res=XPASS; \ - ;; \ - *) \ - col=$$grn; res=PASS; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xfail=`expr $$xfail + 1`; \ - col=$$lgn; res=XFAIL; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - col=$$red; res=FAIL; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - col=$$blu; res=SKIP; \ - fi; \ - echo "$${col}$$res$${std}: $$tst"; \ +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + else \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ - if test "$$all" -eq 1; then \ - tests="test"; \ - All=""; \ - else \ - tests="tests"; \ - All="All "; \ - fi; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="$$All$$all $$tests passed"; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ else \ - if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ - banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all $$tests failed"; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ else \ - if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ - banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + color_start= color_end=; \ fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - skipped="($$skip test was not run)"; \ - else \ - skipped="($$skip tests were not run)"; \ - fi; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - if test "$$failed" -eq 0; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - fi; \ - echo "$${col}$$dashes$${std}"; \ - echo "$${col}$$banner$${std}"; \ - test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ - test -z "$$report" || echo "$${col}$$report$${std}"; \ - echo "$${col}$$dashes$${std}"; \ - test "$$failed" -eq 0; \ - else :; fi + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_SCRIPTS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +pcre_jit_test.log: pcre_jit_test$(EXEEXT) + @p='pcre_jit_test$(EXEEXT)'; \ + b='pcre_jit_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +pcrecpp_unittest.log: pcrecpp_unittest$(EXEEXT) + @p='pcrecpp_unittest$(EXEEXT)'; \ + b='pcrecpp_unittest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +pcre_scanner_unittest.log: pcre_scanner_unittest$(EXEEXT) + @p='pcre_scanner_unittest$(EXEEXT)'; \ + b='pcre_scanner_unittest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +pcre_stringpiece_unittest.log: pcre_stringpiece_unittest$(EXEEXT) + @p='pcre_stringpiece_unittest$(EXEEXT)'; \ + b='pcre_stringpiece_unittest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +RunTest.log: RunTest + @p='RunTest'; \ + b='RunTest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +RunGrepTest.log: RunGrepTest + @p='RunGrepTest'; \ + b='RunGrepTest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) - @list='$(MANS)'; if test -n "$$list"; then \ - list=`for p in $$list; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ - if test -n "$$list" && \ - grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ - echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ - grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ - echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ - echo " typically \`make maintainer-clean' will remove them" >&2; \ - exit 1; \ - else :; fi; \ - else :; fi $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -2463,41 +2822,40 @@ distdir: $(DISTFILES) || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__remove_distdir) + $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__remove_distdir) - -dist-lzma: distdir - tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma - $(am__remove_distdir) + $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-tarZ: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) + $(am__post_remove_distdir) dist-shar: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) + $(am__post_remove_distdir) -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another @@ -2508,8 +2866,6 @@ distcheck: dist GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lzma*) \ - lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ @@ -2521,18 +2877,19 @@ distcheck: dist *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir); chmod u+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + && ../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ @@ -2555,7 +2912,7 @@ distcheck: dist && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 - $(am__remove_distdir) + $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' @@ -2619,6 +2976,9 @@ install-strip: "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) @@ -2632,8 +2992,8 @@ maintainer-clean-generic: @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) -@WITH_GCOV_FALSE@distclean-local: @WITH_GCOV_FALSE@clean-local: +@WITH_GCOV_FALSE@distclean-local: clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ @@ -2721,32 +3081,34 @@ uninstall-man: uninstall-man1 uninstall-man3 .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 \ - clean-libtool clean-local clean-noinstPROGRAMS ctags dist \ - dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \ - dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-libtool distclean-local 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-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 \ +.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \ + check-am clean clean-binPROGRAMS clean-cscope clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-local \ + clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-local 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-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 \ install-pkgconfigDATA install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-binPROGRAMS \ - uninstall-binSCRIPTS uninstall-dist_docDATA \ - uninstall-dist_htmlDATA uninstall-htmlDATA \ - uninstall-includeHEADERS uninstall-libLTLIBRARIES \ - uninstall-man uninstall-man1 uninstall-man3 \ - uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA + recheck tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-binSCRIPTS \ + uninstall-dist_docDATA uninstall-dist_htmlDATA \ + uninstall-htmlDATA uninstall-includeHEADERS \ + uninstall-libLTLIBRARIES uninstall-man uninstall-man1 \ + uninstall-man3 uninstall-nodist_includeHEADERS \ + uninstall-pkgconfigDATA # The only difference between pcre.h.in and pcre.h is the setting of the PCRE @@ -2756,14 +3118,16 @@ pcre.h.generic: pcre.h.in configure.ac cp -p pcre.h $@ # It is more complicated for config.h.generic. We need the version that results -# from a default configuration. We can get this by doing a configure in a -# temporary directory. However, some trickery is needed, -# because the source directory may already be configured. If you -# just try running configure in a new directory, it complains. For this reason, -# we move config.status out of the way while doing the default configuration. -# The resulting config.h is munged by perl to put #ifdefs round any #defines -# and to get rid of any gcc-specific visibility settings. Make sure that -# PCRE_EXP_DEFN is unset (in case it has visibility settings). +# from a default configuration so as to get all the default values for PCRE +# configuration macros such as MATCH_LIMIT and NEWLINE. We can get this by +# doing a configure in a temporary directory. However, some trickery is needed, +# because the source directory may already be configured. If you just try +# running configure in a new directory, it complains. For this reason, we move +# config.status out of the way while doing the default configuration. The +# resulting config.h is munged by perl to put #ifdefs round any #defines for +# macros with values, and to #undef all boolean macros such as HAVE_xxx and +# SUPPORT_xxx. We also get rid of any gcc-specific visibility settings. Make +# sure that PCRE_EXP_DEFN is unset (in case it has visibility settings). config.h.generic: configure.ac rm -rf $@ _generic mkdir _generic @@ -2776,8 +3140,10 @@ config.h.generic: configure.ac -e 'if(/PCRE_EXP_DEFN/){print"/* #undef PCRE_EXP_DEFN */\n";$$blank=0;next;}' \ -e 'if(/to make a symbol visible/){next;}' \ -e 'if(/__attribute__ \(\(visibility/){next;}' \ - -e 'if(/^#define\s(?!PACKAGE)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;}' \ - -e 'else {if(/^\s*$$/){print unless $$blank; $$blank=1;} else{print;$$blank=0;}}' \ + -e 'if(/LT_OBJDIR/){print"/* This is ignored unless you are using libtool. */\n";}' \ + -e 'if(/^#define\s((?:HAVE|SUPPORT|STDC)_\w+)/){print"/* #undef $$1 */\n";$$blank=0;next;}' \ + -e 'if(/^#define\s(?!PACKAGE|VERSION)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;next;}' \ + -e 'if(/^\s*$$/){print unless $$blank; $$blank=1;} else{print;$$blank=0;}' \ _generic/config.h >$@ rm -rf _generic diff --git a/tools/pcre/NEWS b/tools/pcre/NEWS index ebd9c5ec..6331e990 100644 --- a/tools/pcre/NEWS +++ b/tools/pcre/NEWS @@ -1,6 +1,88 @@ News about PCRE releases ------------------------ +Release 8.35 04-April-2014 +-------------------------- + +There have been performance improvements for classes containing non-ASCII +characters and the "auto-possessification" feature has been extended. Other +minor improvements have been implemented and bugs fixed. There is a new callout +feature to enable applications to do detailed stack checks at compile time, to +avoid running out of stack for deeply nested parentheses. The JIT compiler has +been extended with experimental support for ARM-64, MIPS-64, and PPC-LE. + + +Release 8.34 15-December-2013 +----------------------------- + +As well as fixing the inevitable bugs, performance has been improved by +refactoring and extending the amount of "auto-possessification" that PCRE does. +Other notable changes: + +. Implemented PCRE_INFO_MATCH_EMPTY, which yields 1 if the pattern can match + an empty string. If it can, pcretest shows this in its information output. + +. A back reference to a named subpattern when there is more than one of the + same name now checks them in the order in which they appear in the pattern. + The first one that is set is used for the reference. Previously only the + first one was inspected. This change makes PCRE more compatible with Perl. + +. Unicode character properties were updated from Unicode 6.3.0. + +. The character VT has been added to the set of characters that match \s and + are generally treated as white space, following this same change in Perl + 5.18. There is now no difference between "Perl space" and "POSIX space". + +. Perl has changed its handling of \8 and \9. If there is no previously + encountered capturing group of those numbers, they are treated as the + literal characters 8 and 9 instead of a binary zero followed by the + literals. PCRE now does the same. + +. Following Perl, added \o{} to specify codepoints in octal, making it + possible to specify values greater than 0777 and also making them + unambiguous. + +. In UCP mode, \s was not matching two of the characters that Perl matches, + namely NEL (U+0085) and MONGOLIAN VOWEL SEPARATOR (U+180E), though they + were matched by \h. + +. Add JIT support for the 64 bit TileGX architecture. + +. Upgraded the handling of the POSIX classes [:graph:], [:print:], and + [:punct:] when PCRE_UCP is set so as to include the same characters as Perl + does in Unicode mode. + +. Perl no longer allows group names to start with digits, so I have made this + change also in PCRE. + +. Added support for [[:<:]] and [[:>:]] as used in the BSD POSIX library to + mean "start of word" and "end of word", respectively, as a transition aid. + + +Release 8.33 28-May-2013 +-------------------------- + +A number of bugs are fixed, and some performance improvements have been made. +There are also some new features, of which these are the most important: + +. The behaviour of the backtracking verbs has been rationalized and + documented in more detail. + +. JIT now supports callouts and all of the backtracking verbs. + +. Unicode validation has been updated in the light of Unicode Corrigendum #9, + which points out that "non characters" are not "characters that may not + appear in Unicode strings" but rather "characters that are reserved for + internal use and have only local meaning". + +. (*LIMIT_MATCH=d) and (*LIMIT_RECURSION=d) have been added so that the + creator of a pattern can specify lower (but not higher) limits for the + matching process. + +. The PCRE_NEVER_UTF option is available to prevent pattern-writers from using + the (*UTF) feature, as this could be a security issue. + + Release 8.32 30-November-2012 ----------------------------- @@ -591,7 +673,7 @@ some of the new functionality in Perl 5.005. Another (I hope this is the last!) change has been made to the API for the pcre_compile() function. An additional argument has been added to make it possible to pass over a pointer to character tables built in the current -locale by pcre_maketables(). To use the default tables, this new arguement +locale by pcre_maketables(). To use the default tables, this new argument should be passed as NULL. IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.05 diff --git a/tools/pcre/NON-AUTOTOOLS-BUILD b/tools/pcre/NON-AUTOTOOLS-BUILD index a4e2e463..cddf3e06 100644 --- a/tools/pcre/NON-AUTOTOOLS-BUILD +++ b/tools/pcre/NON-AUTOTOOLS-BUILD @@ -9,11 +9,14 @@ This document contains the following sections: Building for virtual Pascal Stack size in Windows environments Linking programs in Windows environments + Calling conventions 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 CE with Visual Studio 200x Building under Windows with BCC5.5 + Building using Borland C++ Builder 2007 (CB2007) and higher Building PCRE on OpenVMS Building PCRE on Stratus OpenVOS Building PCRE on native z/OS and z/VM @@ -168,8 +171,8 @@ can skip ahead to the CMake section. pcre16_version.c pcre16_xclass.c - (7') If you want to build a 16-bit library (as well as, or instead of the 8-bit - or 32-bit libraries) repeat steps 5-6 with the following files: + (8) If you want to build a 32-bit library (as well as, or instead of the 8-bit + or 16-bit libraries) repeat steps 5-6 with the following files: pcre32_byte_order.c pcre32_chartables.c @@ -194,30 +197,31 @@ can skip ahead to the CMake section. pcre32_version.c pcre32_xclass.c - (8) If you want to build the POSIX wrapper functions (which apply only to the + (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. - (9) The pcretest program can be linked with any combination of the 8-bit, 16-bit - and 32-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. +(10) The pcretest program can be linked with any combination of the 8-bit, + 16-bit and 32-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. -(10) Run pcretest on the testinput files in the testdata directory, and check +(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 more than one of the 8-bit, 16-bit and - 32-bit libraries, you need to run pcretest with the -16 option to do 16-bit - tests and with the -32 option to do 32-bit tests. + 32-bit libraries, you need to run pcretest with the -16 option to do + 16-bit tests and with the -32 option to do 32-bit tests. Some tests are relevant only when certain build-time options are selected. - For example, test 4 is for UTF-8/UTF-16/UTF-32 support, and will not run if - you have built PCRE without it. See the comments at the start of each + For example, test 4 is for UTF-8/UTF-16/UTF-32 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. + will run the appropriate tests for you. The command "RunTest list" will + output a list of all the tests. 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 @@ -227,11 +231,11 @@ can skip ahead to the CMake section. locale to "french" rather than "fr_FR", and there some minor output differences. -(11) If you have built PCRE with SUPPORT_JIT, the JIT features will be tested +(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. + the freestanding JIT test program, pcre_jit_test.c. -(12) If you want to use the pcregrep command, compile and link pcregrep.c; it +(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). @@ -428,16 +432,13 @@ CMake build process. In the CMake GUI, the cache can be deleted by selecting USE OF RELATIVE PATHS WITH CMAKE ON WINDOWS -A PCRE user comments as follows: +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: -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) + first path - see below) -- Only some of the contained file paths are modified - shown below for -pcre.vcproj + pcre.vcproj -- It properly modifies I am sure CMake people can fix that if they want to. Until then one will @@ -449,9 +450,9 @@ 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"> +RelativePath="pcre.h" +RelativePath="pcre_chartables.c" +RelativePath="pcre_chartables.c.rule" TESTING WITH RUNTEST.BAT @@ -489,20 +490,6 @@ 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 @@ -510,11 +497,149 @@ can be found in the file "pcre-vsbuild.zip" in the Contrib directory of the FTP site. +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 USING BORLAND C++ BUILDER 2007 (CB2007) AND HIGHER + +A PCRE user sent these comments about this environment (see also the comment +from another user that follows them): + +The XE versions of C++ Builder come with a RegularExpressionsCore class which +contain a version of TPerlRegEx. However, direct use of the C PCRE library may +be desirable. + +The default makevp.bat, however, supplied with PCRE builds a version of PCRE +that is not usable with any version of C++ Builder because the compiler ships +with an embedded version of PCRE, version 2.01 from 1998! [See also the note +about BCC5.5 above.] If you want to use PCRE you'll need to rename the +functions (pcre_compile to pcre_compile_bcc, etc) or do as I have done and just +use the 16 bit versions. I'm using std::wstring everywhere anyway. Since the +embedded version of PCRE does not have the 16 bit function names, there is no +conflict. + +Building PCRE using a C++ Builder static library project file (recommended): + +1. Rename or remove pcre.h, pcreposi.h, and pcreposix.h from your C++ Builder +original include path. + +2. Download PCRE from pcre.org and extract to a directory. + +3. Rename pcre_chartables.c.dist to pcre_chartables.c, pcre.h.generic to +pcre.h, and config.h.generic to config.h. + +4. Edit pcre.h and pcre_config.c so that they include config.h. + +5. Edit config.h like so: + +Comment out the following lines: +#define PACKAGE "pcre" +#define PACKAGE_BUGREPORT "" +#define PACKAGE_NAME "PCRE" +#define PACKAGE_STRING "PCRE 8.32" +#define PACKAGE_TARNAME "pcre" +#define PACKAGE_URL "" +#define PACKAGE_VERSION "8.32" + +Add the following lines: +#ifndef SUPPORT_UTF +#define SUPPORT_UTF 100 // any value is fine +#endif + +#ifndef SUPPORT_UCP +#define SUPPORT_UCP 101 // any value is fine +#endif + +#ifndef SUPPORT_UCP +#define SUPPORT_PCRE16 102 // any value is fine +#endif + +#ifndef SUPPORT_UTF8 +#define SUPPORT_UTF8 103 // any value is fine +#endif + +6. Build a C++ Builder project using the IDE. Go to File / New / Other and +choose Static Library. You can name it pcre.cbproj or whatever. Now set your +paths by going to Project / Options. Set the Include path. Do this from the +"Base" option to apply to both Release and Debug builds. Now add the following +files to the project: + +pcre.h +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_maketables.c +pcre16_newline.c +pcre16_ord2utf16.c +pcre16_printint.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 + +//Optional +pcre_version.c + +7. After compiling the .lib file, copy the .lib and header files to a project +you want to use PCRE with. Enjoy. + +Optional ... Building PCRE using the makevp.bat file: + +1. Edit makevp_c.txt and makevp_l.txt and change all the names to the 16 bit +versions. + +2. Edit makevp.bat and set the path to C++ Builder. Run makevp.bat. + +Another PCRE user added this comment: + +Another approach I successfully used for some years with BCB 5 and 6 was to +make sure that include and library paths of PCRE are configured before the +default paths of the IDE in the dialogs where one can manage those paths. +Afterwards one can open the project files using a text editor and manually add +the self created library for pcre itself, pcrecpp doesn't ship with the IDE, in +the library nodes where the IDE manages its own libraries to link against in +front of the IDE-own libraries. This way one can use the default PCRE function +names without getting access violations on runtime. + + + + 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. +Stephen Hoffman sent the following, in December 2012: + +"Here is a very short write-up on the +OpenVMS port and here + + + +is a zip with the OpenVMS files, and with one modified testing-related PCRE +file." This is a port of PCRE 8.32. + +Earlier, 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 @@ -636,4 +761,4 @@ There is also a mirror here: http://www.vsoft-software.com/downloads.html ========================== -Last Updated: 21 November 2012 +Last Updated: 14 May 2013 diff --git a/tools/pcre/PrepareRelease b/tools/pcre/PrepareRelease index 4ec803e5..9891e08d 100644 --- a/tools/pcre/PrepareRelease +++ b/tools/pcre/PrepareRelease @@ -25,6 +25,12 @@ # when the HTML documentation is built. It works like this so that # doc/html can be deleted and re-created from scratch. +# README & NON-AUTOTOOLS-BUILD +# These files are copied into the doc/html directory, with .txt +# extensions so that they can by hyperlinked from the HTML +# documentation, because some people just go to the HTML without +# looking for text files. + # First, sort out the documentation. Remove pcredemo.3 first because it won't # pass the markup check (it is created below, using markup that none of the @@ -122,6 +128,8 @@ if [ $? != 0 ] ; then exit 1; fi echo "Making HTML documentation" /bin/rm html/* cp index.html.src html/index.html +cp ../README html/README.txt +cp ../NON-AUTOTOOLS-BUILD html/NON-AUTOTOOLS-BUILD.txt for file in *.1 ; do base=`basename $file .1` @@ -218,7 +226,6 @@ files="\ pcre_string_utils.c \ pcre_study.c \ pcre_tables.c \ - pcre_ucp_searchfuncs.c \ pcre_valid_utf8.c \ pcre_version.c \ pcre_xclass.c \ @@ -238,8 +245,6 @@ files="\ pcre_stringpiece_unittest.cc \ perltest.pl \ ucp.h \ - ucpinternal.h \ - ucptable.h \ makevp.bat \ pcre.def \ libpcre.def \ diff --git a/tools/pcre/README b/tools/pcre/README index a2c3d9b3..88f2dfd4 100644 --- a/tools/pcre/README +++ b/tools/pcre/README @@ -9,8 +9,10 @@ from: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.zip There is a mailing list for discussion about the development of PCRE at +pcre-dev@exim.org. You can access the archives and subscribe or manage your +subscription here: - pcre-dev@exim.org + https://lists.exim.org/mailman/listinfo/pcre-dev Please read the NEWS file if you are upgrading from a previous release. The contents of this README file are: @@ -25,6 +27,8 @@ The contents of this README file are: Shared libraries Cross-compiling using autotools Using HP's ANSI C++ compiler (aCC) + Compiling in Tru64 using native compilers + Using Sun's compilers for Solaris Using PCRE from MySQL Making new tarballs Testing PCRE @@ -35,10 +39,10 @@ The contents of this README file are: The PCRE APIs ------------- -PCRE is written in C, and it has its own API. There are three sets of functions, -one for the 8-bit library, which processes strings of bytes, one for the -16-bit library, which processes strings of 16-bit values, and one for the 32-bit -library, which processes strings of 32-bit values. The distribution also +PCRE is written in C, and it has its own API. There are three sets of +functions, one for the 8-bit library, which processes strings of bytes, one for +the 16-bit library, which processes strings of 16-bit values, and one for the +32-bit library, which processes strings of 32-bit values. The distribution also includes a set of C++ wrapper functions (see the pcrecpp man page for details), courtesy of Google Inc., which can be used to call the 8-bit PCRE library from C++. @@ -81,11 +85,12 @@ documentation is supplied in two other forms: 1. There are files called doc/pcre.txt, doc/pcregrep.txt, and doc/pcretest.txt in the source distribution. The first of these is a concatenation of the text forms of all the section 3 man pages except - those that summarize individual functions. The other two are the text - forms of the section 1 man pages for the pcregrep and pcretest commands. - These text forms are provided for ease of scanning with text editors or - similar tools. They are installed in /share/doc/pcre, where - is the installation prefix (defaulting to /usr/local). + the listing of pcredemo.c and those that summarize individual functions. + The other two are the text forms of the section 1 man pages for the + pcregrep and pcretest commands. These text forms are provided for ease of + scanning with text editors or similar tools. They are installed in + /share/doc/pcre, where is the installation prefix + (defaulting to /usr/local). 2. A set of files containing all the documentation in HTML form, hyperlinked in various ways, and rooted in a file called index.html, is distributed in @@ -110,6 +115,11 @@ contributions provided support for compiling PCRE on various flavours of Windows (I myself do not use Windows). Nowadays there is more Windows support in the standard distribution, so these contibutions have been archived. +A PCRE user maintains downloadable Windows binaries of the pcregrep and +pcretest programs here: + + http://www.rexegg.com/pcregrep-pcretest.html + Building PCRE on non-Unix-like systems -------------------------------------- @@ -260,9 +270,17 @@ library. They are also documented in the pcrebuild man page. on the "configure" command. -. PCRE has a counter that can be set to limit the amount of resources it uses. - If the limit is exceeded during a match, the match fails. The default is ten - million. You can change the default by setting, for example, +. PCRE has a counter that limits the depth of nesting of parentheses in a + pattern. This limits the amount of system stack that a pattern uses when it + is compiled. The default is 250, but you can change it by setting, for + example, + + --with-parens-nest-limit=500 + +. PCRE has a counter that can be set to limit the amount of resources it uses + when matching a pattern. If the limit is exceeded during a match, the match + fails. The default is ten million. You can change the default by setting, for + example, --with-match-limit=500000 @@ -342,7 +360,8 @@ library. They are also documented in the pcrebuild man page. report is generated by running "make coverage". If ccache is installed on your system, it must be disabled when building PCRE for coverage reporting. You can do this by setting the environment variable CCACHE_DISABLE=1 before - running "make" to build PCRE. + running "make" to build PCRE. There is more information about coverage + reporting in the "pcrebuild" documentation. . The pcregrep program currently supports only 8-bit data files, and so requires the 8-bit PCRE library. It is possible to compile pcregrep to use @@ -354,12 +373,12 @@ library. They are also documented in the pcrebuild man page. 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: +. The default size (in bytes) of the internal buffer used by pcregrep can be + set by, for example: - --with-pcregrep-bufsize=50K + --with-pcregrep-bufsize=51200 - The default value is 20K. + The value must be a plain integer. The default is 20480. . It is possible to compile pcretest so that it links with the libreadline or libedit libraries, by specifying, respectively, @@ -575,6 +594,27 @@ running the "configure" script: CXXLDFLAGS="-lstd_v2 -lCsup_v2" +Compiling in Tru64 using native compilers +----------------------------------------- + +The following error may occur when compiling with native compilers in the Tru64 +operating system: + + CXX libpcrecpp_la-pcrecpp.lo +cxx: Error: /usr/lib/cmplrs/cxx/V7.1-006/include/cxx/iosfwd, line 58: #error + directive: "cannot include iosfwd -- define __USE_STD_IOSTREAM to + override default - see section 7.1.2 of the C++ Using Guide" +#error "cannot include iosfwd -- define __USE_STD_IOSTREAM to override default +- see section 7.1.2 of the C++ Using Guide" + +This may be followed by other errors, complaining that 'namespace "std" has no +member'. The solution to this is to add the line + +#define __USE_STD_IOSTREAM 1 + +to the config.h file. + + Using Sun's compilers for Solaris --------------------------------- @@ -624,27 +664,40 @@ NON-AUTOTOOLS-BUILD. The RunTest script runs the pcretest test program (which is documented in its own man page) on each of the relevant testinput files in the testdata directory, and compares the output with the contents of the corresponding -testoutput files. Some tests are relevant only when certain build-time options -were selected. For example, the tests for UTF-8/16/32 support are run only if ---enable-utf was used. RunTest outputs a comment when it skips a test. +testoutput files. RunTest uses a file called testtry to hold the main output +from pcretest. Other files whose names begin with "test" are used as working +files in some tests. + +Some tests are relevant only when certain build-time options were selected. For +example, the tests for UTF-8/16/32 support are run only if --enable-utf was +used. RunTest outputs a comment when it skips a test. Many of the tests that are not skipped are run up to three times. The second run forces pcre_study() to be called for all patterns except for a few in some tests that are marked "never study" (see the pcretest program for how this is done). If JIT support is available, the non-DFA tests are run a third time, this time with a forced pcre_study() with the PCRE_STUDY_JIT_COMPILE option. +This testing can be suppressed by putting "nojit" on the RunTest command line. The entire set of tests is run once for each of the 8-bit, 16-bit and 32-bit libraries that are enabled. If you want to run just one set of tests, call RunTest with either the -8, -16 or -32 option. -RunTest uses a file called testtry to hold the main output from pcretest. -Other files whose names begin with "test" are used as working files in some -tests. To run pcretest on just one or more specific test files, give their -numbers as arguments to RunTest, for example: +If valgrind is installed, you can run the tests under it by putting "valgrind" +on the RunTest command line. To run pcretest on just one or more specific test +files, give their numbers as arguments to RunTest, for example: RunTest 2 7 11 +You can also specify ranges of tests such as 3-6 or 3- (meaning 3 to the +end), or a number preceded by ~ to exclude a test. For example: + + Runtest 3-15 ~10 + +This runs tests 3 to 15, excluding test 10, and just ~13 runs all the tests +except test 13. Whatever order the arguments are in, the tests are always run +in numerical order. + You can also call RunTest with the single argument "list" to cause it to output a list of tests. @@ -704,21 +757,24 @@ test is run only when JIT support is not available. They test some JIT-specific features such as information output from pcretest about JIT compilation. The fourteenth, fifteenth, and sixteenth tests are run only in 8-bit mode, and -the seventeenth, eighteenth, and nineteenth tests are run only in 16/32-bit mode. -These are tests that generate different output in the two modes. They are for -general cases, UTF-8/16/32 support, and Unicode property support, respectively. +the seventeenth, eighteenth, and nineteenth tests are run only in 16/32-bit +mode. These are tests that generate different output in the two modes. They are +for general cases, UTF-8/16/32 support, and Unicode property support, +respectively. The twentieth test is run only in 16/32-bit mode. It tests some specific 16/32-bit features of the DFA matching engine. -The twenty-first and twenty-second tests are run only in 16/32-bit mode, when the -link size is set to 2 for the 16-bit library. They test reloading pre-compiled patterns. +The twenty-first and twenty-second tests are run only in 16/32-bit mode, when +the link size is set to 2 for the 16-bit library. They test reloading +pre-compiled patterns. -The twenty-third and twenty-fourth tests are run only in 16-bit mode. They are for -general cases, and UTF-16 support, respectively. +The twenty-third and twenty-fourth tests are run only in 16-bit mode. They are +for general cases, and UTF-16 support, respectively. + +The twenty-fifth and twenty-sixth tests are run only in 32-bit mode. They are +for general cases, and UTF-32 support, respectively. -The twenty-fifth and twenty-sixth tests are run only in 32-bit mode. They are for -general cases, and UTF-32 support, respectively. Character tables ---------------- @@ -784,11 +840,11 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx. (A) Source files of the PCRE library functions and their headers: dftables.c auxiliary program for building pcre_chartables.c - when --enable-rebuild-chartables is specified + when --enable-rebuild-chartables is specified pcre_chartables.c.dist a default set of character tables that assume ASCII - coding; used, unless --enable-rebuild-chartables is - specified, by copying to pcre[16]_chartables.c + coding; used, unless --enable-rebuild-chartables is + specified, by copying to pcre[16]_chartables.c pcreposix.c ) pcre[16|32]_byte_order.c ) @@ -932,4 +988,4 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx. Philip Hazel Email local part: ph10 Email domain: cam.ac.uk -Last updated: 27 October 2012 +Last updated: 17 January 2014 diff --git a/tools/pcre/RunGrepTest b/tools/pcre/RunGrepTest index 94fd808f..f1b03484 100644 --- a/tools/pcre/RunGrepTest +++ b/tools/pcre/RunGrepTest @@ -69,427 +69,447 @@ utf8=$? echo "Testing pcregrep main features" -echo "---------------------------- Test 1 ------------------------------" >testtry -(cd $srcdir; $valgrind $pcregrep PATTERN ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 1 ------------------------------" >testtrygrep +(cd $srcdir; $valgrind $pcregrep PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 2 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep '^PATTERN' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 2 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep '^PATTERN' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 3 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 3 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 4 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -ic PATTERN ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 4 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -ic PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 5 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 5 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 6 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 6 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 7 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 7 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 8 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 8 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 9 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 9 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 10 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 10 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 11 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -vn pattern ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 11 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -vn pattern ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 12 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -ix pattern ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 12 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -ix pattern ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 13 -----------------------------" >>testtry -echo seventeen >testtemp1 -(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist -f $builddir/testtemp1 ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 13 -----------------------------" >>testtrygrep +echo seventeen >testtemp1grep +(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist -f $builddir/testtemp1grep ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 14 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 14 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 15 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep 'abc^*' ./testdata/grepinput) 2>>testtry >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 15 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep 'abc^*' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 16 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtry >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 16 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtrygrep >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 17 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -M 'the\noutput' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 17 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -M 'the\noutput' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 18 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 18 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 19 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -Mix 'Pattern' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 19 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -Mix 'Pattern' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 20 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 20 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 21 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -nA3 'four' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 21 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -nA3 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 22 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -nB3 'four' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 22 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -nB3 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 23 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -C3 'four' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 23 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -C3 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 24 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -A9 'four' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 24 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -A9 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 25 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -nB9 'four' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 25 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -nB9 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 26 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -A9 -B9 'four' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 26 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -A9 -B9 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 27 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -A10 'four' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 27 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -A10 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 28 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -nB10 'four' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 28 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -nB10 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 29 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -C12 -B10 'four' ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 29 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -C12 -B10 'four' ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 30 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 30 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 31 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 31 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 32 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 32 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 33 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep 'fox' ./testdata/grepnonexist) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 33 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 34 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -s 'fox' ./testdata/grepnonexist) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 34 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -s 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 35 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --include grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 35 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --include grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 36 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 36 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 37 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep '^(a+)*\d' ./testdata/grepinput) >>testtry 2>teststderr -echo "RC=$?" >>testtry -echo "======== STDERR ========" >>testtry -cat teststderr >>testtry +echo "---------------------------- Test 37 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep '^(a+)*\d' ./testdata/grepinput) >>testtrygrep 2>teststderrgrep +echo "RC=$?" >>testtrygrep +echo "======== STDERR ========" >>testtrygrep +cat teststderrgrep >>testtrygrep -echo "---------------------------- Test 38 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep '>\x00<' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 38 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep '>\x00<' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 39 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -A1 'before the binary zero' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 39 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -A1 'before the binary zero' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 40 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -B1 'after the binary zero' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 40 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -B1 'after the binary zero' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 41 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 41 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 42 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 42 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 43 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -on 'before|zero|after' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 43 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -on 'before|zero|after' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 44 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -on -e before -ezero -e after ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 44 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -on -e before -ezero -e after ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 45 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 45 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 46 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -eabc -e '(unclosed' ./testdata/grepinput) 2>>testtry >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 46 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -eabc -e '(unclosed' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 47 ------------------------------" >>testtry +echo "---------------------------- Test 47 ------------------------------" >>testtrygrep (cd $srcdir; $valgrind $pcregrep -Fx "AB.VE -elephant" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +elephant" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 48 ------------------------------" >>testtry +echo "---------------------------- Test 48 ------------------------------" >>testtrygrep (cd $srcdir; $valgrind $pcregrep -F "AB.VE -elephant" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +elephant" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 49 ------------------------------" >>testtry +echo "---------------------------- Test 49 ------------------------------" >>testtrygrep (cd $srcdir; $valgrind $pcregrep -F -e DATA -e "AB.VE -elephant" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +elephant" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 50 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 50 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 51 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -Mv "brown\sfox" ./testdata/grepinputv) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 51 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -Mv "brown\sfox" ./testdata/grepinputv) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 52 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --colour=always jumps ./testdata/grepinputv) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 52 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --colour=always jumps ./testdata/grepinputv) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 53 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 53 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 54 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 54 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 55 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist --color=always ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 55 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist --color=always ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 56 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -c lazy ./testdata/grepinput*) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 56 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -c lazy ./testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 57 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -c -l lazy ./testdata/grepinput*) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 57 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -c -l lazy ./testdata/grepinput*) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 58 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --regex=PATTERN ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 58 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --regex=PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 59 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --regexp=PATTERN ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 59 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --regexp=PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 60 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --regex PATTERN ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 60 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --regex PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 61 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --regexp PATTERN ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 61 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --regexp PATTERN ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 62 -----------------------------" >>testtry -(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 62 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --match-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 63 -----------------------------" >>testtry -(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 63 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --recursion-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 64 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o1 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 64 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o1 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 65 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 65 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 66 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o3 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 66 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o3 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 67 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o12 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 67 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o12 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 68 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 68 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 69 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -vn --colour=always pattern ./testdata/grepinputx) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 69 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -vn --colour=always pattern ./testdata/grepinputx) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 70 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 70 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 71 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o "^01|^02|^03" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 71 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o "^01|^02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 72 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|^03" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 72 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 73 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|^03" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 73 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 74 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o "^01|02|^03" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 74 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o "^01|02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 75 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --color=always "^01|02|^03" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 75 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --color=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 76 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|02|^03" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 76 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 77 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o "^01|^02|03" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 77 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o "^01|^02|03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 78 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|03" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 78 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 79 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|03" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 79 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 80 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o "\b01|\b02" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 80 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o "\b01|\b02" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 81 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --color=always "\\b01|\\b02" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 81 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --color=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 82 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o --colour=always "\\b01|\\b02" ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 82 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o --colour=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 83 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 83 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 84 -----------------------------" >>testtry -echo testdata/grepinput3 >testtemp1 -(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist --file-list $builddir/testtemp1 "fox|complete|t7") >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 84 -----------------------------" >>testtrygrep +echo testdata/grepinput3 >testtemp1grep +(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist --file-list $builddir/testtemp1grep "fox|complete|t7") >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 85 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 85 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 86 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep "dog" ./testdata/grepbinary) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 86 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 87 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep "cat" ./testdata/grepbinary) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 87 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep "cat" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 88 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -v "cat" ./testdata/grepbinary) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 88 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -v "cat" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 89 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -I "dog" ./testdata/grepbinary) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 89 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -I "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 90 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --binary-files=without-match "dog" ./testdata/grepbinary) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 90 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --binary-files=without-match "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 91 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -a "dog" ./testdata/grepbinary) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 91 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -a "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 92 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --binary-files=text "dog" ./testdata/grepbinary) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 92 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --binary-files=text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 93 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --text "dog" ./testdata/grepbinary) >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 93 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 94 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --include grepinput8 'fox' ./testdata/grepinput* | sort) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 94 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --include grepinput8 'fox' ./testdata/grepinput* | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 95 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist --exclude grepinputv "fox|complete") >>testtry 2>&1 -echo "RC=$?" >>testtry +echo "---------------------------- Test 95 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist --exclude grepinputv "fox|complete") >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 96 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -L -r --include-dir=testdata --exclude '^(?!grepinput)' 'fox' ./test* | sort) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 96 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -L -r --include-dir=testdata --exclude '^(?!grepinput)' 'fox' ./test* | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 97 -----------------------------" >>testtry -echo "grepinput$" >testtemp1 -echo "grepinput8" >>testtemp1 -(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude-from $builddir/testtemp1 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 97 -----------------------------" >>testtrygrep +echo "grepinput$" >testtemp1grep +echo "grepinput8" >>testtemp1grep +(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 98 -----------------------------" >>testtry -echo "grepinput$" >testtemp1 -echo "grepinput8" >>testtemp1 -(cd $srcdir; $valgrind $pcregrep -L -r --exclude=grepinput3 --include=grepinput --exclude-from $builddir/testtemp1 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 98 -----------------------------" >>testtrygrep +echo "grepinput$" >testtemp1grep +echo "grepinput8" >>testtemp1grep +(cd $srcdir; $valgrind $pcregrep -L -r --exclude=grepinput3 --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 99 -----------------------------" >>testtry -echo "grepinput$" >testtemp1 -echo "grepinput8" >testtemp2 -(cd $srcdir; $valgrind $pcregrep -L -r --include grepinput --exclude-from $builddir/testtemp1 --exclude-from=$builddir/testtemp2 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 99 -----------------------------" >>testtrygrep +echo "grepinput$" >testtemp1grep +echo "grepinput8" >testtemp2grep +(cd $srcdir; $valgrind $pcregrep -L -r --include grepinput --exclude-from $builddir/testtemp1grep --exclude-from=$builddir/testtemp2grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 100 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -Ho2 --only-matching=1 -o3 '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 100 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -Ho2 --only-matching=1 -o3 '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep -echo "---------------------------- Test 101 ------------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep -o3 -Ho2 -o12 --only-matching=1 -o3 --colour=always --om-separator='|' '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtry -echo "RC=$?" >>testtry +echo "---------------------------- Test 101 ------------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -o3 -Ho2 -o12 --only-matching=1 -o3 --colour=always --om-separator='|' '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 102 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -n "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 103 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 104 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep -n --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 105 -----------------------------" >>testtrygrep +(cd $srcdir; $valgrind $pcregrep --colour=always "ipsum|" ./testdata/grepinput3) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep + +echo "---------------------------- Test 106 -----------------------------" >>testtrygrep +(cd $srcdir; echo "a" | $valgrind $pcregrep -M "|a" ) >>testtrygrep 2>&1 +echo "RC=$?" >>testtrygrep # Now compare the results. -$cf $srcdir/testdata/grepoutput testtry +$cf $srcdir/testdata/grepoutput testtrygrep if [ $? != 0 ] ; then exit 1; fi @@ -498,15 +518,15 @@ if [ $? != 0 ] ; then exit 1; fi if [ $utf8 -ne 0 ] ; then echo "Testing pcregrep UTF-8 features" - echo "---------------------------- Test U1 ------------------------------" >testtry - (cd $srcdir; $valgrind $pcregrep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtry - echo "RC=$?" >>testtry + echo "---------------------------- Test U1 ------------------------------" >testtrygrep + (cd $srcdir; $valgrind $pcregrep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtrygrep + echo "RC=$?" >>testtrygrep - echo "---------------------------- Test U2 ------------------------------" >>testtry - (cd $srcdir; $valgrind $pcregrep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtry - echo "RC=$?" >>testtry + echo "---------------------------- Test U2 ------------------------------" >>testtrygrep + (cd $srcdir; $valgrind $pcregrep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtrygrep + echo "RC=$?" >>testtrygrep - $cf $srcdir/testdata/grepoutput8 testtry + $cf $srcdir/testdata/grepoutput8 testtrygrep if [ $? != 0 ] ; then exit 1; fi else @@ -522,28 +542,28 @@ fi # starts with a hyphen. These tests are run in the build directory. echo "Testing pcregrep newline settings" -printf "abc\rdef\r\nghi\njkl" >testNinput +printf "abc\rdef\r\nghi\njkl" >testNinputgrep -printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtry -$valgrind $pcregrep -n -N CR "^(abc|def|ghi|jkl)" testNinput >>testtry +printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtrygrep +$valgrind $pcregrep -n -N CR "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep -printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtry -$valgrind $pcregrep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinput >>testtry +printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtrygrep +$valgrind $pcregrep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep -printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtry +printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtrygrep pattern=`printf 'def\rjkl'` -$valgrind $pcregrep -n --newline=cr -F "$pattern" testNinput >>testtry +$valgrind $pcregrep -n --newline=cr -F "$pattern" testNinputgrep >>testtrygrep -printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtry -$valgrind $pcregrep -n --newline=crlf -F -f $srcdir/testdata/greppatN4 testNinput >>testtry +printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtrygrep +$valgrind $pcregrep -n --newline=crlf -F -f $srcdir/testdata/greppatN4 testNinputgrep >>testtrygrep -printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtry -$valgrind $pcregrep -n --newline=any "^(abc|def|ghi|jkl)" testNinput >>testtry +printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtrygrep +$valgrind $pcregrep -n --newline=any "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep -printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtry -$valgrind $pcregrep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinput >>testtry +printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtrygrep +$valgrind $pcregrep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep -$cf $srcdir/testdata/grepoutputN testtry +$cf $srcdir/testdata/grepoutputN testtrygrep if [ $? != 0 ] ; then exit 1; fi exit 0 diff --git a/tools/pcre/RunTest b/tools/pcre/RunTest index 546e6e53..67cfbf07 100644 --- a/tools/pcre/RunTest +++ b/tools/pcre/RunTest @@ -1,5 +1,6 @@ #! /bin/sh +############################################################################### # Run the PCRE tests using the pcretest program. The appropriate tests are # selected, depending on which build-time options were used. # @@ -13,21 +14,38 @@ # 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. +# When JIT support is available, all appropriate tests are also run with -s+ to +# test (again, almost) everything with studying and the JIT option, unless +# "nojit" is given on the command line. There are also two tests for +# JIT-specific features, one to be run when JIT support is available (unless +# "nojit" is specified), and one when it is not. # # Whichever of the 8-, 16- and 32-bit libraries exist are tested. It is also -# possible to select which to test by the arguments -8, -16 or -32. +# possible to select which to test by giving "-8", "-16" or "-32" on the +# command line. # -# Other arguments for this script can be individual test numbers, or the word -# "valgrind", "valgrind-log" or "sim" followed by an argument to run cross- -# compiled executables under a simulator, for example: +# As well as "nojit", "-8", "-16", and "-32", arguments for this script are +# individual test numbers, ranges of tests such as 3-6 or 3- (meaning 3 to the +# end), or a number preceded by ~ to exclude a test. For example, "3-15 ~10" +# runs tests 3 to 15, excluding test 10, and just "~10" runs all the tests +# except test 10. Whatever order the arguments are in, the tests are always run +# in numerical order. +# +# The special argument "3S" runs test 3, stopping if it fails. Test 3 is the +# locale test, and failure usually means there's an issue with the locale +# rather than a bug in PCRE, so normally subsequent tests are run. "3S" is +# useful when you want to debug or update the test. +# +# Inappropriate tests are automatically skipped (with a comment to say so): for +# example, if JIT support is not compiled, test 12 is skipped, whereas if JIT +# support is compiled, test 13 is skipped. +# +# Other arguments can be one of the words "valgrind", "valgrind-log", or "sim" +# followed by an argument to run cross-compiled executables under a simulator, +# for example: # # RunTest 3 sim "qemu-arm -s 8388608" # -# # There are two special cases where only one argument is allowed: # # If the first and only argument is "ebcdic", the script runs the special @@ -36,7 +54,7 @@ # # 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. @@ -53,8 +71,8 @@ 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)" +title12="Test 12: JIT-specific features (when JIT is available)" +title13="Test 13: JIT-specific features (when JIT is 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" @@ -69,6 +87,8 @@ title24="Test 24: Specials for the 16-bit library with UTF-16 support" title25="Test 25: Specials for the 32-bit library" title26="Test 26: Specials for the 32-bit library with UTF-32 support" +maxtest=26 + if [ $# -eq 1 -a "$1" = "list" ]; then echo $title1 echo $title2 "(not UTF)" @@ -151,17 +171,19 @@ fi # Default values -valgrind= -sim= arg8= arg16= arg32= +nojit= +sim= +skip= +valgrind= # 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. +# Process options and select which tests to run; for those that are explicitly +# requested, check that the necessary optional facilities are available. do1=no do2=no @@ -221,10 +243,34 @@ while [ $# -gt 0 ] ; do -8) arg8=yes;; -16) arg16=yes;; -32) arg32=yes;; + nojit) nojit=yes;; + sim) shift; sim=$1;; valgrind) valgrind="valgrind --tool=memcheck -q --smc-check=all";; valgrind-log) valgrind="valgrind --tool=memcheck --num-callers=30 --leak-check=no --error-limit=no --smc-check=all --log-file=report.%p ";; - sim) shift; sim=$1;; - *) echo "Unknown test number '$1'"; exit 1;; + ~*) + if expr "$1" : '~[0-9][0-9]*$' >/dev/null; then + skip="$skip `expr "$1" : '~\([0-9]*\)*$'`" + else + echo "Unknown option or test selector '$1'"; exit 1 + fi + ;; + *-*) + if expr "$1" : '[0-9][0-9]*-[0-9]*$' >/dev/null; then + tf=`expr "$1" : '\([0-9]*\)'` + tt=`expr "$1" : '.*-\([0-9]*\)'` + if [ "$tt" = "" ] ; then tt=$maxtest; fi + if expr \( "$tf" "<" 1 \) \| \( "$tt" ">" "$maxtest" \) >/dev/null; then + echo "Invalid test range '$1'"; exit 1 + fi + while expr "$tf" "<=" "$tt" >/dev/null; do + eval do${tf}=yes + tf=`expr $tf + 1` + done + else + echo "Invalid test range '$1'"; exit 1 + fi + ;; + *) echo "Unknown option or test selector '$1'"; exit 1;; esac shift done @@ -309,79 +355,12 @@ ucp=$? jitopt= $sim ./pcretest -C jit >/dev/null jit=$? -if [ $jit -ne 0 ] ; then +if [ $jit -ne 0 -a "$nojit" != "yes" ] ; then jitopt=-s+ fi -if [ $utf -eq 0 ] ; then - if [ $do4 = yes ] ; then - 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 support is not configured" - exit 1 - fi - 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 - if [ $do6 = yes ] ; then - echo "Can't run test 6 because Unicode property support is not configured" - exit 1 - fi - 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 [ $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 [ $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. Those that are not -# relevant will be skipped. +# relevant will be automatically 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 \ @@ -418,6 +397,11 @@ if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a \ do26=yes fi +# Handle any explicit skips at this stage, so that an argument list may consist +# only of explicit skips. + +for i in $skip; do eval do$i=no; done + # Show which release and which test data echo "" @@ -479,8 +463,9 @@ 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. Another possibility is "fr", which needs to be run against -# the Windows-specific input and output files. +# for Windows. Another possibility is "fr". Unfortunately, different versions +# of the French locale give different outputs for some items. This test passes +# if the output matches any one of the alternative output files. if [ $do3 = yes ] ; then locale -a | grep '^fr_FR$' >/dev/null @@ -488,20 +473,28 @@ if [ $do3 = yes ] ; then locale=fr_FR infile=$testdata/testinput3 outfile=$testdata/testoutput3 + outfile2=$testdata/testoutput3A + outfile3=$testdata/testoutput3B else infile=test3input outfile=test3output + outfile2=test3outputA + outfile3=test3outputB 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 + sed 's/fr_FR/french/' $testdata/testoutput3A >test3outputA + sed 's/fr_FR/french/' $testdata/testoutput3B >test3outputB else 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 + sed 's/fr_FR/fr/' $testdata/intestinput3 >test3input + sed 's/fr_FR/fr/' $testdata/intestoutput3 >test3output + sed 's/fr_FR/fr/' $testdata/intestoutput3A >test3outputA + sed 's/fr_FR/fr/' $testdata/intestoutput3B >test3outputB else locale= fi @@ -513,18 +506,20 @@ if [ $do3 = yes ] ; then 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 $cf $outfile testtry >teststdout || \ + $cf $outfile2 testtry >teststdout || \ + $cf $outfile3 testtry >teststdout + then if [ "$opt" = "-s" ] ; then echo " OK with study" elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" else echo " OK" fi + else + echo "** Locale test did not run successfully. The output did not match" + echo " $outfile, $outfile2 or $outfile3." + echo " This may mean that there is a problem with the locale settings rather" + echo " than a bug in PCRE." + exit 1 fi else exit 1 fi @@ -700,7 +695,7 @@ fi if [ $do12 = yes ] ; then echo $title12 - if [ $jit -eq 0 ] ; then + if [ $jit -eq 0 -o "$nojit" = "yes" ] ; then echo " Skipped because JIT is not available or not usable" else $sim $valgrind ./pcretest -q $bmode $testdata/testinput12 testtry @@ -1010,6 +1005,6 @@ fi done # Clean up local working files -rm -f test3input test3output testNinput testsaved* teststderr teststdout testtry +rm -f test3input test3output test3outputA testNinput testsaved* teststderr teststdout testtry # End diff --git a/tools/pcre/RunTest.bat b/tools/pcre/RunTest.bat index e09b2d29..8f290f59 100644 --- a/tools/pcre/RunTest.bat +++ b/tools/pcre/RunTest.bat @@ -15,7 +15,7 @@ @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 12 requires presence 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 diff --git a/tools/pcre/aclocal.m4 b/tools/pcre/aclocal.m4 index 56fceecf..693248e3 100644 --- a/tools/pcre/aclocal.m4 +++ b/tools/pcre/aclocal.m4 @@ -1,8 +1,7 @@ -# generated automatically by aclocal 1.11.6 -*- Autoconf -*- +# generated automatically by aclocal 1.14.1 -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009, 2010, 2011 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. @@ -12,13 +11,14 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, -[m4_warning([this file was generated for autoconf 2.68. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. 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'.])]) +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 1 (pkg-config-0.24) @@ -220,25 +220,37 @@ m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_NOARCH_INSTALLDIR -# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software -# Foundation, Inc. + +# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# ------------------------------------------- +# Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])# PKG_CHECK_VAR + +# Copyright (C) 2002-2013 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_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.11' +[am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11.6], [], +m4_if([$1], [1.14.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -254,24 +266,82 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11.6])dnl +[AM_AUTOMAKE_VERSION([1.14.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# Copyright (C) 2011-2013 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_PROG_AR([ACT-IF-FAIL]) +# ------------------------- +# Try to determine the archiver interface, and trigger the ar-lib wrapper +# if it is needed. If the detection of archiver interface fails, run +# ACT-IF-FAIL (default is to abort configure with a proper error message). +AC_DEFUN([AM_PROG_AR], +[AC_BEFORE([$0], [LT_INIT])dnl +AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([ar-lib])dnl +AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) +: ${AR=ar} + +AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], + [AC_LANG_PUSH([C]) + am_cv_ar_interface=ar + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], + [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + ]) + AC_LANG_POP([C])]) + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + m4_default([$1], + [AC_MSG_ERROR([could not determine $AR interface])]) + ;; +esac +AC_SUBST([AR])dnl +]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2013 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. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and @@ -290,7 +360,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you +# harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, @@ -316,22 +386,19 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 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 9 - # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl @@ -350,16 +417,14 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, -# 2010, 2011 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 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 12 -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing @@ -369,7 +434,7 @@ fi])]) # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was @@ -382,12 +447,13 @@ AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], @@ -395,8 +461,8 @@ AC_CACHE_CHECK([dependency style of $depcc], # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -436,16 +502,16 @@ AC_CACHE_CHECK([dependency style of $depcc], : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -454,8 +520,8 @@ AC_CACHE_CHECK([dependency style of $depcc], test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -463,7 +529,7 @@ AC_CACHE_CHECK([dependency style of $depcc], fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -511,7 +577,7 @@ AM_CONDITIONAL([am__fastdep$1], [ # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl @@ -521,9 +587,13 @@ AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' @@ -538,20 +608,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 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 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -564,7 +632,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -576,21 +644,19 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` @@ -608,7 +674,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will +# is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], @@ -618,18 +684,21 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 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 16 - # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- @@ -642,7 +711,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl +[AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -671,31 +740,40 @@ AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AM_PROG_MKDIR_P])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl @@ -706,34 +784,78 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The `parallel-tests' driver may need to know about EXEEXT, so add the -dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) -dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. @@ -755,15 +877,12 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, -# Inc. +# Copyright (C) 2001-2013 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_PROG_INSTALL_SH # ------------------ # Define $install_sh. @@ -777,16 +896,14 @@ if test x"${install_sh}" != xset; then install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi -AC_SUBST(install_sh)]) +AC_SUBST([install_sh])]) -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2003-2013 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 2 - # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -802,14 +919,12 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 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 4 - # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. @@ -827,7 +942,7 @@ am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -852,52 +967,14 @@ AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) -# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# 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 6 - -# AM_PROG_CC_C_O -# -------------- -# Like AC_PROG_CC_C_O, but changed for automake. -AC_DEFUN([AM_PROG_CC_C_O], -[AC_REQUIRE([AC_PROG_CC_C_O])dnl -AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` -eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o -if test "$am_t" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -dnl Make sure AC_PROG_CC is never called again, or it will override our -dnl setting of CC. -m4_define([AC_PROG_CC], - [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) -]) - # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 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 6 - # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -905,11 +982,10 @@ AC_DEFUN([AM_MISSING_PROG], $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) - # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -922,54 +998,22 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) + AC_MSG_WARN(['missing' script is too old or missing]) fi ]) -# Copyright (C) 2003, 2004, 2005, 2006, 2011 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_PROG_MKDIR_P -# --------------- -# Check for `mkdir -p'. -AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) - # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 2001-2013 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 5 - # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], @@ -979,7 +1023,7 @@ AC_DEFUN([_AM_MANGLE_OPTION], # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ @@ -993,24 +1037,82 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 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 5 +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2013 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. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2013 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. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -1021,32 +1123,40 @@ case `pwd` in esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # 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". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + # If neither matched, then we have a broken ls. This can happen + # 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". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$[2]" = conftest.file ) then @@ -1056,31 +1166,50 @@ else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT(yes)]) +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) -# Copyright (C) 2009, 2011 Free Software Foundation, Inc. +# Copyright (C) 2009-2013 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 2 - # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT -# (`yes' being less verbose, `no' or empty being verbose). +# ("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]);; +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +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 dnl -dnl A few `make' implementations (e.g., NonStop OS and NextStep) +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} @@ -1098,7 +1227,7 @@ else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then - dnl Using `$V' instead of `$(V)' breaks IRIX make. + dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else @@ -1115,44 +1244,40 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 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_PROG_INSTALL_STRIP # --------------------- -# One issue with vendor `install' (even GNU) is that you can't +# One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize +# always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# Copyright (C) 2006-2013 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 3 - # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -1166,18 +1291,16 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# Copyright (C) 2004-2013 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 2 - # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory @@ -1187,76 +1310,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar +# AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. + +# We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - # tar/untar a dummy directory, and stop if the command works + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR diff --git a/tools/pcre/ar-lib b/tools/pcre/ar-lib new file mode 100644 index 00000000..fe2301e7 --- /dev/null +++ b/tools/pcre/ar-lib @@ -0,0 +1,270 @@ +#! /bin/sh +# Wrapper for Microsoft lib.exe + +me=ar-lib +scriptversion=2012-03-01.08; # UTC + +# Copyright (C) 2010-2013 Free Software Foundation, Inc. +# Written by Peter Rosin . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + + +# func_error message +func_error () +{ + echo "$me: $1" 1>&2 + exit 1 +} + +file_conv= + +# func_file_conv build_file +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv in + mingw) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_at_file at_file operation archive +# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE +# for each of them. +# When interpreting the content of the @FILE, do NOT use func_file_conv, +# since the user would need to supply preconverted file names to +# binutils ar, at least for MinGW. +func_at_file () +{ + operation=$2 + archive=$3 + at_file_contents=`cat "$1"` + eval set x "$at_file_contents" + shift + + for member + do + $AR -NOLOGO $operation:"$member" "$archive" || exit $? + done +} + +case $1 in + '') + func_error "no command. Try '$0 --help' for more information." + ;; + -h | --h*) + cat <. # # This program is free software; you can redistribute it and/or modify @@ -113,6 +112,11 @@ func_cl_dashl () lib=$dir/$lib.lib break fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi done IFS=$save_IFS diff --git a/tools/pcre/config-cmake.h.in b/tools/pcre/config-cmake.h.in index a93263fa..77d90116 100644 --- a/tools/pcre/config-cmake.h.in +++ b/tools/pcre/config-cmake.h.in @@ -5,6 +5,8 @@ #cmakedefine HAVE_SYS_TYPES_H 1 #cmakedefine HAVE_UNISTD_H 1 #cmakedefine HAVE_WINDOWS_H 1 +#cmakedefine HAVE_STDINT_H 1 +#cmakedefine HAVE_INTTYPES_H 1 #cmakedefine HAVE_TYPE_TRAITS_H 1 #cmakedefine HAVE_BITS_TYPE_TRAITS_H 1 @@ -44,6 +46,7 @@ #define NEWLINE @NEWLINE@ #define POSIX_MALLOC_THRESHOLD @PCRE_POSIX_MALLOC_THRESHOLD@ #define LINK_SIZE @PCRE_LINK_SIZE@ +#define PARENS_NEST_LIMIT @PCRE_PARENS_NEST_LIMIT@ #define MATCH_LIMIT @PCRE_MATCH_LIMIT@ #define MATCH_LIMIT_RECURSION @PCRE_MATCH_LIMIT_RECURSION@ #define PCREGREP_BUFSIZE @PCREGREP_BUFSIZE@ diff --git a/tools/pcre/config.guess b/tools/pcre/config.guess index 68194c9c..9afd6762 100644 --- a/tools/pcre/config.guess +++ b/tools/pcre/config.guess @@ -1,14 +1,12 @@ #! /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, -# 2011, 2012 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2012-08-14' +timestamp='2013-11-29' # 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 -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -22,19 +20,17 @@ timestamp='2012-08-14' # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). # -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. +# Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + me=`echo "$0" | sed -e 's,.*/,,'` @@ -54,9 +50,7 @@ version="\ GNU config.guess ($timestamp) 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, 2011, 2012 -Free Software Foundation, Inc. +Copyright 1992-2013 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." @@ -139,22 +133,20 @@ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in -Linux|GNU/*) +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + eval $set_cc_for_build cat <<-EOF > $dummy.c #include - #ifdef __UCLIBC__ - # ifdef __UCLIBC_CONFIG_VERSION__ - LIBC=uclibc __UCLIBC_CONFIG_VERSION__ - # else + #if defined(__UCLIBC__) LIBC=uclibc - # endif - #else - # ifdef __dietlibc__ + #elif defined(__dietlibc__) LIBC=dietlibc - # else + #else LIBC=gnu - # endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` @@ -329,7 +321,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) + arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) @@ -912,6 +904,9 @@ EOF if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ @@ -974,6 +969,9 @@ EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -997,8 +995,14 @@ EOF ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} @@ -1252,19 +1256,31 @@ EOF exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) diff --git a/tools/pcre/config.h.generic b/tools/pcre/config.h.generic index 98801a81..1ebb7594 100644 --- a/tools/pcre/config.h.generic +++ b/tools/pcre/config.h.generic @@ -5,20 +5,28 @@ can cope with, allowing it to run on SunOS4 and other "close to standard" systems. -In environments that support the facilities, config.h.in is converted by -"configure", or config-cmake.h.in is converted by CMake, into config.h. If you -are going to build PCRE "by hand" without using "configure" or CMake, you -should copy the distributed config.h.generic to config.h, and then edit the -macro definitions to be the way you need them. You must then add --DHAVE_CONFIG_H to all of your compile commands, so that config.h is included -at the start of every source. +In environments that support the GNU autotools, config.h.in is converted into +config.h by the "configure" script. In environments that use CMake, +config-cmake.in is converted into config.h. If you are going to build PCRE "by +hand" without using "configure" or CMake, you should copy the distributed +config.h.generic to config.h, and edit the macro definitions to be the way you +need them. You must then add -DHAVE_CONFIG_H to all of your compile commands, +so that config.h is included at the start of every source. Alternatively, you can avoid editing by using -D on the compiler command line -to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H. +to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H, +but if you do, default values will be taken from config.h for non-boolean +macros that are not defined on the command line. -PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if -HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set -them both to 0; an emulation function will be used. */ +Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE8 should either be defined +(conventionally to 1) for TRUE, and not defined at all for FALSE. All such +macros are listed as a commented #undef in config.h.generic. Macros such as +MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are +surrounded by #ifndef/#endif lines so that the value can be overridden by -D. + +PCRE uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if +HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make +sure both macros are undefined; an emulation function will then be used. */ /* By default, the \R escape sequence matches any Unicode line ending character or sequence of characters. If BSR_ANYCRLF is defined (to any @@ -44,27 +52,19 @@ them both to 0; an emulation function will be used. */ /* #undef EBCDIC_NL25 */ /* Define to 1 if you have the `bcopy' function. */ -#ifndef HAVE_BCOPY -#define HAVE_BCOPY 1 -#endif +/* #undef HAVE_BCOPY */ /* Define to 1 if you have the header file. */ /* #undef HAVE_BITS_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_BZLIB_H -#define HAVE_BZLIB_H 1 -#endif +/* #undef HAVE_BZLIB_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_DIRENT_H -#define HAVE_DIRENT_H 1 -#endif +/* #undef HAVE_DIRENT_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_DLFCN_H -#define HAVE_DLFCN_H 1 -#endif +/* #undef HAVE_DLFCN_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_EDITLINE_READLINE_H */ @@ -73,29 +73,19 @@ them both to 0; an emulation function will be used. */ /* #undef HAVE_EDIT_READLINE_READLINE_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_INTTYPES_H -#define HAVE_INTTYPES_H 1 -#endif +/* #undef HAVE_INTTYPES_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_LIMITS_H -#define HAVE_LIMITS_H 1 -#endif +/* #undef HAVE_LIMITS_H */ /* Define to 1 if the system has the type `long long'. */ -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG 1 -#endif +/* #undef HAVE_LONG_LONG */ /* Define to 1 if you have the `memmove' function. */ -#ifndef HAVE_MEMMOVE -#define HAVE_MEMMOVE 1 -#endif +/* #undef HAVE_MEMMOVE */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_MEMORY_H -#define HAVE_MEMORY_H 1 -#endif +/* #undef HAVE_MEMORY_H */ /* Define if you have POSIX threads libraries and header files. */ /* #undef HAVE_PTHREAD */ @@ -110,34 +100,22 @@ them both to 0; an emulation function will be used. */ /* #undef HAVE_READLINE_READLINE_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_STDINT_H -#define HAVE_STDINT_H 1 -#endif +/* #undef HAVE_STDINT_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_STDLIB_H -#define HAVE_STDLIB_H 1 -#endif +/* #undef HAVE_STDLIB_H */ /* Define to 1 if you have the `strerror' function. */ -#ifndef HAVE_STRERROR -#define HAVE_STRERROR 1 -#endif +/* #undef HAVE_STRERROR */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_STRING -#define HAVE_STRING 1 -#endif +/* #undef HAVE_STRING */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_STRINGS_H -#define HAVE_STRINGS_H 1 -#endif +/* #undef HAVE_STRINGS_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_STRING_H -#define HAVE_STRING_H 1 -#endif +/* #undef HAVE_STRING_H */ /* Define to 1 if you have `strtoimax'. */ /* #undef HAVE_STRTOIMAX */ @@ -146,46 +124,31 @@ them both to 0; an emulation function will be used. */ /* #undef HAVE_STRTOLL */ /* Define to 1 if you have `strtoq'. */ -#ifndef HAVE_STRTOQ -#define HAVE_STRTOQ 1 -#endif +/* #undef HAVE_STRTOQ */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_SYS_STAT_H -#define HAVE_SYS_STAT_H 1 -#endif +/* #undef HAVE_SYS_STAT_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_SYS_TYPES_H -#define HAVE_SYS_TYPES_H 1 -#endif +/* #undef HAVE_SYS_TYPES_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_TYPE_TRAITS_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_UNISTD_H -#define HAVE_UNISTD_H 1 -#endif +/* #undef HAVE_UNISTD_H */ /* Define to 1 if the system has the type `unsigned long long'. */ -#ifndef HAVE_UNSIGNED_LONG_LONG -#define HAVE_UNSIGNED_LONG_LONG 1 -#endif +/* #undef HAVE_UNSIGNED_LONG_LONG */ -/* Define to 1 or 0, depending whether the compiler supports simple visibility - declarations. */ -#ifndef HAVE_VISIBILITY -#define HAVE_VISIBILITY 1 -#endif +/* Define to 1 if the compiler supports simple visibility declarations. */ +/* #undef HAVE_VISIBILITY */ /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_ZLIB_H -#define HAVE_ZLIB_H 1 -#endif +/* #undef HAVE_ZLIB_H */ /* Define to 1 if you have `_strtoi64'. */ /* #undef HAVE__STRTOI64 */ @@ -201,6 +164,7 @@ them both to 0; an emulation function will be used. */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ +/* This is ignored unless you are using libtool. */ #ifndef LT_OBJDIR #define LT_OBJDIR ".libs/" #endif @@ -253,9 +217,6 @@ them both to 0; an emulation function will be used. */ #define NEWLINE 10 #endif -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to any value to get a version that doesn't use @@ -275,7 +236,7 @@ them both to 0; an emulation function will be used. */ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PCRE 8.32" +#define PACKAGE_STRING "PCRE 8.35" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" @@ -284,7 +245,14 @@ them both to 0; an emulation function will be used. */ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "8.32" +#define PACKAGE_VERSION "8.35" + +/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested + parentheses (of any kind) in a pattern. This limits the amount of system + stack that is used while compiling a pattern. */ +#ifndef PARENS_NEST_LIMIT +#define PARENS_NEST_LIMIT 250 +#endif /* The value of PCREGREP_BUFSIZE determines the size of buffer used by pcregrep to hold parts of the file it is searching. This is also the @@ -325,13 +293,7 @@ them both to 0; an emulation function will be used. */ /* #undef PTHREAD_CREATE_JOINABLE */ /* Define to 1 if you have the ANSI C header files. */ -#ifndef STDC_HEADERS -#define STDC_HEADERS 1 -#endif - -/* Define to allow pcretest and pcregrep to be linked with gcov, so that they - are able to generate code coverage reports. */ -/* #undef SUPPORT_GCOV */ +/* #undef STDC_HEADERS */ /* Define to any value to enable support for Just-In-Time compiling. */ /* #undef SUPPORT_JIT */ @@ -357,9 +319,7 @@ them both to 0; an emulation function will be used. */ /* #undef SUPPORT_PCRE32 */ /* Define to any value to enable the 8 bit PCRE library. */ -#ifndef SUPPORT_PCRE8 -#define SUPPORT_PCRE8 /**/ -#endif +/* #undef SUPPORT_PCRE8 */ /* Define to any value to enable JIT support in pcregrep. */ /* #undef SUPPORT_PCREGREP_JIT */ @@ -373,13 +333,11 @@ them both to 0; an emulation function will be used. */ ASCII/UTF-8/16/32, but not both at once. */ /* #undef SUPPORT_UTF */ -/* Valgrind support to find invalid memory reads. */ +/* Define to any value for valgrind support to find invalid memory reads. */ /* #undef SUPPORT_VALGRIND */ /* Version number of package */ -#ifndef VERSION -#define VERSION "8.32" -#endif +#define VERSION "8.35" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ diff --git a/tools/pcre/config.h.in b/tools/pcre/config.h.in index de19fe01..46f56c24 100644 --- a/tools/pcre/config.h.in +++ b/tools/pcre/config.h.in @@ -5,20 +5,28 @@ can cope with, allowing it to run on SunOS4 and other "close to standard" systems. -In environments that support the facilities, config.h.in is converted by -"configure", or config-cmake.h.in is converted by CMake, into config.h. If you -are going to build PCRE "by hand" without using "configure" or CMake, you -should copy the distributed config.h.generic to config.h, and then edit the -macro definitions to be the way you need them. You must then add --DHAVE_CONFIG_H to all of your compile commands, so that config.h is included -at the start of every source. +In environments that support the GNU autotools, config.h.in is converted into +config.h by the "configure" script. In environments that use CMake, +config-cmake.in is converted into config.h. If you are going to build PCRE "by +hand" without using "configure" or CMake, you should copy the distributed +config.h.generic to config.h, and edit the macro definitions to be the way you +need them. You must then add -DHAVE_CONFIG_H to all of your compile commands, +so that config.h is included at the start of every source. Alternatively, you can avoid editing by using -D on the compiler command line -to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H. +to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H, +but if you do, default values will be taken from config.h for non-boolean +macros that are not defined on the command line. -PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if -HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set -them both to 0; an emulation function will be used. */ +Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE8 should either be defined +(conventionally to 1) for TRUE, and not defined at all for FALSE. All such +macros are listed as a commented #undef in config.h.generic. Macros such as +MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are +surrounded by #ifndef/#endif lines so that the value can be overridden by -D. + +PCRE uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if +HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make +sure both macros are undefined; an emulation function will then be used. */ /* By default, the \R escape sequence matches any Unicode line ending character or sequence of characters. If BSR_ANYCRLF is defined (to any @@ -133,8 +141,7 @@ them both to 0; an emulation function will be used. */ /* Define to 1 if the system has the type `unsigned long long'. */ #undef HAVE_UNSIGNED_LONG_LONG -/* Define to 1 or 0, depending whether the compiler supports simple visibility - declarations. */ +/* Define to 1 if the compiler supports simple visibility declarations. */ #undef HAVE_VISIBILITY /* Define to 1 if you have the header file. */ @@ -195,9 +202,6 @@ them both to 0; an emulation function will be used. */ or -2 (ANYCRLF). */ #undef NEWLINE -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -#undef NO_MINUS_C_MINUS_O - /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to any value to get a version that doesn't use @@ -228,6 +232,11 @@ them both to 0; an emulation function will be used. */ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested + parentheses (of any kind) in a pattern. This limits the amount of system + stack that is used while compiling a pattern. */ +#undef PARENS_NEST_LIMIT + /* to make a symbol visible */ #undef PCRECPP_EXP_DECL @@ -284,10 +293,6 @@ them both to 0; an emulation function will be used. */ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS -/* Define to allow pcretest and pcregrep to be linked with gcov, so that they - are able to generate code coverage reports. */ -#undef SUPPORT_GCOV - /* Define to any value to enable support for Just-In-Time compiling. */ #undef SUPPORT_JIT @@ -326,7 +331,7 @@ them both to 0; an emulation function will be used. */ ASCII/UTF-8/16/32, but not both at once. */ #undef SUPPORT_UTF -/* Valgrind support to find invalid memory reads. */ +/* Define to any value for valgrind support to find invalid memory reads. */ #undef SUPPORT_VALGRIND /* Version number of package */ diff --git a/tools/pcre/config.sub b/tools/pcre/config.sub index ae2965a1..61cb4bc2 100644 --- a/tools/pcre/config.sub +++ b/tools/pcre/config.sub @@ -1,24 +1,18 @@ #! /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, -# 2011, 2012 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2012-08-18' +timestamp='2013-10-01' -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or +# 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 +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, see . @@ -26,11 +20,12 @@ timestamp='2012-08-18' # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. +# Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -73,9 +68,7 @@ Report bugs and patches to ." version="\ 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, 2011, 2012 -Free Software Foundation, Inc. +Copyright 1992-2013 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." @@ -156,7 +149,7 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze) + -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; @@ -259,21 +252,24 @@ case $basic_machine in | 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 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx | dvp \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep | metag \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ @@ -291,16 +287,17 @@ case $basic_machine in | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ - | nios | nios2 \ + | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ - | or32 \ + | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ @@ -328,7 +325,7 @@ case $basic_machine in c6x) basic_machine=tic6x-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; @@ -370,13 +367,13 @@ case $basic_machine in | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ @@ -385,11 +382,13 @@ case $basic_machine in | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ @@ -407,12 +406,13 @@ case $basic_machine in | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ @@ -788,7 +788,7 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; - microblaze) + microblaze*) basic_machine=microblaze-xilinx ;; mingw64) @@ -796,7 +796,7 @@ case $basic_machine in os=-mingw64 ;; mingw32) - basic_machine=i386-pc + basic_machine=i686-pc os=-mingw32 ;; mingw32ce) @@ -810,24 +810,6 @@ case $basic_machine in basic_machine=m68k-atari os=-mint ;; - mipsEE* | ee | ps2) - basic_machine=mips64r5900el-scei - case $os in - -linux*) - ;; - *) - os=-elf - ;; - esac - ;; - iop) - basic_machine=mipsel-scei - os=-irx - ;; - dvp) - basic_machine=dvp-scei - os=-elf - ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; @@ -850,7 +832,7 @@ case $basic_machine in basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) - basic_machine=i386-pc + basic_machine=i686-pc os=-msys ;; mvs) @@ -1041,7 +1023,11 @@ case $basic_machine in basic_machine=i586-unknown os=-pw32 ;; - rdos) + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) basic_machine=i386-pc os=-rdos ;; @@ -1368,7 +1354,7 @@ case $os in -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ + | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ @@ -1386,7 +1372,7 @@ case $os in | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -irx* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ @@ -1514,9 +1500,6 @@ case $os in -aros*) os=-aros ;; - -kaos*) - os=-kaos - ;; -zvmoe) os=-zvmoe ;; @@ -1565,6 +1548,9 @@ case $basic_machine in c4x-* | tic4x-*) os=-coff ;; + c8051-*) + os=-elf + ;; hexagon-*) os=-elf ;; @@ -1608,6 +1594,9 @@ case $basic_machine in mips*-*) os=-elf ;; + or1k-*) + os=-elf + ;; or32-*) os=-coff ;; diff --git a/tools/pcre/configure b/tools/pcre/configure index 77229ed9..6b08640e 100644 --- a/tools/pcre/configure +++ b/tools/pcre/configure @@ -1,11 +1,9 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for PCRE 8.32. +# Generated by GNU Autoconf 2.69 for PCRE 8.35. # # -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -134,6 +132,31 @@ export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # 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 +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+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -167,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1" +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -220,21 +244,25 @@ IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : - # 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 - 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+"$@"} + export CONFIG_SHELL + # 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 +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+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi if test x$as_have_required = xno; then : @@ -336,6 +364,14 @@ $as_echo X"$as_dir" | } # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -457,6 +493,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -491,16 +531,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -512,28 +552,8 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -567,8 +587,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='PCRE' PACKAGE_TARNAME='pcre' -PACKAGE_VERSION='8.32' -PACKAGE_STRING='PCRE 8.32' +PACKAGE_VERSION='8.35' +PACKAGE_STRING='PCRE 8.35' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -679,8 +699,6 @@ NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB -ac_ct_AR -AR LN_S NM ac_ct_DUMPBIN @@ -726,6 +744,8 @@ CPPFLAGS LDFLAGS CFLAGS CC +ac_ct_AR +AR AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V @@ -829,6 +849,7 @@ enable_pcretest_libedit enable_pcretest_libreadline with_posix_malloc_threshold with_link_size +with_parens_nest_limit with_match_limit with_match_limit_recursion enable_valgrind @@ -1309,8 +1330,6 @@ target=$target_alias 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 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1396,7 +1415,7 @@ if test "$ac_init_help" = "long"; then # 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.32 to adapt to many kinds of systems. +\`configure' configures PCRE 8.35 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1466,7 +1485,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PCRE 8.32:";; + short | recursive ) echo "Configuration of PCRE 8.35:";; esac cat <<\_ACEOF @@ -1474,10 +1493,12 @@ Optional Features: --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-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] @@ -1526,16 +1547,18 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-pic try to use only PIC/non-PIC objects [default=use + --with-pic[=PKGS] 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) + pcregrep buffer size (default=20480, minimum=8192) --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) + --with-parens-nest-limit=N + nested parentheses limit (default=250) --with-match-limit=N default limit on internal looping (default=10000000) --with-match-limit-recursion=N default limit on internal recursion @@ -1631,10 +1654,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -PCRE configure 8.32 -generated by GNU Autoconf 2.68 +PCRE configure 8.35 +generated by GNU Autoconf 2.69 -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1856,7 +1879,8 @@ int main () { static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -1872,7 +1896,8 @@ main () { static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -1932,7 +1957,7 @@ $as_echo "$ac_try_echo"; } >&5 test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext + test -x conftest$ac_exeext }; then : ac_retval=0 else @@ -2082,7 +2107,7 @@ $as_echo "$ac_try_echo"; } >&5 test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext + test -x conftest$ac_exeext }; then : ac_retval=0 else @@ -2386,8 +2411,8 @@ 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.32, which was -generated by GNU Autoconf 2.68. Invocation command line was +It was created by PCRE $as_me 8.35, which was +generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2735,7 +2760,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -am__api_version='1.11' +am__api_version='1.14' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do @@ -2803,7 +2828,7 @@ case $as_dir/ in #(( # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -2861,9 +2886,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -2874,32 +2896,40 @@ case `pwd` in 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 +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # 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 -alias in your environment" "$LINENO" 5 - fi + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + # If neither matched, then we have a broken ls. This can happen + # 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 + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$2" = conftest.file ) then @@ -2911,6 +2941,16 @@ Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. @@ -2933,12 +2973,12 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then @@ -2950,10 +2990,10 @@ if test x"${install_sh}" != xset; then esac fi -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. +# will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. @@ -2972,7 +3012,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3012,7 +3052,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3063,7 +3103,7 @@ do test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ @@ -3092,12 +3132,6 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -3116,7 +3150,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3180,6 +3214,45 @@ else fi rmdir .tst 2>/dev/null +# 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=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -3202,7 +3275,7 @@ fi # Define the identity of the package. PACKAGE='pcre' - VERSION='8.32' + VERSION='8.35' cat >>confdefs.h <<_ACEOF @@ -3230,27 +3303,79 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi # 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;; +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 @@ -3284,21 +3409,69 @@ AM_BACKSLASH='\' ac_config_headers="$ac_config_headers config.h" -# This was added at the suggestion of libtoolize (03-Jan-10) +# This is a new thing required to stop a warning from automake 1.12 +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" -# The default CFLAGS and CXXFLAGS in Autoconf are "-g -O2" for gcc and just -# "-g" for any other compiler. There doesn't seem to be a standard way of -# getting rid of the -g (which I don't think is needed for a production -# library). This fudge seems to achieve the necessary. First, we remember the -# externally set values of CFLAGS and CXXFLAGS. Then call the AC_PROG_CC and -# AC_PROG_CXX macros to find the compilers - if CFLAGS and CXXFLAGS are not -# set, they will be set to Autoconf's defaults. Afterwards, if the original -# values were not set, remove the -g from the Autoconf defaults. -# (PH 02-May-07) +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi -remember_set_CFLAGS="$CFLAGS" -remember_set_CXXFLAGS="$CXXFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -3322,7 +3495,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3362,7 +3535,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3415,7 +3588,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3456,7 +3629,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -3514,7 +3687,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3558,7 +3731,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4004,8 +4177,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -4089,68 +4261,64 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -DEPDIR="${am__leading_dot}deps" -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= @@ -4164,8 +4332,8 @@ else # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -4200,16 +4368,16 @@ else : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -4218,8 +4386,8 @@ else test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -4227,7 +4395,922 @@ else fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar lib "link -lib" + 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 ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + 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 +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar lib "link -lib" +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 ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + 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 +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="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 + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 +$as_echo_n "checking the archiver ($AR) interface... " >&6; } +if ${am_cv_ar_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + am_cv_ar_interface=ar + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int some_variable = 0; +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_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 + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_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 + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 +$as_echo "$am_cv_ar_interface" >&6; } + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + as_fn_error $? "could not determine $AR interface" "$LINENO" 5 + ;; +esac + + +# This was added at the suggestion of libtoolize (03-Jan-10) + + +# The default CFLAGS and CXXFLAGS in Autoconf are "-g -O2" for gcc and just +# "-g" for any other compiler. There doesn't seem to be a standard way of +# getting rid of the -g (which I don't think is needed for a production +# library). This fudge seems to achieve the necessary. First, we remember the +# externally set values of CFLAGS and CXXFLAGS. Then call the AC_PROG_CC and +# AC_PROG_CXX macros to find the compilers - if CFLAGS and CXXFLAGS are not +# set, they will be set to Autoconf's defaults. Afterwards, if the original +# values were not set, remove the -g from the Autoconf defaults. +# (PH 02-May-07) + +remember_set_CFLAGS="$CFLAGS" +remember_set_CXXFLAGS="$CXXFLAGS" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +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 ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $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 +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +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 ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $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_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + 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 + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +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 ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $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 +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +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 ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $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 + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + 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 ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $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 +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +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 ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $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_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + 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 + CC=$ac_ct_CC + fi +fi + +fi + + +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; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $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 ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +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 ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +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 ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +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 + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -4309,7 +5392,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4353,7 +5436,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4549,8 +5632,8 @@ else # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -4585,16 +5668,16 @@ else : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -4603,8 +5686,8 @@ else test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -4612,7 +5695,7 @@ else fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -4666,131 +5749,6 @@ else fi -if test "x$CC" != xcc; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 -$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 -$as_echo_n "checking whether cc understands -c and -o together... " >&6; } -fi -set dummy $CC; ac_cc=`$as_echo "$2" | - sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -# Make sure it works both with $CC and with simple cc. -# We do the test twice because some compilers refuse to overwrite an -# existing .o file with -o, though they will create one. -ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' -rm -f conftest2.* -if { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && - test -f conftest2.$ac_objext && { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; -then - eval ac_cv_prog_cc_${ac_cc}_c_o=yes - if test "x$CC" != xcc; then - # Test first that cc exists at all. - if { ac_try='cc -c conftest.$ac_ext >&5' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' - rm -f conftest2.* - if { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && - test -f conftest2.$ac_objext && { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; - then - # cc works too. - : - else - # cc exists but doesn't like -o. - eval ac_cv_prog_cc_${ac_cc}_c_o=no - fi - fi - fi -else - eval ac_cv_prog_cc_${ac_cc}_c_o=no -fi -rm -f core conftest* - -fi -if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h - -fi - -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o -if test "$am_t" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi - if test "x$remember_set_CFLAGS" = "x" @@ -4849,7 +5807,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # Check for a 64-bit integer type - ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -5004,7 +5961,7 @@ do for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -5070,7 +6027,7 @@ do for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -5352,7 +6309,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5392,7 +6349,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5444,7 +6401,7 @@ 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 + if as_fn_executable_p "$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 @@ -5484,7 +6441,7 @@ 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 + if as_fn_executable_p "$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 @@ -5536,7 +6493,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5576,7 +6533,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5642,8 +6599,8 @@ esac -macro_version='2.4' -macro_revision='1.3293' +macro_version='2.4.2' +macro_revision='1.3337' @@ -5750,7 +6707,7 @@ do for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue + as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in @@ -5829,7 +6786,7 @@ do for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue + as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in @@ -6085,7 +7042,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6129,7 +7086,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6287,6 +7244,11 @@ else lt_cv_sys_max_cmd_len=196608 ;; + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not @@ -6326,7 +7288,7 @@ else # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do @@ -6548,7 +7510,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6588,7 +7550,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6752,7 +7714,7 @@ irix5* | irix6* | nonstopux*) lt_cv_deplibs_check_method=pass_all ;; -# This must be Linux ELF. +# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; @@ -6891,7 +7853,7 @@ 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 + if as_fn_executable_p "$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 @@ -6931,7 +7893,7 @@ 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 + if as_fn_executable_p "$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 @@ -7031,7 +7993,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 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 @@ -7075,7 +8037,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then 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 @@ -7200,7 +8162,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7240,7 +8202,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7299,7 +8261,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7339,7 +8301,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7389,13 +8351,13 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in @@ -7542,6 +8504,7 @@ for ac_symprfx in "" "_"; do # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ @@ -7930,7 +8893,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } CFLAGS="$SAVE_CFLAGS" fi ;; -sparc*-*solaris*) +*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 @@ -7941,7 +8904,20 @@ sparc*-*solaris*) case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" @@ -7974,7 +8950,7 @@ 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 + if as_fn_executable_p "$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 @@ -8014,7 +8990,7 @@ 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 + if as_fn_executable_p "$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 @@ -8094,7 +9070,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8134,7 +9110,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8186,7 +9162,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8226,7 +9202,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8278,7 +9254,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8318,7 +9294,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8370,7 +9346,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8410,7 +9386,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8462,7 +9438,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8502,7 +9478,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8581,7 +9557,13 @@ else $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 @@ -8592,6 +9574,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $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 ${lt_cv_ld_exported_symbols_list+:} false; then : @@ -8624,6 +9607,7 @@ rm -f core conftest.err conftest.$ac_objext \ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $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 ${lt_cv_ld_force_load+:} false; then : @@ -8645,7 +9629,9 @@ _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? - if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 @@ -8791,7 +9777,22 @@ fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : - withval=$with_pic; pic_mode="$withval" + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac else pic_mode=default fi @@ -8864,6 +9865,10 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + @@ -9328,7 +10333,9 @@ lt_prog_compiler_static= case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' - lt_prog_compiler_pic='-Xcompiler -fPIC' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi ;; esac else @@ -9419,18 +10426,33 @@ lt_prog_compiler_static= ;; *) case `$CC -V 2>&1 | sed 5q` in - *Sun\ F* | *Sun*Fortran*) + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; esac ;; esac @@ -9792,7 +10814,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported @@ -10042,8 +11063,7 @@ _LT_EOF xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld='-rpath $libdir' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ @@ -10422,6 +11442,7 @@ fi # 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 + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' 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' @@ -10467,6 +11488,7 @@ fi hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else whole_archive_flag_spec='' fi @@ -10495,10 +11517,6 @@ fi hardcode_shlibpath_var=no ;; - freebsd1*) - ld_shlibs=no - ;; - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little @@ -10511,7 +11529,7 @@ fi ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) + freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes @@ -10550,7 +11568,6 @@ fi fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld='+b $libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes @@ -11168,11 +12185,6 @@ esac - - - - - @@ -11268,7 +12280,7 @@ need_version=unknown case $host_os in aix3*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH @@ -11277,7 +12289,7 @@ aix3*) ;; aix[4-9]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes @@ -11342,7 +12354,7 @@ beos*) ;; bsdi[45]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -11481,7 +12493,7 @@ darwin* | rhapsody*) ;; dgux*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' @@ -11489,10 +12501,6 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd1*) - dynamic_linker=no - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. @@ -11500,18 +12508,11 @@ freebsd* | dragonfly*) objformat=`/usr/bin/objformat` else case $host_os in - freebsd[123]*) objformat=aout ;; + freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi - # Handle Gentoo/FreeBSD as it was Linux - case $host_vendor in - gentoo) - version_type=linux ;; - *) - version_type=freebsd-$objformat ;; - esac - + version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' @@ -11522,16 +12523,10 @@ freebsd* | dragonfly*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; - linux) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - need_lib_prefix=no - need_version=no - ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in - freebsd2*) + freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) @@ -11551,17 +12546,18 @@ freebsd* | dragonfly*) ;; gnu*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" @@ -11622,7 +12618,7 @@ hpux9* | hpux10* | hpux11*) ;; interix[3-9]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' @@ -11638,7 +12634,7 @@ irix5* | irix6* | nonstopux*) nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; @@ -11675,9 +12671,9 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; -# This must be Linux ELF. +# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -11759,7 +12755,7 @@ netbsd*) ;; newsos6) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes @@ -11828,7 +12824,7 @@ rdos*) ;; solaris*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -11853,7 +12849,7 @@ sunos4*) ;; sysv4 | sysv4.3*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -11877,7 +12873,7 @@ sysv4 | sysv4.3*) sysv4*MP*) if test -d /usr/nec ;then - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH @@ -11908,7 +12904,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -11918,7 +12914,7 @@ tpf*) ;; uts4*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -12843,7 +13839,6 @@ export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= -hardcode_libdir_flag_spec_ld_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported @@ -13427,6 +14422,7 @@ fi hardcode_shlibpath_var_CXX=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else whole_archive_flag_spec_CXX='' fi @@ -13471,7 +14467,7 @@ fi esac ;; - freebsd[12]*) + freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no @@ -14147,6 +15143,7 @@ _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 @@ -14936,7 +15933,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie ;; cygwin* | mingw* | cegcc*) case $cc_basename in - cl*) ;; + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; *) 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' @@ -15086,8 +16085,6 @@ esac - - @@ -15116,7 +16113,7 @@ need_version=unknown case $host_os in aix3*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH @@ -15125,7 +16122,7 @@ aix3*) ;; aix[4-9]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes @@ -15190,7 +16187,7 @@ beos*) ;; bsdi[45]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -15327,7 +16324,7 @@ darwin* | rhapsody*) ;; dgux*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' @@ -15335,10 +16332,6 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd1*) - dynamic_linker=no - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. @@ -15346,18 +16339,11 @@ freebsd* | dragonfly*) objformat=`/usr/bin/objformat` else case $host_os in - freebsd[123]*) objformat=aout ;; + freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi - # Handle Gentoo/FreeBSD as it was Linux - case $host_vendor in - gentoo) - version_type=linux ;; - *) - version_type=freebsd-$objformat ;; - esac - + version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' @@ -15368,16 +16354,10 @@ freebsd* | dragonfly*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; - linux) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - need_lib_prefix=no - need_version=no - ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in - freebsd2*) + freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) @@ -15397,17 +16377,18 @@ freebsd* | dragonfly*) ;; gnu*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" @@ -15468,7 +16449,7 @@ hpux9* | hpux10* | hpux11*) ;; interix[3-9]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' @@ -15484,7 +16465,7 @@ irix5* | irix6* | nonstopux*) nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; @@ -15521,9 +16502,9 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; -# This must be Linux ELF. +# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -15605,7 +16586,7 @@ netbsd*) ;; newsos6) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes @@ -15674,7 +16655,7 @@ rdos*) ;; solaris*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -15699,7 +16680,7 @@ sunos4*) ;; sysv4 | sysv4.3*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -15723,7 +16704,7 @@ sysv4 | sysv4.3*) sysv4*MP*) if test -d /usr/nec ;then - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH @@ -15754,7 +16735,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -15764,7 +16745,7 @@ tpf*) ;; uts4*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -15903,6 +16884,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_config_commands="$ac_config_commands libtool" @@ -16039,9 +17022,9 @@ _ACEOF # Versioning PCRE_MAJOR="8" -PCRE_MINOR="32" +PCRE_MINOR="35" PCRE_PRERELEASE="" -PCRE_DATE="2012-11-30" +PCRE_DATE="2014-04-04" if test "$PCRE_MINOR" = "08" -o "$PCRE_MINOR" = "09" then @@ -16289,6 +17272,16 @@ else fi +# Handle --with-parens-nest-limit=N + +# Check whether --with-parens-nest-limit was given. +if test "${with_parens_nest_limit+set}" = set; then : + withval=$with_parens_nest_limit; +else + with_parens_nest_limit=250 +fi + + # Handle --with-match-limit=N # Check whether --with-match-limit was given. @@ -16568,7 +17561,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi -for ac_header in limits.h sys/types.h sys/stat.h dirent.h windows.h +for ac_header in limits.h sys/types.h sys/stat.h dirent.h 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" @@ -16581,6 +17574,18 @@ fi done +for ac_header in windows.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" +if test "x$ac_cv_header_windows_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_WINDOWS_H 1 +_ACEOF + HAVE_WINDOWS_H=1 +fi + +done + # The files below are C++ header files. pcre_have_type_traits="0" @@ -16857,11 +17862,11 @@ else int main () { -/* FIXME: Include the comments suggested by Paul. */ + #ifndef __cplusplus - /* Ultrix mips cc rejects this. */ + /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; - const charset cs; + const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; @@ -16878,8 +17883,9 @@ main () ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this. */ - char *t; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; @@ -16895,10 +17901,10 @@ main () iptr p = 0; ++p; } - { /* AIX XL C 1.02.0.0 rejects this saying + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; @@ -17474,7 +18480,10 @@ $as_echo "#define SUPPORT_PCRE32 /**/" >>confdefs.h fi +# Unless running under Windows, JIT support requires pthreads. + if test "$enable_jit" = "yes"; then + if test "$HAVE_WINDOWS_H" != "1"; then ac_ext=c @@ -17615,7 +18624,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ax_pthread_config="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -17818,7 +18827,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -17871,9 +18880,10 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu - CC="$PTHREAD_CC" - CFLAGS="$PTHREAD_CFLAGS $CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" + CC="$PTHREAD_CC" + CFLAGS="$PTHREAD_CFLAGS $CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + fi $as_echo "#define SUPPORT_JIT /**/" >>confdefs.h @@ -17918,7 +18928,13 @@ $as_echo "#define SUPPORT_LIBBZ2 /**/" >>confdefs.h fi if test $with_pcregrep_bufsize -lt 8192 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $with_pcregrep_bufsize is too small for --with-pcregrep-bufsize; using 8192" >&5 +$as_echo "$as_me: WARNING: $with_pcregrep_bufsize is too small for --with-pcregrep-bufsize; using 8192" >&2;} with_pcregrep_bufsize="8192" +else + if test $? -gt 1 ; then + as_fn_error $? "Bad value for --with-pcregrep-bufsize" "$LINENO" 5 + fi fi @@ -17963,6 +18979,12 @@ _ACEOF +cat >>confdefs.h <<_ACEOF +#define PARENS_NEST_LIMIT $with_parens_nest_limit +_ACEOF + + + cat >>confdefs.h <<_ACEOF #define MATCH_LIMIT $with_match_limit _ACEOF @@ -18024,16 +19046,16 @@ esac # (Note: The libpcre*_version bits are m4 variables, assigned above) EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \ - $NO_UNDEFINED -version-info 3:0:2" + $NO_UNDEFINED -version-info 3:3:2" EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \ - $NO_UNDEFINED -version-info 2:0:2" + $NO_UNDEFINED -version-info 2:3:2" EXTRA_LIBPCRE32_LDFLAGS="$EXTRA_LIBPCRE32_LDFLAGS \ - $NO_UNDEFINED -version-info 0:0:0" + $NO_UNDEFINED -version-info 0:3:0" EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \ - $NO_UNDEFINED -version-info 0:1:0" + $NO_UNDEFINED -version-info 0:2:0" EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \ $NO_UNDEFINED -version-info 0:0:0 \ @@ -18113,7 +19135,7 @@ if test "$enable_pcretest_libreadline" = "yes"; then fi fi -# Check for valgrind +# Handle valgrind support if test "$enable_valgrind" = "yes"; then @@ -18143,7 +19165,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -18186,7 +19208,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -18329,7 +19351,7 @@ $as_echo "yes" >&6; } fi fi -# test code coverage reporting +# Handle code coverage reporting support if test "$enable_coverage" = "yes"; then if test "x$GCC" != "xyes"; then as_fn_error $? "Code coverage reports can only be generated when using GCC" "$LINENO" 5 @@ -18354,7 +19376,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SHTOOL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -18407,7 +19429,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LCOV="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -18453,7 +19475,7 @@ 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 + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GENHTML="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -18480,11 +19502,7 @@ fi as_fn_error $? "genhtml not found" "$LINENO" 5 fi - -$as_echo "#define SUPPORT_GCOV 1" >>confdefs.h - - - # And add flags needed for gcov + # Set flags needed for gcov GCOV_CFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" GCOV_CXXFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" GCOV_LIBS="-lgcov" @@ -18624,6 +19642,14 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' @@ -18640,6 +19666,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then 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__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + 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. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -18978,16 +20008,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -19047,28 +20077,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -19089,8 +20107,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # 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.32, which was -generated by GNU Autoconf 2.68. Invocation command line was +This file was extended by PCRE $as_me 8.35, which was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -19155,11 +20173,11 @@ _ACEOF 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.32 -configured by $0, generated by GNU Autoconf 2.68, +PCRE config.status 8.35 +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -19250,7 +20268,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' @@ -19295,6 +20313,7 @@ pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' @@ -19375,7 +20394,6 @@ with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' @@ -19447,7 +20465,6 @@ with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' @@ -19489,6 +20506,7 @@ DLLTOOL \ OBJDUMP \ SHELL \ ECHO \ +PATH_SEPARATOR \ SED \ GREP \ EGREP \ @@ -19537,7 +20555,6 @@ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ -hardcode_libdir_flag_spec_ld \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ @@ -19571,7 +20588,6 @@ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ -hardcode_libdir_flag_spec_ld_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ @@ -20274,7 +21290,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -20287,7 +21303,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -20321,21 +21337,19 @@ $as_echo X"$mf" | continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || @@ -20389,8 +21403,8 @@ $as_echo X"$file" | # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. @@ -20453,6 +21467,9 @@ SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + # The host system. host_alias=$host_alias host=$host @@ -20748,10 +21765,6 @@ no_undefined_flag=$lt_no_undefined_flag # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec -# If ld is used when linking, flag to hardcode \$libdir into a binary -# during linking. This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld - # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator @@ -21094,10 +22107,6 @@ no_undefined_flag=$lt_no_undefined_flag_CXX # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX -# If ld is used when linking, flag to hardcode \$libdir into a binary -# during linking. This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX - # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX @@ -21255,6 +22264,7 @@ $PACKAGE-$VERSION configuration summary: Use stack recursion ............. : ${enable_stack_for_recursion} POSIX mem threshold ............. : ${with_posix_malloc_threshold} Internal link size .............. : ${with_link_size} + Nested parentheses limit ........ : ${with_parens_nest_limit} Match limit ..................... : ${with_match_limit} Match limit recursion ........... : ${with_match_limit_recursion} Build shared libs ............... : ${enable_shared} diff --git a/tools/pcre/configure.ac b/tools/pcre/configure.ac index a5dc3c79..aab2f56c 100644 --- a/tools/pcre/configure.ac +++ b/tools/pcre/configure.ac @@ -9,18 +9,18 @@ dnl The PCRE_PRERELEASE feature is for identifying release candidates. It might dnl be defined as -RC2, for example. For real releases, it should be empty. m4_define(pcre_major, [8]) -m4_define(pcre_minor, [32]) +m4_define(pcre_minor, [35]) m4_define(pcre_prerelease, []) -m4_define(pcre_date, [2012-11-30]) +m4_define(pcre_date, [2014-04-04]) # 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, [3:0:2]) -m4_define(libpcre16_version, [2:0:2]) -m4_define(libpcre32_version, [0:0:0]) -m4_define(libpcreposix_version, [0:1:0]) +m4_define(libpcre_version, [3:3:2]) +m4_define(libpcre16_version, [2:3:2]) +m4_define(libpcre32_version, [0:3:0]) +m4_define(libpcreposix_version, [0:2:0]) m4_define(libpcrecpp_version, [0:0:0]) AC_PREREQ(2.57) @@ -30,6 +30,9 @@ AM_INIT_AUTOMAKE([dist-bzip2 dist-zip]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_CONFIG_HEADERS(config.h) +# This is a new thing required to stop a warning from automake 1.12 +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) + # This was added at the suggestion of libtoolize (03-Jan-10) AC_CONFIG_MACRO_DIR([m4]) @@ -245,7 +248,7 @@ AC_ARG_ENABLE(pcregrep-libbz2, # Handle --with-pcregrep-bufsize=N AC_ARG_WITH(pcregrep-bufsize, AS_HELP_STRING([--with-pcregrep-bufsize=N], - [pcregrep buffer size (default=20480)]), + [pcregrep buffer size (default=20480, minimum=8192)]), , with_pcregrep_bufsize=20480) # Handle --enable-pcretest-libedit @@ -272,6 +275,12 @@ AC_ARG_WITH(link-size, [internal link size (2, 3, or 4 allowed; default=2)]), , with_link_size=2) +# Handle --with-parens-nest-limit=N +AC_ARG_WITH(parens-nest-limit, + AS_HELP_STRING([--with-parens-nest-limit=N], + [nested parentheses limit (default=250)]), + , with_parens_nest_limit=250) + # Handle --with-match-limit=N AC_ARG_WITH(match-limit, AS_HELP_STRING([--with-match-limit=N], @@ -427,24 +436,33 @@ AH_TOP([ can cope with, allowing it to run on SunOS4 and other "close to standard" systems. -In environments that support the facilities, config.h.in is converted by -"configure", or config-cmake.h.in is converted by CMake, into config.h. If you -are going to build PCRE "by hand" without using "configure" or CMake, you -should copy the distributed config.h.generic to config.h, and then edit the -macro definitions to be the way you need them. You must then add --DHAVE_CONFIG_H to all of your compile commands, so that config.h is included -at the start of every source. +In environments that support the GNU autotools, config.h.in is converted into +config.h by the "configure" script. In environments that use CMake, +config-cmake.in is converted into config.h. If you are going to build PCRE "by +hand" without using "configure" or CMake, you should copy the distributed +config.h.generic to config.h, and edit the macro definitions to be the way you +need them. You must then add -DHAVE_CONFIG_H to all of your compile commands, +so that config.h is included at the start of every source. Alternatively, you can avoid editing by using -D on the compiler command line -to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H. +to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H, +but if you do, default values will be taken from config.h for non-boolean +macros that are not defined on the command line. -PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if -HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set -them both to 0; an emulation function will be used. */]) +Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE8 should either be defined +(conventionally to 1) for TRUE, and not defined at all for FALSE. All such +macros are listed as a commented #undef in config.h.generic. Macros such as +MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are +surrounded by #ifndef/#endif lines so that the value can be overridden by -D. + +PCRE uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if +HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make +sure both macros are undefined; an emulation function will then be used. */]) # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS(limits.h sys/types.h sys/stat.h dirent.h windows.h) +AC_CHECK_HEADERS(limits.h sys/types.h sys/stat.h dirent.h) +AC_CHECK_HEADERS([windows.h], [HAVE_WINDOWS_H=1]) # The files below are C++ header files. pcre_have_type_traits="0" @@ -669,11 +687,15 @@ if test "$enable_pcre32" = "yes"; then Define to any value to enable the 32 bit PCRE library.]) fi +# Unless running under Windows, JIT support requires pthreads. + if test "$enable_jit" = "yes"; then - AX_PTHREAD([], [AC_MSG_ERROR([JIT support requires pthreads])]) - CC="$PTHREAD_CC" - CFLAGS="$PTHREAD_CFLAGS $CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" + if test "$HAVE_WINDOWS_H" != "1"; then + AX_PTHREAD([], [AC_MSG_ERROR([JIT support requires pthreads])]) + CC="$PTHREAD_CC" + CFLAGS="$PTHREAD_CFLAGS $CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + fi AC_DEFINE([SUPPORT_JIT], [], [ Define to any value to enable support for Just-In-Time compiling.]) else @@ -722,7 +744,12 @@ if test "$enable_pcregrep_libbz2" = "yes"; then fi if test $with_pcregrep_bufsize -lt 8192 ; then + AC_MSG_WARN([$with_pcregrep_bufsize is too small for --with-pcregrep-bufsize; using 8192]) with_pcregrep_bufsize="8192" +else + if test $? -gt 1 ; then + AC_MSG_ERROR([Bad value for --with-pcregrep-bufsize]) + fi fi AC_DEFINE_UNQUOTED([PCREGREP_BUFSIZE], [$with_pcregrep_bufsize], [ @@ -773,6 +800,11 @@ AC_DEFINE_UNQUOTED([POSIX_MALLOC_THRESHOLD], [$with_posix_malloc_threshold], [ faster than using malloc() for each call. The threshold above which the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD.]) +AC_DEFINE_UNQUOTED([PARENS_NEST_LIMIT], [$with_parens_nest_limit], [ + The value of PARENS_NEST_LIMIT specifies the maximum depth of nested + parentheses (of any kind) in a pattern. This limits the amount of system + stack that is used while compiling a pattern.]) + AC_DEFINE_UNQUOTED([MATCH_LIMIT], [$with_match_limit], [ The value of MATCH_LIMIT determines the default number of times the internal match() function can be called during a single execution of @@ -838,7 +870,7 @@ fi if test "$enable_valgrind" = "yes"; then AC_DEFINE_UNQUOTED([SUPPORT_VALGRIND], [], [ - Valgrind support to find invalid memory reads.]) + Define to any value for valgrind support to find invalid memory reads.]) fi # Platform specific issues @@ -946,7 +978,7 @@ if test "$enable_pcretest_libreadline" = "yes"; then fi fi -# Check for valgrind +# Handle valgrind support if test "$enable_valgrind" = "yes"; then m4_ifdef([PKG_CHECK_MODULES], @@ -954,7 +986,7 @@ if test "$enable_valgrind" = "yes"; then [AC_MSG_ERROR([pkg-config not supported])]) fi -# test code coverage reporting +# Handle code coverage reporting support if test "$enable_coverage" = "yes"; then if test "x$GCC" != "xyes"; then AC_MSG_ERROR([Code coverage reports can only be generated when using GCC]) @@ -985,11 +1017,7 @@ if test "$enable_coverage" = "yes"; then AC_MSG_ERROR([genhtml not found]) fi - AC_DEFINE([SUPPORT_GCOV],[1], [ - Define to allow pcretest and pcregrep to be linked with gcov, so that they - are able to generate code coverage reports.]) - - # And add flags needed for gcov + # Set flags needed for gcov GCOV_CFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" GCOV_CXXFLAGS="-O0 -ggdb3 -fprofile-arcs -ftest-coverage" GCOV_LIBS="-lgcov" @@ -1064,6 +1092,7 @@ $PACKAGE-$VERSION configuration summary: Use stack recursion ............. : ${enable_stack_for_recursion} POSIX mem threshold ............. : ${with_posix_malloc_threshold} Internal link size .............. : ${with_link_size} + Nested parentheses limit ........ : ${with_parens_nest_limit} Match limit ..................... : ${with_match_limit} Match limit recursion ........... : ${with_match_limit_recursion} Build shared libs ............... : ${enable_shared} diff --git a/tools/pcre/depcomp b/tools/pcre/depcomp index 25a39e6c..4ebd5b3a 100644 --- a/tools/pcre/depcomp +++ b/tools/pcre/depcomp @@ -1,10 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2012-03-27.16; # UTC +scriptversion=2013-05-30.07; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,9 +27,9 @@ scriptversion=2012-03-27.16; # UTC case $1 in '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] @@ -57,11 +56,65 @@ EOF ;; esac +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + # A tabulation character. tab=' ' # A newline character. nl=' ' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 @@ -75,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" +# Avoid interferences from the environment. +gccflag= dashmflag= + # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case @@ -86,32 +142,32 @@ if test "$depmode" = hp; then fi if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvisualcpp + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then - # This is just like msvc7 but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvc7 + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 fi if test "$depmode" = xlc; then - # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations. - gccflag=-qmakedep=gcc,-MF - depmode=gcc + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc fi case "$depmode" in @@ -134,8 +190,7 @@ gcc3) done "$@" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -143,13 +198,17 @@ gcc3) ;; gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then @@ -157,15 +216,14 @@ gcc) fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. + # The second -e expression handles DOS-style file names with drive + # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. @@ -174,15 +232,15 @@ gcc) ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. - tr ' ' "$nl" < "$tmpdepfile" | ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -200,8 +258,7 @@ sgi) "$@" -MDupdate "$tmpdepfile" fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -209,7 +266,6 @@ sgi) if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" - # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in @@ -217,19 +273,15 @@ sgi) # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr "$nl" ' ' >> "$depfile" + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" - # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" ;; @@ -247,9 +299,8 @@ aix) # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u @@ -262,9 +313,7 @@ aix) "$@" -M fi stat=$? - - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi @@ -273,65 +322,113 @@ aix) do test -f "$tmpdepfile" && break done - if test -f "$tmpdepfile"; then - # Each line is of the form 'foo.o: dependent.h'. - # Do two passes, one to just change these to - # '$object: dependent.h' and one to simply 'dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" + aix_post_process_depfile ;; -icc) - # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'. - # However on - # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using '\': - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - # tcc 0.9.26 (FIXME still under development at the moment of writing) - # will emit a similar output, but also prepend the continuation lines - # with horizontal tabulation characters. +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" - # Each line is of the form 'foo.o: dependent.h', - # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'. + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to - # '$object: dependent.h' and one to simply 'dependent.h:'. - sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \ - < "$tmpdepfile" > "$depfile" - sed ' - s/[ '"$tab"'][ '"$tab"']*/ /g - s/^ *// - s/ *\\*$// - s/^[^:]*: *// - /^$/d - /:$/d - s/$/ :/ - ' < "$tmpdepfile" >> "$depfile" + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -342,9 +439,8 @@ hp2) # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d @@ -355,8 +451,7 @@ hp2) "$@" +Maked fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi @@ -366,76 +461,61 @@ hp2) test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" else - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in 'foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; msvc7) if test "$libtool" = yes; then @@ -446,8 +526,7 @@ msvc7) "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" - if test "$stat" = 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -473,6 +552,7 @@ $ { G p }' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; @@ -524,13 +604,14 @@ dashmstdout) # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | - sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile" + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" - tr ' ' "$nl" < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -583,10 +664,12 @@ makedepend) # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; @@ -622,10 +705,10 @@ cpp) esac done - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" @@ -657,15 +740,15 @@ msvisualcpp) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; + set fnord "$@" + shift + shift + ;; *) - set fnord "$@" "$arg" - shift - shift - ;; + set fnord "$@" "$arg" + shift + shift + ;; esac done "$@" -E 2>/dev/null | diff --git a/tools/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt b/tools/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt new file mode 100644 index 00000000..cddf3e06 --- /dev/null +++ b/tools/pcre/doc/html/NON-AUTOTOOLS-BUILD.txt @@ -0,0 +1,764 @@ +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 + Calling conventions 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 CE with Visual Studio 200x + Building under Windows with BCC5.5 + Building using Borland C++ Builder 2007 (CB2007) and higher + Building PCRE on OpenVMS + Building PCRE on Stratus OpenVOS + Building PCRE on native z/OS and z/VM + + +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". If you are going to use CMake, this section does not apply to you; you +can skip ahead to the CMake section. + + (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, you can alter the definition of the NEWLINE macro to + specify what character(s) you want to be interpreted as line terminators. + In an EBCDIC environment, you MUST change NEWLINE, because its default + value is 10, an ASCII LF. The usual EBCDIC newline character is 21 (0x15, + NL), though in some cases it may be 37 (0x25). + + 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_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 + + 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. + + Note that you must still compile pcre_jit_compile.c, even if you have not + defined SUPPORT_JIT in config.h, because when JIT support is not + configured, dummy functions are compiled. When JIT support IS configured, + pcre_jit_compile.c #includes sources from the sljit subdirectory, where + there should be 16 files, all of whose names begin with "sljit". + + (6) 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. + + (7) If you want to build a 16-bit library (as well as, or instead of the 8-bit + or 32-bit libraries) repeat steps 5-6 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 + 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 + + (8) If you want to build a 32-bit library (as well as, or instead of the 8-bit + or 16-bit libraries) repeat steps 5-6 with the following files: + + pcre32_byte_order.c + pcre32_chartables.c + pcre32_compile.c + pcre32_config.c + pcre32_dfa_exec.c + pcre32_exec.c + pcre32_fullinfo.c + pcre32_get.c + pcre32_globals.c + pcre32_jit_compile.c + pcre32_maketables.c + pcre32_newline.c + pcre32_ord2utf32.c + pcre32_refcount.c + pcre32_string_utils.c + pcre32_study.c + pcre32_tables.c + pcre32_ucd.c + pcre32_utf32_utils.c + pcre32_valid_utf32.c + pcre32_version.c + pcre32_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 any combination of the 8-bit, + 16-bit and 32-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 more than one of the 8-bit, 16-bit and + 32-bit libraries, you need to run pcretest with the -16 option to do + 16-bit tests and with the -32 option to do 32-bit tests. + + Some tests are relevant only when certain build-time options are selected. + For example, test 4 is for UTF-8/UTF-16/UTF-32 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. The command "RunTest list" will + output a list of all the tests. + + 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 freestanding 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. If they are not +followed exactly, errors may occur. In the event that errors do occur, it is +recommended that you delete the CMake cache before attempting to repeat the +CMake build process. In the CMake GUI, the cache can be deleted by selecting +"File > Delete Cache". + +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++. Do not try + to start Cmake from the Windows Start menu, as this can lead to errors. + +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 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 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 USING BORLAND C++ BUILDER 2007 (CB2007) AND HIGHER + +A PCRE user sent these comments about this environment (see also the comment +from another user that follows them): + +The XE versions of C++ Builder come with a RegularExpressionsCore class which +contain a version of TPerlRegEx. However, direct use of the C PCRE library may +be desirable. + +The default makevp.bat, however, supplied with PCRE builds a version of PCRE +that is not usable with any version of C++ Builder because the compiler ships +with an embedded version of PCRE, version 2.01 from 1998! [See also the note +about BCC5.5 above.] If you want to use PCRE you'll need to rename the +functions (pcre_compile to pcre_compile_bcc, etc) or do as I have done and just +use the 16 bit versions. I'm using std::wstring everywhere anyway. Since the +embedded version of PCRE does not have the 16 bit function names, there is no +conflict. + +Building PCRE using a C++ Builder static library project file (recommended): + +1. Rename or remove pcre.h, pcreposi.h, and pcreposix.h from your C++ Builder +original include path. + +2. Download PCRE from pcre.org and extract to a directory. + +3. Rename pcre_chartables.c.dist to pcre_chartables.c, pcre.h.generic to +pcre.h, and config.h.generic to config.h. + +4. Edit pcre.h and pcre_config.c so that they include config.h. + +5. Edit config.h like so: + +Comment out the following lines: +#define PACKAGE "pcre" +#define PACKAGE_BUGREPORT "" +#define PACKAGE_NAME "PCRE" +#define PACKAGE_STRING "PCRE 8.32" +#define PACKAGE_TARNAME "pcre" +#define PACKAGE_URL "" +#define PACKAGE_VERSION "8.32" + +Add the following lines: +#ifndef SUPPORT_UTF +#define SUPPORT_UTF 100 // any value is fine +#endif + +#ifndef SUPPORT_UCP +#define SUPPORT_UCP 101 // any value is fine +#endif + +#ifndef SUPPORT_UCP +#define SUPPORT_PCRE16 102 // any value is fine +#endif + +#ifndef SUPPORT_UTF8 +#define SUPPORT_UTF8 103 // any value is fine +#endif + +6. Build a C++ Builder project using the IDE. Go to File / New / Other and +choose Static Library. You can name it pcre.cbproj or whatever. Now set your +paths by going to Project / Options. Set the Include path. Do this from the +"Base" option to apply to both Release and Debug builds. Now add the following +files to the project: + +pcre.h +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_maketables.c +pcre16_newline.c +pcre16_ord2utf16.c +pcre16_printint.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 + +//Optional +pcre_version.c + +7. After compiling the .lib file, copy the .lib and header files to a project +you want to use PCRE with. Enjoy. + +Optional ... Building PCRE using the makevp.bat file: + +1. Edit makevp_c.txt and makevp_l.txt and change all the names to the 16 bit +versions. + +2. Edit makevp.bat and set the path to C++ Builder. Run makevp.bat. + +Another PCRE user added this comment: + +Another approach I successfully used for some years with BCB 5 and 6 was to +make sure that include and library paths of PCRE are configured before the +default paths of the IDE in the dialogs where one can manage those paths. +Afterwards one can open the project files using a text editor and manually add +the self created library for pcre itself, pcrecpp doesn't ship with the IDE, in +the library nodes where the IDE manages its own libraries to link against in +front of the IDE-own libraries. This way one can use the default PCRE function +names without getting access violations on runtime. + + + + +BUILDING PCRE ON OPENVMS + +Stephen Hoffman sent the following, in December 2012: + +"Here is a very short write-up on the +OpenVMS port and here + + + +is a zip with the OpenVMS files, and with one modified testing-related PCRE +file." This is a port of PCRE 8.32. + +Earlier, 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. + + +BUILDING PCRE ON NATIVE Z/OS AND Z/VM + +z/OS and z/VM are operating systems for mainframe computers, produced by IBM. +The character code used is EBCDIC, not ASCII or Unicode. In z/OS, UNIX APIs and +applications can be supported through UNIX System Services, and in such an +environment PCRE can be built in the same way as in other systems. However, in +native z/OS (without UNIX System Services) and in z/VM, special ports are +required. For details, please see this web site: + + http://www.zaconsultants.net + +There is also a mirror here: + + http://www.vsoft-software.com/downloads.html + +========================== +Last Updated: 14 May 2013 diff --git a/tools/pcre/doc/html/README.txt b/tools/pcre/doc/html/README.txt new file mode 100644 index 00000000..88f2dfd4 --- /dev/null +++ b/tools/pcre/doc/html/README.txt @@ -0,0 +1,991 @@ +README file for PCRE (Perl-compatible regular expression library) +----------------------------------------------------------------- + +The latest release of PCRE is always available in three alternative formats +from: + + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.bz2 + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.zip + +There is a mailing list for discussion about the development of PCRE at +pcre-dev@exim.org. You can access the archives and subscribe or manage your +subscription here: + + https://lists.exim.org/mailman/listinfo/pcre-dev + +Please read the NEWS file if you are upgrading from a previous release. +The contents of this README file are: + + The PCRE APIs + Documentation for PCRE + Contributions by users of PCRE + 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) + Compiling in Tru64 using native compilers + Using Sun's compilers for Solaris + Using PCRE from MySQL + Making new tarballs + Testing PCRE + Character tables + File manifest + + +The PCRE APIs +------------- + +PCRE is written in C, and it has its own API. There are three sets of +functions, one for the 8-bit library, which processes strings of bytes, one for +the 16-bit library, which processes strings of 16-bit values, and one for the +32-bit library, which processes strings of 32-bit values. The distribution also +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 +with existing files of that name by distributing it that way. To use PCRE with +an existing program that uses the POSIX API, pcreposix.h will have to be +renamed or pointed at by a link. + +If you are using the POSIX interface to PCRE and there is already a POSIX regex +library installed on your system, as well as worrying about the regex.h header +file (as mentioned above), you must also take care when linking programs to +ensure that they link with PCRE's libpcreposix library. Otherwise they may pick +up the POSIX functions of the same name from the other library. + +One way of avoiding this confusion is to compile PCRE with the addition of +-Dregcomp=PCREregcomp (and similarly for the other POSIX functions) to the +compiler flags (CFLAGS if you are using "configure" -- see below). This has the +effect of renaming the functions so that the names no longer clash. Of course, +you have to do the same thing for your applications, or write them using the +new names. + + +Documentation for PCRE +---------------------- + +If you install PCRE in the normal way on a Unix-like system, you will end up +with a set of man pages whose names all start with "pcre". The one that is just +called "pcre" lists all the others. In addition to these man pages, the PCRE +documentation is supplied in two other forms: + + 1. There are files called doc/pcre.txt, doc/pcregrep.txt, and + doc/pcretest.txt in the source distribution. The first of these is a + concatenation of the text forms of all the section 3 man pages except + the listing of pcredemo.c and those that summarize individual functions. + The other two are the text forms of the section 1 man pages for the + pcregrep and pcretest commands. These text forms are provided for ease of + scanning with text editors or similar tools. They are installed in + /share/doc/pcre, where is the installation prefix + (defaulting to /usr/local). + + 2. A set of files containing all the documentation in HTML form, hyperlinked + in various ways, and rooted in a file called index.html, is distributed in + doc/html and installed in /share/doc/pcre/html. + +Users of PCRE have contributed files containing the documentation for various +releases in CHM format. These can be found in the Contrib directory of the FTP +site (see next section). + + +Contributions by users of PCRE +------------------------------ + +You can find contributions from PCRE users in the directory + + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib + +There is a README file giving brief descriptions of what they are. Some are +complete in themselves; others are pointers to URLs containing relevant files. +Some of this material is likely to be well out-of-date. Several of the earlier +contributions provided support for compiling PCRE on various flavours of +Windows (I myself do not use Windows). Nowadays there is more Windows support +in the standard distribution, so these contibutions have been archived. + +A PCRE user maintains downloadable Windows binaries of the pcregrep and +pcretest programs here: + + http://www.rexegg.com/pcregrep-pcretest.html + + +Building PCRE on non-Unix-like systems +-------------------------------------- + +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 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" (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, +the usual methods of changing standard defaults are available. For example: + +CFLAGS='-O2 -Wall' ./configure --prefix=/opt/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 +into /source/pcre/pcre-xxx, but you want to build it in /build/pcre/pcre-xxx: + +cd /build/pcre/pcre-xxx +/source/pcre/pcre-xxx/configure + +PCRE is written in C and is normally compiled as a C library. However, it is +possible to build it as a C++ library, though the provided building apparatus +does not have any features to support this. + +There are some optional features that can be included or omitted from the PCRE +library. 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 + + (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 add + --enable-pcre32 to the "configure" command, the 32-bit library is also built. + If you want only the 16-bit or 32-bit library, use --disable-pcre8 to disable + building the 8-bit library. + +. 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 + the 8-bit library, or UTF-16 Unicode character strings in the 16-bit library, + or UTF-32 Unicode character strings in the 32-bit library, you must add + --enable-utf to the "configure" command. Without it, the code for handling + UTF-8, UTF-16 and UTF-8 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/32, 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, UTF-16 and UTF-32 + 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 or 32-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/32 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 + end of a line. Whatever you specify at build time is the default; the caller + of PCRE can change the selection at run time. The default newline indicator + is a single LF character (the Unix standard). You can specify the default + newline indicator by adding --enable-newline-is-cr or --enable-newline-is-lf + or --enable-newline-is-crlf or --enable-newline-is-anycrlf or + --enable-newline-is-any to the "configure" command, respectively. + + If you specify --enable-newline-is-cr or --enable-newline-is-crlf, some of + the standard tests will fail, because the lines in the test files end with + LF. Even if the files are edited to change the line endings, there are likely + to be some failures. With --enable-newline-is-anycrlf or + --enable-newline-is-any, many tests should succeed, but there may be some + failures. + +. By default, the sequence \R in a pattern matches any Unicode line ending + sequence. This is independent of the option specifying what PCRE considers to + be the end of a line (see above). However, the caller of PCRE can restrict \R + to match only CR, LF, or CRLF. You can make this the default by adding + --enable-bsr-anycrlf to the "configure" command (bsr = "backslash R"). + +. When called via the POSIX interface, PCRE uses malloc() to get additional + storage for processing capturing parentheses if there are more than 10 of + them in a pattern. You can increase this threshold by setting, for example, + + --with-posix-malloc-threshold=20 + + on the "configure" command. + +. PCRE has a counter that limits the depth of nesting of parentheses in a + pattern. This limits the amount of system stack that a pattern uses when it + is compiled. The default is 250, but you can change it by setting, for + example, + + --with-parens-nest-limit=500 + +. PCRE has a counter that can be set to limit the amount of resources it uses + when matching a pattern. If the limit is exceeded during a match, the match + fails. The default is ten million. You can change the default by setting, for + example, + + --with-match-limit=500000 + + on the "configure" command. This is just the default; individual calls to + pcre_exec() can supply their own value. There is more discussion on the + pcreapi man page. + +. There is a separate counter that limits the depth of recursive function calls + during a matching process. This also has a default of ten million, which is + essentially "unlimited". You can change the default by setting, for example, + + --with-match-limit-recursion=500000 + + Recursive function calls use up the runtime stack; running out of stack can + cause programs to crash in strange ways. There is a discussion about stack + 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. 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. In the 32-bit + library, the only supported link size is 4. + +. 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 + obtained from the heap via the special functions pcre_stack_malloc() and + pcre_stack_free() to save data that would otherwise be saved on the stack. To + build PCRE like this, use + + --disable-stack-for-recursion + + 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 + 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 + tables for ASCII encoding that is part of the distribution. If you specify + + --enable-rebuild-chartables + + a program called dftables is compiled and run in the default C locale when + you obey "make". It builds a source file called pcre_chartables.c. If you do + not specify this option, pcre_chartables.c is created as a copy of + pcre_chartables.c.dist. See "Character tables" below for further information. + +. It is possible to compile PCRE for use on systems that use EBCDIC as their + character code (as opposed to ASCII/Unicode) by specifying + + --enable-ebcdic + + 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/16/32. There is a second option, --enable-ebcdic-nl25, + which specifies that the code value for the EBCDIC NL character is 0x25 + instead of the default 0x15. + +. In environments where valgrind is installed, if you specify + + --enable-valgrind + + PCRE will use valgrind annotations to mark certain memory regions as + unaddressable. This allows it to detect invalid memory accesses, and is + mostly useful for debugging PCRE itself. + +. In environments where the gcc compiler is used and lcov version 1.6 or above + is installed, if you specify + + --enable-coverage + + the build process implements a code coverage report for the test suite. The + report is generated by running "make coverage". If ccache is installed on + your system, it must be disabled when building PCRE for coverage reporting. + You can do this by setting the environment variable CCACHE_DISABLE=1 before + running "make" to build PCRE. There is more information about coverage + reporting in the "pcrebuild" documentation. + +. The pcregrep program currently supports only 8-bit data files, and so + requires the 8-bit PCRE library. It is possible to compile pcregrep to use + 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 (in bytes) of the internal buffer used by pcregrep can be + set by, for example: + + --with-pcregrep-bufsize=51200 + + The value must be a plain integer. The default is 20480. + +. It is possible to compile pcretest so that it links with the libreadline + or libedit libraries, by specifying, respectively, + + --enable-pcretest-libreadline or --enable-pcretest-libedit + + If this is done, when pcretest's input is from a terminal, it reads it using + the readline() function. This provides line-editing and history facilities. + Note that libreadline is GPL-licenced, so if you distribute a binary of + pcretest linked in this way, there may be licensing issues. These can be + avoided by linking with libedit (which has a BSD licence) instead. + + 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 + to specify something like LIBS="-lncurses" as well. This is because, to quote + the readline INSTALL, "Readline uses the termcap functions, but does not link + with the termcap or curses library itself, allowing applications which link + with readline the to choose an appropriate library." If you get error + messages about missing functions tgetstr, tgetent, tputs, tgetflag, or tgoto, + this is the problem, and linking with the ncurses library should fix it. + +The "configure" script builds the following files for the basic C library: + +. 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 ) +. libpcre32.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. + +When building the 8-bit library, if a C++ compiler is found, the following +files are also built: + +. 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". This builds the the libraries +libpcre, libpcre16 and/or libpcre32, 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. + +You can use "make install" to install PCRE into live directories on your +system. The following are installed (file names are all relative to the + that is set when "configure" is run): + + Commands (bin): + pcretest + pcregrep (if 8-bit support is enabled) + pcre-config + + Libraries (lib): + libpcre16 (if 16-bit support is enabled) + libpcre32 (if 32-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 + libpcre32.pc + libpcre.pc + libpcreposix.pc + libpcrecpp.pc (if C++ support is enabled) + + Header files (include): + pcre.h + pcreposix.h + pcre_scanner.h ) + pcre_stringpiece.h ) if C++ support is enabled + pcrecpp.h ) + pcrecpparg.h ) + + Man pages (share/man/man{1,3}): + pcregrep.1 + pcretest.1 + pcre-config.1 + pcre.3 + pcre*.3 (lots more pages, all starting "pcre") + + HTML documentation (share/doc/pcre/html): + index.html + *.html (lots more pages, hyperlinked from index.html) + + Text file documentation (share/doc/pcre): + AUTHORS + COPYING + ChangeLog + 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-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 +------------------------------------ + +Running "make install" installs the command pcre-config, which can be used to +recall information about the PCRE configuration and installation. For example: + + pcre-config --version + +prints the version number, and + + pcre-config --libs + +outputs information about where the library is installed. This command can be +included in makefiles for programs that use PCRE, saving the programmer from +having to remember too many details. + +The pkg-config command is another system for saving and retrieving information +about installed libraries. Instead of separate commands for each library, a +single command is used. For example: + + pkg-config --cflags pcre + +The data is held in *.pc files that are installed in a directory called +/lib/pkgconfig. + + +Shared libraries +---------------- + +The default distribution builds PCRE as shared libraries and static libraries, +as long as the operating system supports shared libraries. Shared library +support relies on the "libtool" script which is built as part of the +"configure" process. + +The libtool script is used to compile and link both shared and static +libraries. They are placed in a subdirectory called .libs when they are newly +built. The programs pcretest and pcregrep are built to use these uninstalled +libraries (by means of wrapper scripts in the case of shared libraries). When +you use "make install" to install shared libraries, pcregrep and pcretest are +automatically re-built to use the newly installed shared libraries before being +installed themselves. However, the versions left in the build directory still +use the uninstalled libraries. + +To build PCRE using static libraries only you must use --disable-shared when +configuring it. For example: + +./configure --prefix=/usr/gnu --disable-shared + +Then run "make" in the usual way. Similarly, you can use --disable-static to +build only shared libraries. + + +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 +specify --enable-rebuild-chartables, because if you do, the dftables.c source +file is compiled and run on the local host, in order to generate the inbuilt +character tables (the pcre_chartables.c file). This will probably not work, +because dftables.c needs to be compiled with the local compiler, not the cross +compiler. + +When --enable-rebuild-chartables is not specified, pcre_chartables.c is created +by making a copy of pcre_chartables.c.dist, which is a default set of tables +that assumes ASCII code. Cross-compiling with the default tables should not be +a problem. + +If you need to modify the character tables when cross-compiling, you should +move pcre_chartables.c.dist out of the way, then compile dftables.c by hand and +run it on the local host to make a new version of pcre_chartables.c.dist. +Then when you cross-compile PCRE this new version of the tables will be used. + + +Using HP's ANSI C++ compiler (aCC) +---------------------------------- + +Unless C++ support is disabled by specifying the "--disable-cpp" option of the +"configure" script, you must include the "-AA" option in the CXXFLAGS +environment variable in order for the C++ components to compile correctly. + +Also, note that the aCC compiler on PA-RISC platforms may have a defect whereby +needed libraries fail to get included when specifying the "-AA" compiler +option. If you experience unresolved symbols when linking the C++ programs, +use the workaround of specifying the following environment variable prior to +running the "configure" script: + + CXXLDFLAGS="-lstd_v2 -lCsup_v2" + + +Compiling in Tru64 using native compilers +----------------------------------------- + +The following error may occur when compiling with native compilers in the Tru64 +operating system: + + CXX libpcrecpp_la-pcrecpp.lo +cxx: Error: /usr/lib/cmplrs/cxx/V7.1-006/include/cxx/iosfwd, line 58: #error + directive: "cannot include iosfwd -- define __USE_STD_IOSTREAM to + override default - see section 7.1.2 of the C++ Using Guide" +#error "cannot include iosfwd -- define __USE_STD_IOSTREAM to override default +- see section 7.1.2 of the C++ Using Guide" + +This may be followed by other errors, complaining that 'namespace "std" has no +member'. The solution to this is to add the line + +#define __USE_STD_IOSTREAM 1 + +to the config.h file. + + +Using Sun's compilers for Solaris +--------------------------------- + +A user reports that the following configurations work on Solaris 9 sparcv9 and +Solaris 9 x86 (32-bit): + + Solaris 9 sparcv9: ./configure --disable-cpp CC=/bin/cc CFLAGS="-m64 -g" + Solaris 9 x86: ./configure --disable-cpp CC=/bin/cc CFLAGS="-g" + + +Using PCRE from MySQL +--------------------- + +On systems where both PCRE and MySQL are installed, it is possible to make use +of PCRE from within MySQL, as an alternative to the built-in pattern matching. +There is a web page that tells you how to do this: + + http://www.mysqludf.org/lib_mysqludf_preg/index.php + + +Making new tarballs +------------------- + +The command "make dist" creates three PCRE tarballs, in tar.gz, tar.bz2, and +zip formats. The command "make distcheck" does the same, but then does a trial +build of the new distribution to ensure that it works. + +If you have modified any of the man page sources in the doc directory, you +should first run the PrepareRelease script before making a distribution. This +script creates the .txt and HTML forms of the documentation from the man pages. + + +Testing PCRE +------------ + +To test the basic PCRE library on a Unix-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 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 relevant testinput files in the testdata +directory, and compares the output with the contents of the corresponding +testoutput files. RunTest uses a file called testtry to hold the main output +from pcretest. Other files whose names begin with "test" are used as working +files in some tests. + +Some tests are relevant only when certain build-time options were selected. For +example, the tests for UTF-8/16/32 support are run only if --enable-utf was +used. RunTest outputs a comment when it skips a test. + +Many of the tests that are not skipped are run up to three times. The second +run forces pcre_study() to be called for all patterns except for a few in some +tests that are marked "never study" (see the pcretest program for how this is +done). If JIT support is available, the non-DFA tests are run a third time, +this time with a forced pcre_study() with the PCRE_STUDY_JIT_COMPILE option. +This testing can be suppressed by putting "nojit" on the RunTest command line. + +The entire set of tests is run once for each of the 8-bit, 16-bit and 32-bit +libraries that are enabled. If you want to run just one set of tests, call +RunTest with either the -8, -16 or -32 option. + +If valgrind is installed, you can run the tests under it by putting "valgrind" +on the RunTest command line. To run pcretest on just one or more specific test +files, give their numbers as arguments to RunTest, for example: + + RunTest 2 7 11 + +You can also specify ranges of tests such as 3-6 or 3- (meaning 3 to the +end), or a number preceded by ~ to exclude a test. For example: + + Runtest 3-15 ~10 + +This runs tests 3 to 15, excluding test 10, and just ~13 runs all the tests +except test 13. Whatever order the arguments are in, the tests are always run +in numerical order. + +You can also call RunTest with the single argument "list" to cause it to output +a list of tests. + +The first test file can be fed directly into the perltest.pl script to check +that Perl gives the same results. The only difference you should see is in the +first few lines, where the Perl version is given instead of the PCRE version. + +The second set of tests check pcre_fullinfo(), pcre_study(), +pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error +detection, and run-time flags that are specific to PCRE, as well as the POSIX +wrapper API. It also uses the debugging flags to check some of the internals of +pcre_compile(). + +If you build PCRE with a locale setting that is not the standard C locale, the +character tables may be different (see next paragraph). In some cases, this may +cause failures in the second set of tests. For example, in a locale where the +isprint() function yields TRUE for characters in the range 128-255, the use of +[:isascii:] inside a character class defines a different set of characters, and +this shows up in this test as a difference in the compiled code, which is being +listed for checking. Where the comparison test output contains [\x00-\x7f] the +test will contain [\x00-\xff], and similarly in some other cases. This is not a +bug in PCRE. + +The third set of tests checks pcre_maketables(), the facility for building a +set of character tables for a specific locale and using them instead of the +default tables. The tests make use of the "fr_FR" (French) locale. Before +running the test, the script checks for the presence of this locale by running +the "locale" command. If that command fails, or if it doesn't include "fr_FR" +in the list of available locales, the third test cannot be run, and a comment +is output to say why. If running this test produces instances of the error + + ** Failed to set locale "fr_FR" + +in the comparison output, it means that locale is not available on your system, +despite being listed by "locale". This does not mean that PCRE is broken. + +[If you are trying to run this test on Windows, you may be able to get it to +work by changing "fr_FR" to "french" everywhere it occurs. Alternatively, use +RunTest.bat. The version of RunTest.bat included with PCRE 7.4 and above uses +Windows versions of test 2. More info on using RunTest.bat is included in the +document entitled NON-UNIX-USE.] + +The fourth and fifth tests check the UTF-8/16/32 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/32 mode, UTF-8/16/32 mode, and UTF-8/16/32 +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/32-bit +mode. These are tests that generate different output in the two modes. They are +for general cases, UTF-8/16/32 support, and Unicode property support, +respectively. + +The twentieth test is run only in 16/32-bit mode. It tests some specific +16/32-bit features of the DFA matching engine. + +The twenty-first and twenty-second tests are run only in 16/32-bit mode, when +the link size is set to 2 for the 16-bit library. They test reloading +pre-compiled patterns. + +The twenty-third and twenty-fourth tests are run only in 16-bit mode. They are +for general cases, and UTF-16 support, respectively. + +The twenty-fifth and twenty-sixth tests are run only in 32-bit mode. They are +for general cases, and UTF-32 support, respectively. + + +Character tables +---------------- + +For speed, PCRE uses four tables for manipulating and identifying characters +whose code point values are less than 256. The final argument of the +pcre_compile() function is a pointer to a block of memory containing the +concatenated tables. A call to pcre_maketables() can be used to generate a set +of tables in the current locale. If the final argument for pcre_compile() is +passed as NULL, a set of default tables that is built into the binary is used. + +The source file called pcre_chartables.c contains the default set of tables. By +default, this is created as a copy of pcre_chartables.c.dist, which contains +tables for ASCII coding. However, if --enable-rebuild-chartables is specified +for ./configure, a different version of pcre_chartables.c is built by the +program dftables (compiled from dftables.c), which uses the ANSI C character +handling functions such as isalnum(), isalpha(), isupper(), islower(), etc. to +build the table sources. This means that the default C locale which is set for +your system will control the contents of these default tables. You can change +the default tables by editing pcre_chartables.c and then re-building PCRE. If +you do this, you should take care to ensure that the file does not get +automatically re-generated. The best way to do this is to move +pcre_chartables.c.dist out of the way and replace it with your customized +tables. + +When the dftables program is run as a result of --enable-rebuild-chartables, +it uses the default C locale that is set on your system. It does not pay +attention to the LC_xxx environment variables. In other words, it uses the +system's default locale rather than whatever the compiling user happens to have +set. If you really do want to build a source set of character tables in a +locale that is specified by the LC_xxx variables, you can run the dftables +program by hand with the -L option. For example: + + ./dftables -L pcre_chartables.c.special + +The first two 256-byte tables provide lower casing and case flipping functions, +respectively. The next table consists of three 32-byte bit maps which identify +digits, "word" characters, and white space, respectively. These are used when +building 32-byte bit maps that represent character classes for code points less +than 256. + +The final 256-byte table has bits indicating various character types, as +follows: + + 1 white space character + 2 letter + 4 decimal digit + 8 hexadecimal digit + 16 alphanumeric or '_' + 128 regular expression metacharacter or binary zero + +You should not alter the set of characters that contain the 128 bit, as that +will cause PCRE to malfunction. + + +File manifest +------------- + +The distribution should contain the files listed below. Where a file name is +given as pcre[16|32]_xxx it means that there are three files, one with the name +pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx. + +(A) Source files of the PCRE library functions and their headers: + + dftables.c auxiliary program for building pcre_chartables.c + when --enable-rebuild-chartables is specified + + pcre_chartables.c.dist a default set of character tables that assume ASCII + coding; used, unless --enable-rebuild-chartables is + specified, by copying to pcre[16]_chartables.c + + pcreposix.c ) + pcre[16|32]_byte_order.c ) + pcre[16|32]_compile.c ) + pcre[16|32]_config.c ) + pcre[16|32]_dfa_exec.c ) + pcre[16|32]_exec.c ) + pcre[16|32]_fullinfo.c ) + pcre[16|32]_get.c ) sources for the functions in the library, + pcre[16|32]_globals.c ) and some internal functions that they use + pcre[16|32]_jit_compile.c ) + pcre[16|32]_maketables.c ) + pcre[16|32]_newline.c ) + pcre[16|32]_refcount.c ) + pcre[16|32]_string_utils.c ) + pcre[16|32]_study.c ) + pcre[16|32]_tables.c ) + pcre[16|32]_ucd.c ) + pcre[16|32]_version.c ) + pcre[16|32]_xclass.c ) + pcre_ord2utf8.c ) + pcre_valid_utf8.c ) + pcre16_ord2utf16.c ) + pcre16_utf16_utils.c ) + pcre16_valid_utf16.c ) + pcre32_utf32_utils.c ) + pcre32_valid_utf32.c ) + + pcre[16|32]_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" + + pcrecpp.h public header file for the C++ wrapper + pcrecpparg.h.in template for another C++ header file + pcre_scanner.h public header file for C++ scanner functions + pcrecpp.cc ) + pcre_scanner.cc ) source for the C++ wrapper library + + pcre_stringpiece.h.in template for pcre_stringpiece.h, the header for the + C++ stringpiece functions + pcre_stringpiece.cc source for the C++ stringpiece functions + +(B) Source files for programs that use PCRE: + + pcredemo.c simple demonstration of coding calls to PCRE + pcregrep.c source of a grep utility that uses PCRE + pcretest.c comprehensive test program + +(C) Auxiliary files: + + 132html script to turn "man" pages into HTML + AUTHORS information about the author of PCRE + ChangeLog log of changes to the code + CleanTxt script to clean nroff output for txt man pages + Detrail script to remove trailing spaces + HACKING some notes about the internals of PCRE + INSTALL generic installation instructions + LICENCE conditions for the use of PCRE + COPYING the same, using GNU's standard name + Makefile.in ) template for Unix Makefile, which is built by + ) "configure" + Makefile.am ) the automake input that was used to create + ) Makefile.in + NEWS important changes in this release + 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 + RunGrepTest a Unix shell script for pcregrep tests + aclocal.m4 m4 macros (generated by "aclocal") + config.guess ) files used by libtool, + config.sub ) used only when building a shared library + configure a configuring shell script (built by autoconf) + configure.ac ) the autoconf input that was used to build + ) "configure" and config.h + depcomp ) script to find program dependencies, generated by + ) automake + doc/*.3 man page sources for PCRE + doc/*.1 man page sources for pcregrep and pcretest + doc/index.html.src the base HTML page + doc/html/* HTML documentation + doc/pcre.txt plain text version of the man pages + 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 + libpcre32.pc.in template for libpcre32.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 + ltmain.sh file used to build a libtool script + missing ) common stub for a few missing GNU programs while + ) installing, generated by automake + 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 + +(E) Auxiliary files for VPASCAL + + makevp.bat + makevp_c.txt + makevp_l.txt + pcregexp.pas + +(F) Auxiliary files for building PCRE "by hand" + + pcre.h.generic ) a version of the public PCRE header file + ) for use in non-"configure" environments + config.h.generic ) a version of config.h for use in non-"configure" + ) environments + +(F) Miscellaneous + + RunTest.bat a script for running tests under Windows + +Philip Hazel +Email local part: ph10 +Email domain: cam.ac.uk +Last updated: 17 January 2014 diff --git a/tools/pcre/doc/html/index.html b/tools/pcre/doc/html/index.html index 21e11eaf..352c55df 100644 --- a/tools/pcre/doc/html/index.html +++ b/tools/pcre/doc/html/index.html @@ -11,27 +11,29 @@

    Perl-compatible Regular Expressions (PCRE)

    -The HTML documentation for PCRE comprises the following pages: +The HTML documentation for PCRE consists of a number of pages that are listed +below in alphabetical order. If you are new to PCRE, please read the first one +first.

    + + + - - - - + @@ -67,7 +69,7 @@ The HTML documentation for PCRE comprises the following pages: - + @@ -118,13 +120,13 @@ functions. - - - + + + @@ -140,14 +142,17 @@ functions. + + + - - + + diff --git a/tools/pcre/doc/html/pcre-config.html b/tools/pcre/doc/html/pcre-config.html index c2e3ba28..56a80604 100644 --- a/tools/pcre/doc/html/pcre-config.html +++ b/tools/pcre/doc/html/pcre-config.html @@ -23,8 +23,8 @@ man page, in case the conversion went wrong.
    SYNOPSIS

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


    DESCRIPTION

    diff --git a/tools/pcre/doc/html/pcre.html b/tools/pcre/doc/html/pcre.html index edb7479a..c2b29aa8 100644 --- a/tools/pcre/doc/html/pcre.html +++ b/tools/pcre/doc/html/pcre.html @@ -38,9 +38,9 @@ Herczeg.

    Starting with release 8.32 it is possible to compile a third separate PCRE -library, which supports 32-bit character strings (including -UTF-32 strings). The build process allows any set of the 8-, 16- and 32-bit -libraries. The work to make this possible was done by Christian Persch. +library that supports 32-bit character strings (including UTF-32 strings). The +build process allows any combination of the 8-, 16- and 32-bit libraries. The +work to make this possible was done by Christian Persch.

    The three libraries contain identical sets of functions, except that the names @@ -62,7 +62,7 @@ The current implementation of PCRE corresponds approximately with Perl 5.12, including support for UTF-8/16/32 encoded strings and Unicode general category properties. However, UTF-8/16/32 and Unicode support has to be explicitly enabled; it is not the default. The Unicode tables correspond to Unicode -release 6.2.0. +release 6.3.0.

    In addition to the Perl-compatible matching function, PCRE contains an @@ -100,8 +100,11 @@ function makes it possible for a client to discover which features are available. The features themselves are described in the pcrebuild page. Documentation about building PCRE for various operating systems can be -found in the README and NON-AUTOTOOLS_BUILD files in the source -distribution. +found in the +README +and +NON-AUTOTOOLS_BUILD +files in the source distribution.

    The libraries contains a number of undocumented internal functions and data @@ -126,8 +129,11 @@ use sufficiently many resources as to cause your application to lose performance.

    -The best way of guarding against this possibility is to use the +One way of guarding against this possibility is to use the pcre_fullinfo() function to check the compiled pattern's options for UTF. +Alternatively, from release 8.33, you can set the PCRE_NEVER_UTF option at +compile time. This causes an compile time error if a pattern contains a +UTF-setting sequence.

    If your application is one that supports UTF, be aware that validity checking @@ -148,15 +154,18 @@ page. The user documentation for PCRE comprises a number of different sections. 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 section, are concatenated, for ease -of searching. The sections are as follows: +the descriptions of the pcregrep and pcretest programs are in files +called pcregrep.txt and pcretest.txt, respectively. The remaining +sections, except for the pcredemo section (which is a program listing), +are concatenated in pcre.txt, for ease of searching. The sections are as +follows:

       pcre              this document
    +  pcre-config       show PCRE installation configuration information
       pcre16            details of the 16-bit library
       pcre32            details of the 32-bit library
    -  pcre-config       show PCRE installation configuration information
       pcreapi           details of PCRE's native C API
    -  pcrebuild         options for building PCRE
    +  pcrebuild         building PCRE
       pcrecallout       details of the callout feature
       pcrecompat        discussion of Perl compatibility
       pcrecpp           details of the C++ wrapper for the 8-bit library
    @@ -176,8 +185,8 @@ of searching. The sections are as follows:
       pcretest          description of the pcretest testing command
       pcreunicode       discussion of Unicode and UTF-8/16/32 support
     
    -In addition, in the "man" and HTML formats, there is a short page for each -C library function, listing its arguments and results. +In the "man" and HTML formats, there is also a short page for each C library +function, listing its arguments and results.


    AUTHOR

    @@ -195,9 +204,9 @@ two digits 10, at the domain cam.ac.uk.


    REVISION

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

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcre16.html b/tools/pcre/doc/html/pcre16.html index 179b2ada..f00859f0 100644 --- a/tools/pcre/doc/html/pcre16.html +++ b/tools/pcre/doc/html/pcre16.html @@ -42,126 +42,126 @@ man page, in case the conversion went wrong.
    PCRE 16-BIT API BASIC FUNCTIONS

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

    -

    + 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); -

    -

    + int *errorcodeptr, + const char **errptr, int *erroffset, + const unsigned char *tableptr); +
    +
    pcre16_extra *pcre16_study(const pcre16 *code, int options, -const char **errptr); -

    -

    + 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); -

    -

    + 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_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); -

    -

    + 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 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); -

    -

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

    -

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

    -

    + 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 stringcount, int stringnumber, + PCRE_SPTR16 *stringptr); +
    +
    int pcre16_get_substring_list(PCRE_SPTR16 subject, -int *ovector, int stringcount, PCRE_SPTR16 **listptr); -

    -

    + 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); -

    -

    + 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 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); + 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); + PCRE_SPTR16 input, int length, int *byte_order, + int keep_boms);


    THE PCRE 16-BIT LIBRARY

    @@ -259,8 +259,9 @@ 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. +The lengths and starting offsets of subject strings must be specified in 16-bit +data units, and the offsets within subject strings that are returned by the +matching functions are in also 16-bit units rather than bytes.


    NAMED SUBPATTERNS

    @@ -374,9 +375,9 @@ Cambridge CB2 3QH, England.


    REVISION

    -Last updated: 08 November 2012 +Last updated: 12 May 2013
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2013 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcre32.html b/tools/pcre/doc/html/pcre32.html new file mode 100644 index 00000000..f96876e7 --- /dev/null +++ b/tools/pcre/doc/html/pcre32.html @@ -0,0 +1,382 @@ + + +pcre32 specification + + +

    pcre32 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 32-BIT API BASIC FUNCTIONS
    +

    +pcre32 *pcre32_compile(PCRE_SPTR32 pattern, int options, + const char **errptr, int *erroffset, + const unsigned char *tableptr); +
    +
    +pcre32 *pcre32_compile2(PCRE_SPTR32 pattern, int options, + int *errorcodeptr, + const unsigned char *tableptr); +
    +
    +pcre32_extra *pcre32_study(const pcre32 *code, int options, + const char **errptr); +
    +
    +void pcre32_free_study(pcre32_extra *extra); +
    +
    +int pcre32_exec(const pcre32 *code, const pcre32_extra *extra, + PCRE_SPTR32 subject, int length, int startoffset, + int options, int *ovector, int ovecsize); +
    +
    +int pcre32_dfa_exec(const pcre32 *code, const pcre32_extra *extra, + PCRE_SPTR32 subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + int *workspace, int wscount); +

    +
    PCRE 32-BIT API STRING EXTRACTION FUNCTIONS
    +

    +int pcre32_copy_named_substring(const pcre32 *code, + PCRE_SPTR32 subject, int *ovector, + int stringcount, PCRE_SPTR32 stringname, + PCRE_UCHAR32 *buffer, int buffersize); +
    +
    +int pcre32_copy_substring(PCRE_SPTR32 subject, int *ovector, + int stringcount, int stringnumber, PCRE_UCHAR32 *buffer, + int buffersize); +
    +
    +int pcre32_get_named_substring(const pcre32 *code, + PCRE_SPTR32 subject, int *ovector, + int stringcount, PCRE_SPTR32 stringname, + PCRE_SPTR32 *stringptr); +
    +
    +int pcre32_get_stringnumber(const pcre32 *code, + PCRE_SPTR32 name); +
    +
    +int pcre32_get_stringtable_entries(const pcre32 *code, + PCRE_SPTR32 name, PCRE_UCHAR32 **first, PCRE_UCHAR32 **last); +
    +
    +int pcre32_get_substring(PCRE_SPTR32 subject, int *ovector, + int stringcount, int stringnumber, + PCRE_SPTR32 *stringptr); +
    +
    +int pcre32_get_substring_list(PCRE_SPTR32 subject, + int *ovector, int stringcount, PCRE_SPTR32 **listptr); +
    +
    +void pcre32_free_substring(PCRE_SPTR32 stringptr); +
    +
    +void pcre32_free_substring_list(PCRE_SPTR32 *stringptr); +

    +
    PCRE 32-BIT API AUXILIARY FUNCTIONS
    +

    +pcre32_jit_stack *pcre32_jit_stack_alloc(int startsize, int maxsize); +
    +
    +void pcre32_jit_stack_free(pcre32_jit_stack *stack); +
    +
    +void pcre32_assign_jit_stack(pcre32_extra *extra, + pcre32_jit_callback callback, void *data); +
    +
    +const unsigned char *pcre32_maketables(void); +
    +
    +int pcre32_fullinfo(const pcre32 *code, const pcre32_extra *extra, + int what, void *where); +
    +
    +int pcre32_refcount(pcre32 *code, int adjust); +
    +
    +int pcre32_config(int what, void *where); +
    +
    +const char *pcre32_version(void); +
    +
    +int pcre32_pattern_to_host_byte_order(pcre32 *code, + pcre32_extra *extra, const unsigned char *tables); +

    +
    PCRE 32-BIT API INDIRECTED FUNCTIONS
    +

    +void *(*pcre32_malloc)(size_t); +
    +
    +void (*pcre32_free)(void *); +
    +
    +void *(*pcre32_stack_malloc)(size_t); +
    +
    +void (*pcre32_stack_free)(void *); +
    +
    +int (*pcre32_callout)(pcre32_callout_block *); +

    +
    PCRE 32-BIT API 32-BIT-ONLY FUNCTION
    +

    +int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *output, + PCRE_SPTR32 input, int length, int *byte_order, + int keep_boms); +

    +
    THE PCRE 32-BIT LIBRARY
    +

    +Starting with release 8.32, it is possible to compile a PCRE library that +supports 32-bit character strings, including UTF-32 strings, as well as or +instead of the original 8-bit library. This work was done by Christian Persch, +based on the work done by Zoltan Herczeg for the 16-bit library. All three +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 and 32-bit libraries. This page +describes what is different when you use the 32-bit library. +

    +

    +WARNING: A single application can be linked with all or any of the three +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 pcre32_compile(), you must do so +with pcre32_study(), not pcre_study(), and you must free the +study data with pcre32_free_study(). +

    +
    THE HEADER FILE
    +

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

    +
    THE LIBRARY NAME
    +

    +In Unix-like systems, the 32-bit library is called libpcre32, and can +normally be accesss by adding -lpcre32 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 32-bit library, strings are passed as +vectors of unsigned 32-bit quantities. The macro PCRE_UCHAR32 specifies an +appropriate data type, and PCRE_SPTR32 is defined as "const PCRE_UCHAR32 *". In +very many environments, "unsigned int" is a 32-bit data type. When PCRE is +built, it defines PCRE_UCHAR32 as "unsigned int", but checks that it really is +a 32-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 32-bit patterns +and JIT stacks are pcre32 and pcre32_jit_stack respectively. The +type of the user-accessible structure that is returned by pcre32_study() +is pcre32_extra, and the type of the structure that is used for passing +data to a callout function is pcre32_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 32-bit instead of +8-bit types. +

    +
    32-BIT FUNCTIONS
    +

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

    +

    +The input and output arguments of +pcre32_utf32_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 32-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 32-bit units placed into the output +buffer, including the zero terminator if the string was zero-terminated. +

    +
    SUBJECT STRING OFFSETS
    +

    +The lengths and starting offsets of subject strings must be specified in 32-bit +data units, and the offsets within subject strings that are returned by the +matching functions are in also 32-bit units rather than bytes. +

    +
    NAMED SUBPATTERNS
    +

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

    +
    OPTION NAMES
    +

    +There are two new general option names, PCRE_UTF32 and PCRE_NO_UTF32_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-32 strings +in the +pcreunicode +page. +

    +

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

    +
    CHARACTER CODES
    +

    +In 32-bit mode, when PCRE_UTF32 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 0x7fffffff 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-32 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 ill-formed in UTF-32. +

    +

    +A UTF-32 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 +pcre32_utf32_to_host_byte_order() is provided to help with this (see +above). +

    +
    ERROR NAMES
    +

    +The error PCRE_ERROR_BADUTF32 corresponds to its 8-bit counterpart. +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 +pcre32_exec(). +

    +

    +There are new error codes whose names begin with PCRE_UTF32_ERR for invalid +UTF-32 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-32 errors are: +

    +  PCRE_UTF32_ERR1  Surrogate character (range from 0xd800 to 0xdfff)
    +  PCRE_UTF32_ERR2  Non-character
    +  PCRE_UTF32_ERR3  Character > 0x10ffff
    +
    +

    +
    ERROR TEXTS
    +

    +If there is an error while compiling a pattern, the error text that is passed +back by pcre32_compile() or pcre32_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 32-bit vectors. +

    +
    TESTING
    +

    +The pcretest program continues to operate with 8-bit input and output +files, but it can be used for testing the 32-bit library. If it is run with the +command line option -32, patterns and subject strings are converted from +8-bit to 32-bit before being passed to PCRE, and the 32-bit library functions +are used instead of the 8-bit ones. Returned 32-bit strings are converted to +8-bit for output. If both the 8-bit and the 16-bit libraries were not compiled, +pcretest defaults to 32-bit and the -32 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, +16-bit and 32-bit libraries has been built, and runs the tests appropriately. +

    +
    NOT SUPPORTED IN 32-BIT MODE
    +

    +Not all the features of the 8-bit library are available with the 32-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: 12 May 2013 +
    +Copyright © 1997-2013 University of Cambridge. +
    +

    +Return to the PCRE index page. +

    diff --git a/tools/pcre/doc/html/pcre_assign_jit_stack.html b/tools/pcre/doc/html/pcre_assign_jit_stack.html index d77d4e1c..b2eef704 100644 --- a/tools/pcre/doc/html/pcre_assign_jit_stack.html +++ b/tools/pcre/doc/html/pcre_assign_jit_stack.html @@ -20,15 +20,15 @@ SYNOPSIS

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

    -

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

    -

    + pcre16_jit_callback callback, void *data); +
    +
    void pcre32_assign_jit_stack(pcre32_extra *extra, -pcre32_jit_callback callback, void *data); + pcre32_jit_callback callback, void *data);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_compile.html b/tools/pcre/doc/html/pcre_compile.html index 01214751..95b4bec6 100644 --- a/tools/pcre/doc/html/pcre_compile.html +++ b/tools/pcre/doc/html/pcre_compile.html @@ -20,18 +20,18 @@ SYNOPSIS

    pcre *pcre_compile(const char *pattern, int options, -const char **errptr, int *erroffset, -const unsigned char *tableptr); -

    -

    + 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); -

    -

    + const char **errptr, int *erroffset, + const unsigned char *tableptr); +
    +
    pcre32 *pcre32_compile(PCRE_SPTR32 pattern, int options, -const char **errptr, int *erroffset, -const unsigned char *tableptr); + const char **errptr, int *erroffset, + const unsigned char *tableptr);


    DESCRIPTION @@ -65,6 +65,7 @@ The option bits are: PCRE_FIRSTLINE Force matching to be before newline PCRE_JAVASCRIPT_COMPAT JavaScript compatibility PCRE_MULTILINE ^ and $ match newlines within data + PCRE_NEVER_UTF Lock out UTF, e.g. via (*UTF) PCRE_NEWLINE_ANY Recognize any Unicode newline sequence PCRE_NEWLINE_ANYCRLF Recognize CR, LF, and CRLF as newline sequences @@ -73,6 +74,8 @@ The option bits are: PCRE_NEWLINE_LF Set LF as the newline sequence PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren- theses (named ones available) + PCRE_NO_AUTO_POSSESS Disable auto-possessification + PCRE_NO_START_OPTIMIZE Disable match-time start optimizations PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16 validity (only relevant if PCRE_UTF16 is set) diff --git a/tools/pcre/doc/html/pcre_compile2.html b/tools/pcre/doc/html/pcre_compile2.html index 7d76bd9c..9cd56a23 100644 --- a/tools/pcre/doc/html/pcre_compile2.html +++ b/tools/pcre/doc/html/pcre_compile2.html @@ -20,21 +20,21 @@ SYNOPSIS

    pcre *pcre_compile2(const char *pattern, int options, -int *errorcodeptr, -const char **errptr, int *erroffset, -const unsigned char *tableptr); -

    -

    + int *errorcodeptr, + 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); -

    -

    + int *errorcodeptr, + const char **errptr, int *erroffset, + const unsigned char *tableptr); +
    +
    pcre32 *pcre32_compile2(PCRE_SPTR32 pattern, int options, -int *errorcodeptr, -const char **errptr, int *erroffset, -const unsigned char *tableptr); +" int *errorcodeptr,£ + const char **errptr, int *erroffset, + const unsigned char *tableptr);


    DESCRIPTION @@ -69,6 +69,7 @@ The option bits are: PCRE_FIRSTLINE Force matching to be before newline PCRE_JAVASCRIPT_COMPAT JavaScript compatibility PCRE_MULTILINE ^ and $ match newlines within data + PCRE_NEVER_UTF Lock out UTF, e.g. via (*UTF) PCRE_NEWLINE_ANY Recognize any Unicode newline sequence PCRE_NEWLINE_ANYCRLF Recognize CR, LF, and CRLF as newline sequences @@ -77,6 +78,8 @@ The option bits are: PCRE_NEWLINE_LF Set LF as the newline sequence PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren- theses (named ones available) + PCRE_NO_AUTO_POSSESS Disable auto-possessification + PCRE_NO_START_OPTIMIZE Disable match-time start optimizations PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16 validity (only relevant if PCRE_UTF16 is set) diff --git a/tools/pcre/doc/html/pcre_config.html b/tools/pcre/doc/html/pcre_config.html index fc10d183..bcdcdded 100644 --- a/tools/pcre/doc/html/pcre_config.html +++ b/tools/pcre/doc/html/pcre_config.html @@ -48,6 +48,7 @@ point to an unsigned long integer. The available codes are: 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_PARENS_LIMIT Parentheses nesting limit PCRE_CONFIG_MATCH_LIMIT Internal resource limit PCRE_CONFIG_MATCH_LIMIT_RECURSION Internal recursion depth limit diff --git a/tools/pcre/doc/html/pcre_copy_named_substring.html b/tools/pcre/doc/html/pcre_copy_named_substring.html index ae4f6905..77b48043 100644 --- a/tools/pcre/doc/html/pcre_copy_named_substring.html +++ b/tools/pcre/doc/html/pcre_copy_named_substring.html @@ -20,21 +20,21 @@ SYNOPSIS

    int pcre_copy_named_substring(const pcre *code, -const char *subject, int *ovector, -int stringcount, const char *stringname, -char *buffer, int buffersize); -

    -

    + const char *subject, int *ovector, + 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); -

    -

    + PCRE_SPTR16 subject, int *ovector, + int stringcount, PCRE_SPTR16 stringname, + PCRE_UCHAR16 *buffer, int buffersize); +
    +
    int pcre32_copy_named_substring(const pcre32 *code, -PCRE_SPTR32 subject, int *ovector, -int stringcount, PCRE_SPTR32 stringname, -PCRE_UCHAR32 *buffer, int buffersize); + PCRE_SPTR32 subject, int *ovector, + int stringcount, PCRE_SPTR32 stringname, + PCRE_UCHAR32 *buffer, int buffersize);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_copy_substring.html b/tools/pcre/doc/html/pcre_copy_substring.html index 12bfb636..ecaebe85 100644 --- a/tools/pcre/doc/html/pcre_copy_substring.html +++ b/tools/pcre/doc/html/pcre_copy_substring.html @@ -20,18 +20,18 @@ SYNOPSIS

    int pcre_copy_substring(const char *subject, int *ovector, -int stringcount, int stringnumber, char *buffer, -int buffersize); -

    -

    + 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); -

    -

    + int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, + int buffersize); +
    +
    int pcre32_copy_substring(PCRE_SPTR32 subject, int *ovector, -int stringcount, int stringnumber, PCRE_UCHAR32 *buffer, -int buffersize); + int stringcount, int stringnumber, PCRE_UCHAR32 *buffer, + int buffersize);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_dfa_exec.html b/tools/pcre/doc/html/pcre_dfa_exec.html index 663e1d0f..5fff6a7e 100644 --- a/tools/pcre/doc/html/pcre_dfa_exec.html +++ b/tools/pcre/doc/html/pcre_dfa_exec.html @@ -20,21 +20,21 @@ SYNOPSIS

    int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, -const char *subject, int length, int startoffset, -int options, int *ovector, int ovecsize, -int *workspace, int wscount); -

    -

    + const char *subject, int length, int startoffset, + 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); -

    -

    + PCRE_SPTR16 subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + int *workspace, int wscount); +
    +
    int pcre32_dfa_exec(const pcre32 *code, const pcre32_extra *extra, -PCRE_SPTR32 subject, int length, int startoffset, -int options, int *ovector, int ovecsize, -int *workspace, int wscount); + PCRE_SPTR32 subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + int *workspace, int wscount);


    DESCRIPTION @@ -50,16 +50,17 @@ are: extra Points to an associated pcre[16|32]_extra structure, or is NULL subject Points to the subject string - length Length of the subject string, in bytes - startoffset Offset in bytes in the subject at which to - start matching + length Length of the subject string + startoffset Offset in the subject at which to start matching options Option bits ovector Points to a vector of ints for result offsets ovecsize Number of elements in the vector workspace Points to a vector of ints used as working space wscount Number of elements in the vector -The options are: +The units for length and startoffset are bytes for +pcre_exec(), 16-bit data items for pcre16_exec(), and 32-bit items +for pcre32_exec(). The options are:
       PCRE_ANCHORED          Match only at the first position
       PCRE_BSR_ANYCRLF       \R matches only CR, LF, or CRLF
    diff --git a/tools/pcre/doc/html/pcre_exec.html b/tools/pcre/doc/html/pcre_exec.html
    index e4ddf9a8..18e1a13f 100644
    --- a/tools/pcre/doc/html/pcre_exec.html
    +++ b/tools/pcre/doc/html/pcre_exec.html
    @@ -20,18 +20,18 @@ SYNOPSIS
     

    int pcre_exec(const pcre *code, const pcre_extra *extra, -const char *subject, int length, int startoffset, -int options, int *ovector, int ovecsize); -

    -

    + 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); -

    -

    + PCRE_SPTR16 subject, int length, int startoffset, + int options, int *ovector, int ovecsize); +
    +
    int pcre32_exec(const pcre32 *code, const pcre32_extra *extra, -PCRE_SPTR32 subject, int length, int startoffset, -int options, int *ovector, int ovecsize); + PCRE_SPTR32 subject, int length, int startoffset, + int options, int *ovector, int ovecsize);


    DESCRIPTION @@ -45,14 +45,15 @@ offsets to captured substrings. Its arguments are: extra Points to an associated pcre[16|32]_extra structure, or is NULL subject Points to the subject string - length Length of the subject string, in bytes - startoffset Offset in bytes in the subject at which to - start matching + length Length of the subject string + startoffset Offset in the subject at which to start matching options Option bits ovector Points to a vector of ints for result offsets ovecsize Number of elements in the vector (a multiple of 3)
    -The options are: +The units for length and startoffset are bytes for +pcre_exec(), 16-bit data items for pcre16_exec(), and 32-bit items +for pcre32_exec(). The options are:
       PCRE_ANCHORED          Match only at the first position
       PCRE_BSR_ANYCRLF       \R matches only CR, LF, or CRLF
    diff --git a/tools/pcre/doc/html/pcre_fullinfo.html b/tools/pcre/doc/html/pcre_fullinfo.html
    index d353432b..b88fc115 100644
    --- a/tools/pcre/doc/html/pcre_fullinfo.html
    +++ b/tools/pcre/doc/html/pcre_fullinfo.html
    @@ -20,15 +20,15 @@ SYNOPSIS
     

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

    -

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

    -

    + int what, void *where); +
    +
    int pcre32_fullinfo(const pcre32 *code, const pcre32_extra *extra, -int what, void *where); + int what, void *where);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_get_named_substring.html b/tools/pcre/doc/html/pcre_get_named_substring.html index 6150ad71..72924d9b 100644 --- a/tools/pcre/doc/html/pcre_get_named_substring.html +++ b/tools/pcre/doc/html/pcre_get_named_substring.html @@ -20,21 +20,21 @@ SYNOPSIS

    int pcre_get_named_substring(const pcre *code, -const char *subject, int *ovector, -int stringcount, const char *stringname, -const char **stringptr); -

    -

    + const char *subject, int *ovector, + 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); -

    -

    + PCRE_SPTR16 subject, int *ovector, + int stringcount, PCRE_SPTR16 stringname, + PCRE_SPTR16 *stringptr); +
    +
    int pcre32_get_named_substring(const pcre32 *code, -PCRE_SPTR32 subject, int *ovector, -int stringcount, PCRE_SPTR32 stringname, -PCRE_SPTR32 *stringptr); + PCRE_SPTR32 subject, int *ovector, + int stringcount, PCRE_SPTR32 stringname, + PCRE_SPTR32 *stringptr);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_get_stringnumber.html b/tools/pcre/doc/html/pcre_get_stringnumber.html index 08967de3..7324d782 100644 --- a/tools/pcre/doc/html/pcre_get_stringnumber.html +++ b/tools/pcre/doc/html/pcre_get_stringnumber.html @@ -20,15 +20,15 @@ SYNOPSIS

    int pcre_get_stringnumber(const pcre *code, -const char *name); -

    -

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

    -

    + PCRE_SPTR16 name); +
    +
    int pcre32_get_stringnumber(const pcre32 *code, -PCRE_SPTR32 name); + PCRE_SPTR32 name);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_get_stringtable_entries.html b/tools/pcre/doc/html/pcre_get_stringtable_entries.html index 38f9c0c9..79906798 100644 --- a/tools/pcre/doc/html/pcre_get_stringtable_entries.html +++ b/tools/pcre/doc/html/pcre_get_stringtable_entries.html @@ -20,15 +20,15 @@ SYNOPSIS

    int pcre_get_stringtable_entries(const pcre *code, -const char *name, char **first, char **last); -

    -

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

    -

    + PCRE_SPTR16 name, PCRE_UCHAR16 **first, PCRE_UCHAR16 **last); +
    +
    int pcre32_get_stringtable_entries(const pcre32 *code, -PCRE_SPTR32 name, PCRE_UCHAR32 **first, PCRE_UCHAR32 **last); + PCRE_SPTR32 name, PCRE_UCHAR32 **first, PCRE_UCHAR32 **last);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_get_substring.html b/tools/pcre/doc/html/pcre_get_substring.html index 2a5a610f..1a8e4f5a 100644 --- a/tools/pcre/doc/html/pcre_get_substring.html +++ b/tools/pcre/doc/html/pcre_get_substring.html @@ -20,18 +20,18 @@ SYNOPSIS

    int pcre_get_substring(const char *subject, int *ovector, -int stringcount, int stringnumber, -const char **stringptr); -

    -

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

    -

    + int stringcount, int stringnumber, + PCRE_SPTR16 *stringptr); +
    +
    int pcre32_get_substring(PCRE_SPTR32 subject, int *ovector, -int stringcount, int stringnumber, -PCRE_SPTR32 *stringptr); + int stringcount, int stringnumber, + PCRE_SPTR32 *stringptr);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_get_substring_list.html b/tools/pcre/doc/html/pcre_get_substring_list.html index 85edef4b..7e8c6bc8 100644 --- a/tools/pcre/doc/html/pcre_get_substring_list.html +++ b/tools/pcre/doc/html/pcre_get_substring_list.html @@ -20,15 +20,15 @@ SYNOPSIS

    int pcre_get_substring_list(const char *subject, -int *ovector, int stringcount, const char ***listptr); -

    -

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

    -

    + int *ovector, int stringcount, PCRE_SPTR16 **listptr); +
    +
    int pcre32_get_substring_list(PCRE_SPTR32 subject, -int *ovector, int stringcount, PCRE_SPTR32 **listptr); + int *ovector, int stringcount, PCRE_SPTR32 **listptr);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_jit_exec.html b/tools/pcre/doc/html/pcre_jit_exec.html index 0c63503a..4ebb0cbc 100644 --- a/tools/pcre/doc/html/pcre_jit_exec.html +++ b/tools/pcre/doc/html/pcre_jit_exec.html @@ -20,21 +20,21 @@ SYNOPSIS

    int pcre_jit_exec(const pcre *code, const pcre_extra *extra, -const char *subject, int length, int startoffset, -int options, int *ovector, int ovecsize, -pcre_jit_stack *jstack); -

    -

    + const char *subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + pcre_jit_stack *jstack); +
    +
    int pcre16_jit_exec(const pcre16 *code, const pcre16_extra *extra, -PCRE_SPTR16 subject, int length, int startoffset, -int options, int *ovector, int ovecsize, -pcre_jit_stack *jstack); -

    -

    + PCRE_SPTR16 subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + pcre_jit_stack *jstack); +
    +
    int pcre32_jit_exec(const pcre32 *code, const pcre32_extra *extra, -PCRE_SPTR32 subject, int length, int startoffset, -int options, int *ovector, int ovecsize, -pcre_jit_stack *jstack); + PCRE_SPTR32 subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + pcre_jit_stack *jstack);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_jit_stack_alloc.html b/tools/pcre/doc/html/pcre_jit_stack_alloc.html index 4153ee59..23ba4507 100644 --- a/tools/pcre/doc/html/pcre_jit_stack_alloc.html +++ b/tools/pcre/doc/html/pcre_jit_stack_alloc.html @@ -20,15 +20,15 @@ SYNOPSIS

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

    -

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

    -

    + int maxsize); +
    +
    pcre32_jit_stack *pcre32_jit_stack_alloc(int startsize, -int maxsize); + int maxsize);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_pattern_to_host_byte_order.html b/tools/pcre/doc/html/pcre_pattern_to_host_byte_order.html index 68d6f5a1..1b1c8037 100644 --- a/tools/pcre/doc/html/pcre_pattern_to_host_byte_order.html +++ b/tools/pcre/doc/html/pcre_pattern_to_host_byte_order.html @@ -20,15 +20,15 @@ SYNOPSIS

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

    -

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

    -

    + pcre16_extra *extra, const unsigned char *tables); +
    +
    int pcre32_pattern_to_host_byte_order(pcre32 *code, -pcre32_extra *extra, const unsigned char *tables); + pcre32_extra *extra, const unsigned char *tables);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_study.html b/tools/pcre/doc/html/pcre_study.html index 2baf54c4..af82f114 100644 --- a/tools/pcre/doc/html/pcre_study.html +++ b/tools/pcre/doc/html/pcre_study.html @@ -20,15 +20,15 @@ SYNOPSIS

    pcre_extra *pcre_study(const pcre *code, int options, -const char **errptr); -

    -

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

    -

    + const char **errptr); +
    +
    pcre32_extra *pcre32_study(const pcre32 *code, int options, -const char **errptr); + const char **errptr);


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_utf16_to_host_byte_order.html b/tools/pcre/doc/html/pcre_utf16_to_host_byte_order.html index 164e2365..18e7788f 100644 --- a/tools/pcre/doc/html/pcre_utf16_to_host_byte_order.html +++ b/tools/pcre/doc/html/pcre_utf16_to_host_byte_order.html @@ -20,8 +20,8 @@ SYNOPSIS

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


    DESCRIPTION diff --git a/tools/pcre/doc/html/pcre_utf32_to_host_byte_order.html b/tools/pcre/doc/html/pcre_utf32_to_host_byte_order.html new file mode 100644 index 00000000..772ae40c --- /dev/null +++ b/tools/pcre/doc/html/pcre_utf32_to_host_byte_order.html @@ -0,0 +1,57 @@ + + +pcre_utf32_to_host_byte_order specification + + +

    pcre_utf32_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 pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *output, + PCRE_SPTR32 input, int length, int *host_byte_order, + int keep_boms); +

    +
    +DESCRIPTION +
    +

    +This function, which exists only in the 32-bit library, converts a UTF-32 +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 32-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 32-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 --git a/tools/pcre/doc/html/pcreapi.html b/tools/pcre/doc/html/pcreapi.html index 59398df3..b401ecc7 100644 --- a/tools/pcre/doc/html/pcreapi.html +++ b/tools/pcre/doc/html/pcreapi.html @@ -46,126 +46,129 @@ man page, in case the conversion went wrong.
    PCRE NATIVE API BASIC FUNCTIONS

    pcre *pcre_compile(const char *pattern, int options, -const char **errptr, int *erroffset, -const unsigned char *tableptr); -

    -

    + const char **errptr, int *erroffset, + const unsigned char *tableptr); +
    +
    pcre *pcre_compile2(const char *pattern, int options, -int *errorcodeptr, -const char **errptr, int *erroffset, -const unsigned char *tableptr); -

    -

    + int *errorcodeptr, + const char **errptr, int *erroffset, + const unsigned char *tableptr); +
    +
    pcre_extra *pcre_study(const pcre *code, int options, -const char **errptr); -

    -

    + 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); -

    -

    + const char *subject, int length, int startoffset, + int options, int *ovector, int ovecsize); +
    +
    int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, -const char *subject, int length, int startoffset, -int options, int *ovector, int ovecsize, -int *workspace, int wscount); + const char *subject, int length, int startoffset, + 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, -char *buffer, int buffersize); -

    -

    + const char *subject, int *ovector, + int stringcount, const char *stringname, + char *buffer, int buffersize); +
    +
    int pcre_copy_substring(const char *subject, int *ovector, -int stringcount, int stringnumber, char *buffer, -int buffersize); -

    -

    + int stringcount, int stringnumber, char *buffer, + int buffersize); +
    +
    int pcre_get_named_substring(const pcre *code, -const char *subject, int *ovector, -int stringcount, const char *stringname, -const char **stringptr); -

    -

    + const char *subject, int *ovector, + int stringcount, const char *stringname, + const char **stringptr); +
    +
    int pcre_get_stringnumber(const pcre *code, -const char *name); -

    -

    + const char *name); +
    +
    int pcre_get_stringtable_entries(const pcre *code, -const char *name, char **first, char **last); -

    -

    + const char *name, char **first, char **last); +
    +
    int pcre_get_substring(const char *subject, int *ovector, -int stringcount, int stringnumber, -const char **stringptr); -

    -

    + int stringcount, int stringnumber, + const char **stringptr); +
    +
    int pcre_get_substring_list(const char *subject, -int *ovector, int stringcount, const char ***listptr); -

    -

    + int *ovector, int stringcount, const char ***listptr); +
    +
    void pcre_free_substring(const char *stringptr); -

    -

    +
    +
    void pcre_free_substring_list(const char **stringptr);


    PCRE NATIVE API AUXILIARY FUNCTIONS

    int pcre_jit_exec(const pcre *code, const pcre_extra *extra, -const char *subject, int length, int startoffset, -int options, int *ovector, int ovecsize, -pcre_jit_stack *jstack); -

    -

    + const char *subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + pcre_jit_stack *jstack); +
    +
    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); -

    -

    + 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 what, void *where); +
    +
    int pcre_refcount(pcre *code, int adjust); -

    -

    +
    +
    int pcre_config(int what, void *where); -

    -

    +
    +
    const char *pcre_version(void); -

    -

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


    PCRE NATIVE API INDIRECTED FUNCTIONS

    void *(*pcre_malloc)(size_t); -

    -

    +
    +
    void (*pcre_free)(void *); -

    -

    +
    +
    void *(*pcre_stack_malloc)(size_t); -

    -

    +
    +
    void (*pcre_stack_free)(void *); -

    -

    +
    +
    int (*pcre_callout)(pcre_callout_block *); +
    +
    +int (*pcre_stack_guard)(void);


    PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES

    @@ -187,10 +190,10 @@ by UTF16 or UTF32, respectively. This facility is in fact just cosmetic; the

    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, or 32-bit data -quantities and UTF-32 when using the 32-bit library, unless specified -otherwise. More details of the specific differences for the 16-bit and 32-bit -libraries are given in the +16-bit data units and UTF-16 when using the 16-bit library, or 32-bit data +units and UTF-32 when using the 32-bit library, unless specified otherwise. +More details of the specific differences for the 16-bit and 32-bit libraries +are given in the pcre16 and pcre32 @@ -324,6 +327,15 @@ 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. +

    +

    +The global variable pcre_stack_guard initially contains NULL. It can be +set by the caller to a function that is called by PCRE whenever it starts +to compile a parenthesized part of a pattern. When parentheses are nested, PCRE +uses recursive function calls, which use up the system stack. This function is +provided so that applications with restricted stacks can force a compilation +error if the stack runs out. The function should return zero if all is well, or +non-zero to force an error.


    NEWLINES

    @@ -369,7 +381,8 @@ controlled in a similar way, but by separate options. 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. +callout and stack-checking functions pointed to by pcre_callout and +pcre_stack_guard, are shared by all threads.

    The compiled form of a regular expression is not altered during matching, so @@ -483,6 +496,16 @@ interface uses malloc() for output vectors. Further details are given in the pcreposix documentation. +

    +  PCRE_CONFIG_PARENS_LIMIT
    +
    +The output is a long integer that gives the maximum depth of nesting of +parentheses (of any kind) in a pattern. This limit is imposed to cap the amount +of system stack used when a pattern is compiled. It is specified when PCRE is +built; the default is 250. This limit does not take into account the stack that +may already be used by the calling application. For finer control over +compilation stack usage, you can set a pointer to an external checking function +in pcre_stack_guard.
       PCRE_CONFIG_MATCH_LIMIT
     
    @@ -509,12 +532,14 @@ avoiding the use of the stack.
    COMPILING A PATTERN

    pcre *pcre_compile(const char *pattern, int options, -const char **errptr, int *erroffset, -const unsigned char *tableptr); + const char **errptr, int *erroffset, + const unsigned char *tableptr); +
    +
    pcre *pcre_compile2(const char *pattern, int options, -int *errorcodeptr, -const char **errptr, int *erroffset, -const unsigned char *tableptr); + int *errorcodeptr, + const char **errptr, int *erroffset, + const unsigned char *tableptr);

    Either of the functions pcre_compile() or pcre_compile2() can be @@ -558,16 +583,16 @@ 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. 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. +data unit that was being processed when the error was discovered is placed in +the variable pointed to by erroffset, which must not be NULL (if it is, +an immediate error is given). However, for an invalid UTF-8 or UTF-16 string, +the offset is that of the first data unit of the failing character.

    Some errors are not detected until the whole pattern has been scanned; in these cases, the offset passed back is the length of the pattern. Note that the -offset is in bytes, not characters, even in UTF-8 mode. It may sometimes point -into the middle of a UTF-8 character. +offset is in data units, not characters, even in a UTF mode. It may sometimes +point into the middle of a UTF-8 or UTF-16 character.

    If pcre_compile2() is used instead of pcre_compile(), and the @@ -580,8 +605,9 @@ 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. +pattern, and used again by pcre_exec() and pcre_dfa_exec() when the +pattern is matched. For more discussion, see the section on locale support +below.

    This code fragment shows a typical straightforward call to pcre_compile(): @@ -666,12 +692,24 @@ documentation.

       PCRE_EXTENDED
     
    -If this bit is set, white space data characters in the pattern are totally -ignored except when escaped or inside a character class. White space does not -include the VT character (code 11). In addition, 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. +If this bit is set, most white space characters in the pattern are totally +ignored except when escaped or inside a character class. However, white space +is not allowed within sequences such as (?> that introduce various +parenthesized subpatterns, nor within a numerical quantifier such as {1,3}. +However, ignorable white space is permitted between an item and a following +quantifier and between a quantifier and a following + that indicates +possessiveness. +

    +

    +White space did not used to include the VT character (code 11), because Perl +did not treat this character as white space. However, Perl changed at release +5.18, so PCRE followed at release 8.34, and VT is now treated as white space. +

    +

    +PCRE_EXTENDED also causes characters between an unescaped # outside a character +class and the next newline, inclusive, to be ignored. PCRE_EXTENDED is +equivalent to Perl's /x option, and it can be changed within a pattern by a +(?x) option setting.

    Which characters are interpreted as newlines is controlled by the options @@ -741,12 +779,14 @@ 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 the string, or before a -terminating newline (unless PCRE_DOLLAR_ENDONLY is set). This is the same as -Perl. +By default, for the purposes of matching "start of line" and "end of line", +PCRE treats the subject string as consisting of a single line of characters, +even if it actually contains newlines. The "start of line" metacharacter (^) +matches only at the start of the string, and the "end of line" metacharacter +($) matches only at the end of the string, or before a terminating newline +(except when PCRE_DOLLAR_ENDONLY is set). Note, however, that unless +PCRE_DOTALL is set, the "any character" metacharacter (.) does not match at a +newline. This behaviour (for ^, $, and dot) is the same as Perl.

    When PCRE_MULTILINE it is set, the "start of line" and "end of line" constructs @@ -755,6 +795,15 @@ 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 newlines in a subject string, or no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no effect. +

    +  PCRE_NEVER_UTF
    +
    +This option locks out interpretation of the pattern as UTF-8 (or UTF-16 or +UTF-32 in the 16-bit and 32-bit libraries). In particular, it prevents the +creator of the pattern from switching to UTF interpretation by starting the +pattern with (*UTF). This may be useful in applications that process patterns +from external sources. The combination of PCRE_UTF8 and PCRE_NEVER_UTF also +causes an error.
       PCRE_NEWLINE_CR
       PCRE_NEWLINE_LF
    @@ -814,12 +863,23 @@ 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
    +  PCRE_NO_AUTO_POSSESS
    +
    +If this option is set, it disables "auto-possessification". This is an +optimization that, for example, turns a+b into a++b in order to avoid +backtracks into a+ that can never be successful. However, if callouts are in +use, auto-possessification means that some of them are never taken. You can set +this option if you want the matching functions to do a full unoptimized search +and run all the callouts, but it is mainly provided for testing purposes. +
    +  PCRE_NO_START_OPTIMIZE
     
    This is an option that acts at matching time; that is, it is really an option for pcre_exec() or pcre_dfa_exec(). If it is set at compile time, -it is remembered with the compiled pattern and assumed at matching time. For -details see the discussion of PCRE_NO_START_OPTIMIZE +it is remembered with the compiled pattern and assumed at matching time. This +is necessary if you want to use JIT execution, because the JIT compiler needs +to know whether or not this option is set. For details see the discussion of +PCRE_NO_START_OPTIMIZE below.
       PCRE_UCP
    @@ -862,10 +922,10 @@ 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 only. If the same string is being matched
    -many times, the option can be safely set for the second and subsequent
    +undefined. It may cause your program to crash or loop. Note that this option
    +can also be passed to pcre_exec() and pcre_dfa_exec(), to suppress
    +the validity checking of subject strings only. If the same string is being
    +matched many times, the option can be safely set for the second and subsequent
     matchings to improve performance.
     


    COMPILATION ERROR CODES
    @@ -910,7 +970,7 @@ have fallen out of use. To avoid confusion, they have not been re-used. 31 POSIX collating elements are not supported 32 this version of PCRE is compiled without UTF support 33 [this code is not in use] - 34 character value in \x{...} sequence is too large + 34 character value in \x{} or \o{} is too large 35 invalid condition (?(0) 36 \C not allowed in lookbehind assertion 37 PCRE does not support \L, \l, \N{name}, \U, or \u @@ -938,7 +998,7 @@ have fallen out of use. To avoid confusion, they have not been re-used. name/number or by a plain number 58 a numbered reference must not be zero 59 an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) - 60 (*VERB) not recognized + 60 (*VERB) not recognized or malformed 61 number is too big 62 subpattern name expected 63 digit expected after (?+ @@ -958,14 +1018,22 @@ have fallen out of use. To avoid confusion, they have not been re-used. 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) 76 character value in \u.... sequence is too large 77 invalid UTF-32 string (specifically UTF-32) + 78 setting UTF is disabled by the application + 79 non-hex character in \x{} (closing brace missing?) + 80 non-octal character in \o{} (closing brace missing?) + 81 missing opening brace after \o + 82 parentheses are too deeply nested + 83 invalid range in character class + 84 group name must start with a non-digit + 85 parentheses are too deeply nested (stack check)
    The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may be used if the limits were changed when PCRE was built.


    STUDYING A PATTERN

    -pcre_extra *pcre_study(const pcre *code, int options -const char **errptr); +pcre_extra *pcre_study(const pcre *code, int options, + const char **errptr);

    If a compiled pattern is going to be used several times, it is worth spending @@ -1069,26 +1137,37 @@ In 32-bit mode, the bitmap is used for 32-bit values less than 256.)

    These two optimizations apply to both pcre_exec() and pcre_dfa_exec(), and the information is also used by the JIT compiler. -The 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 +The optimizations can be disabled by setting the PCRE_NO_START_OPTIMIZE option. +You might want to do this if your pattern contains callouts or (*MARK) and you +want to make use of these facilities in cases where matching fails. +

    +

    +PCRE_NO_START_OPTIMIZE can be specified at either compile time or execution +time. However, if PCRE_NO_START_OPTIMIZE is passed to pcre_exec(), (that +is, after any JIT compilation has happened) JIT execution is disabled. For JIT +execution to work with PCRE_NO_START_OPTIMIZE, the option must be set at +compile time. +

    +

    +There is a longer discussion of PCRE_NO_START_OPTIMIZE below.


    LOCALE SUPPORT

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

    +

    +The use of locales with Unicode is discouraged. If you are handling characters +with code points greater than 128, you should either use Unicode support, or +use locales, but not try to mix the two.

    PCRE contains an internal set of tables that are used when the final argument @@ -1106,10 +1185,10 @@ 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 treated as letters), -the following code could be used: +to pcre_compile() as often as necessary. For example, to build and use +tables that are appropriate for the French locale (where accented characters +with values greater than 128 are treated as letters), the following code could +be used:

       setlocale(LC_CTYPE, "fr_FR");
       tables = pcre_maketables();
    @@ -1127,21 +1206,25 @@ 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() -and normally also by pcre_exec(). Thus, by default, for any single +and also by pcre_exec() and pcre_dfa_exec(). Thus, for any single pattern, compilation, studying and matching all happen in the same locale, but -different patterns can be compiled in different locales. +different patterns can be processed in different locales.

    It is possible to pass a table pointer or NULL (indicating the use of the -internal tables) to pcre_exec(). Although not intended for this purpose, -this facility could be used to match a pattern in a different locale from the -one in which it was compiled. Passing table pointers at run time is discussed -below in the section on matching a pattern. +internal tables) to pcre_exec() or pcre_dfa_exec() (see the +discussion below in the section on matching a pattern). This facility is +provided for use with pre-compiled patterns that have been saved and reloaded. +Character tables are not saved with patterns, so if a non-standard table was +used at compile time, it must be provided again when the reloaded pattern is +matched. Attempting to use this facility to match a pattern in a different +locale from the one in which it was compiled is likely to lead to anomalous +(usually incorrect) results.


    INFORMATION ABOUT A PATTERN

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

    The pcre_fullinfo() function returns information about a compiled @@ -1162,6 +1245,7 @@ the following negative numbers: PCRE_ERROR_BADENDIANNESS the pattern was compiled with different endianness PCRE_ERROR_BADOPTION the value of what was invalid + PCRE_ERROR_UNSET the requested field is not set

    The "magic number" is placed at the start of each compiled pattern as an simple check against passing an arbitrary memory pointer. The endianness error can @@ -1199,12 +1283,15 @@ information call is provided for internal use by the pcre_study() function. External callers can cause PCRE to use its internal tables by passing a NULL table pointer.
    -  PCRE_INFO_FIRSTBYTE
    +  PCRE_INFO_FIRSTBYTE (deprecated)
     
    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. +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. Negative values are used for special cases. However, this means that +when the 32-bit library is in non-UTF-32 mode, the full 32-bit range of +characters cannot be returned. For this reason, this value is deprecated; use +PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER instead.

    If there is a fixed first value, for example, the letter "c" from a pattern @@ -1227,12 +1314,43 @@ starts with "^", or -1 is returned, indicating that the pattern matches only at the start of a subject string or after any newline within the string. Otherwise -2 is returned. For anchored patterns, -2 is returned. +

    +  PCRE_INFO_FIRSTCHARACTER
    +
    +Return the value of the first data unit (non-UTF character) of any matched +string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS returns 1; +otherwise return 0. The fourth argument should point to an uint_t +variable.

    -Since for the 32-bit library using the non-UTF-32 mode, this function is unable -to return the full 32-bit range of the character, this value is deprecated; -instead the PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER values -should be used. +In the 8-bit library, the value is always less than 256. In the 16-bit library +the value can be up to 0xffff. In the 32-bit library in UTF-32 mode the value +can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode. +

    +  PCRE_INFO_FIRSTCHARACTERFLAGS
    +
    +Return information about the first data unit of any matched string, for a +non-anchored pattern. The fourth argument should point to an int +variable. +

    +

    +If there is a fixed first value, for example, the letter "c" from a pattern +such as (cat|cow|coyote), 1 is returned, and the character value can be +retrieved using PCRE_INFO_FIRSTCHARACTER. If there is no fixed first value, and +if either +
    +
    +(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch +starts with "^", or +
    +
    +(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set +(if it were set, the pattern would be anchored), +
    +
    +2 is returned, indicating that the pattern matches only at the start of a +subject string or after any newline within the string. Otherwise 0 is +returned. For anchored patterns, 0 is returned.

       PCRE_INFO_FIRSTTABLE
     
    @@ -1281,26 +1399,43 @@ is -1.

    Since for the 32-bit library using the non-UTF-32 mode, this function is unable -to return the full 32-bit range of the character, this value is deprecated; +to return the full 32-bit range of characters, this value is deprecated; instead the PCRE_INFO_REQUIREDCHARFLAGS and PCRE_INFO_REQUIREDCHAR values should be used. +

    +  PCRE_INFO_MATCH_EMPTY
    +
    +Return 1 if the pattern can match an empty string, otherwise 0. The fourth +argument should point to an int variable. +
    +  PCRE_INFO_MATCHLIMIT
    +
    +If the pattern set a match limit by including an item of the form +(*LIMIT_MATCH=nnnn) at the start, the value is returned. The fourth argument +should point to an unsigned 32-bit integer. If no such value has been set, the +call to pcre_fullinfo() returns the error PCRE_ERROR_UNSET.
       PCRE_INFO_MAXLOOKBEHIND
     
    -Return the number of characters (NB not bytes) in the longest 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. +Return the number of characters (NB not data units) in the longest lookbehind +assertion in the pattern. This information is useful when doing multi-segment +matching using the partial matching facilities. Note that the simple assertions +\b and \B require a one-character lookbehind. \A also registers a +one-character lookbehind, though it does not actually inspect the previous +character. This is to ensure that at least one character from the old segment +is retained when a new segment is processed. Otherwise, if there are no +lookbehinds in the pattern, \A might match incorrectly at the start of a new +segment.
       PCRE_INFO_MINLENGTH
     
    If the pattern was studied and a minimum length for matching subject strings was computed, its value is returned. Otherwise the returned value is -1. The -value is a number of characters, which in UTF-8 mode may be different from the -number of bytes. The fourth argument should 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. +value is a number of characters, which in UTF mode may be different from the +number of data units. The fourth argument should point to an int +variable. A non-negative value is a lower bound to the length of any matching +string. There may not be any strings of that length that do actually match, but +every string that does match is at least that long.
       PCRE_INFO_NAMECOUNT
       PCRE_INFO_NAMEENTRYSIZE
    @@ -1324,22 +1459,24 @@ length of the longest name. PCRE_INFO_NAMETABLE returns 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 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.
    -In the 32-bit library, the pointer points to 32-bit data units, the first of
    -which contains the parenthesis number. The rest
    -of the entry is the corresponding name, zero terminated.
    +16-bit data units, the first of which contains the parenthesis number. In the
    +32-bit library, the pointer points to 32-bit data units, the first of which
    +contains the parenthesis number. The rest of the entry is the corresponding
    +name, zero terminated.
     

    -The names are in alphabetical order. Duplicate names may appear if (?| is used -to create multiple groups with the same number, as described in the +The names are in alphabetical order. If (?| is used to create multiple groups +with the same number, as described in the section on duplicate subpattern numbers in the pcrepattern -page. Duplicate names for subpatterns with different numbers are permitted only -if PCRE_DUPNAMES is set. In all cases of duplicate names, they appear in the -table in the order in which they were found in the pattern. In the absence of -(?| this is the order of increasing number; when (?| is used this is not -necessarily the case because later subpatterns may have lower numbers. +page, the groups may be given the same name, but there is only one entry in the +table. Different names for groups of the same number are not permitted. +Duplicate names for subpatterns with different numbers are permitted, +but only if PCRE_DUPNAMES is set. They appear in the table in the order in +which they were found in the pattern. In the absence of (?| this is the order +of increasing number; when (?| is used this is not necessarily the case because +later subpatterns may have lower numbers.

    As a simple example of the name/number table, consider the following pattern @@ -1391,10 +1528,17 @@ alternatives begin with one of the following:

    For such patterns, the PCRE_ANCHORED bit is set in the options returned by pcre_fullinfo(). +
    +  PCRE_INFO_RECURSIONLIMIT
    +
    +If the pattern set a recursion limit by including an item of the form +(*LIMIT_RECURSION=nnnn) at the start, the value is returned. The fourth +argument should point to an unsigned 32-bit integer. If no such value has been +set, the call to pcre_fullinfo() returns the error PCRE_ERROR_UNSET.
       PCRE_INFO_SIZE
     
    -Return the size of the compiled pattern in bytes (for both libraries). The +Return the size of the compiled pattern in bytes (for all three libraries). The fourth argument should point to a size_t variable. This value does not include the size of the pcre structure that is returned by pcre_compile(). The value that is passed as the argument to @@ -1405,70 +1549,17 @@ does not alter the value returned by this option.
       PCRE_INFO_STUDYSIZE
     
    -Return the size in bytes of the data block pointed to by the study_data -field in a pcre_extra block. If pcre_extra is NULL, or there is no -study data, zero is returned. The fourth argument should point to a -size_t variable. The study_data field is set by pcre_study() -to record information that will speed up matching (see the section entitled +Return the size in bytes (for all three libraries) of the data block pointed to +by the study_data field in a pcre_extra block. If pcre_extra +is NULL, or there is no study data, zero is returned. The fourth 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 private, but its length is made available via this option so that it can be saved and restored (see the pcreprecompile documentation for details). -
    -  PCRE_INFO_FIRSTCHARACTERFLAGS
    -
    -Return information about the first data unit of any matched string, for a -non-anchored pattern. The fourth argument should point to an int -variable. -

    -

    -If there is a fixed first value, for example, the letter "c" from a pattern -such as (cat|cow|coyote), 1 is returned, and the character value can be -retrieved using PCRE_INFO_FIRSTCHARACTER. -

    -

    -If there is no fixed first value, and if either -
    -
    -(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch -starts with "^", or -
    -
    -(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set -(if it were set, the pattern would be anchored), -
    -
    -2 is returned, indicating that the pattern matches only at the start of a -subject string or after any newline within the string. Otherwise 0 is -returned. For anchored patterns, 0 is returned. -

    -  PCRE_INFO_FIRSTCHARACTER
    -
    -Return the fixed first character value, if PCRE_INFO_FIRSTCHARACTERFLAGS -returned 1; otherwise returns 0. The fourth argument should point to an -uint_t variable. -

    -

    -In the 8-bit library, the value is always less than 256. In the 16-bit library -the value can be up to 0xffff. In the 32-bit library in UTF-32 mode the value -can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode. -

    -

    -If there is no fixed first value, and if either -
    -
    -(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch -starts with "^", or -
    -
    -(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set -(if it were set, the pattern would be anchored), -
    -
    --1 is returned, indicating that the pattern matches only at the start of a -subject string or after any newline within the string. Otherwise -2 is -returned. For anchored patterns, -2 is returned.

       PCRE_INFO_REQUIREDCHARFLAGS
     
    @@ -1517,8 +1608,8 @@ is different. (This seems a highly unlikely scenario.)
    MATCHING A PATTERN: THE TRADITIONAL FUNCTION

    int pcre_exec(const pcre *code, const pcre_extra *extra, -const char *subject, int length, int startoffset, -int options, int *ovector, int ovecsize); + 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 @@ -1634,6 +1725,16 @@ the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT.

    +A value for the match limit may also be supplied by an item at the start of a +pattern of the form +

    +  (*LIMIT_MATCH=d)
    +
    +where d is a decimal number. However, such a setting is ignored unless d is +less than the limit set by the caller of pcre_exec() or, if no such limit +is set, less than the default. +

    +

    The match_limit_recursion field is similar to match_limit, but instead of limiting the total number of times that match() is called, it limits the depth of recursion. The recursion depth is a smaller number than the @@ -1655,23 +1756,38 @@ PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_RECURSIONLIMIT.

    +A value for the recursion limit may also be supplied by an item at the start of +a pattern of the form +

    +  (*LIMIT_RECURSION=d)
    +
    +where d is a decimal number. However, such a setting is ignored unless d is +less than the limit set by the caller of pcre_exec() or, if no such limit +is set, less than the default. +

    +

    The callout_data field is used in conjunction with the "callout" feature, 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 argument. -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 +The tables field is provided for use with patterns that have been +pre-compiled using custom character tables, saved to disc or elsewhere, and +then reloaded, because the tables that were used to compile a pattern are not +saved with it. See the pcreprecompile -documentation for a discussion of saving compiled patterns for later use. +documentation for a discussion of saving compiled patterns for later use. If +NULL is passed using this mechanism, it forces PCRE's internal tables to be +used. +

    +

    +Warning: The tables that pcre_exec() uses must be the same as those +that were used when the pattern was compiled. If this is not the case, the +behaviour of pcre_exec() is undefined. Therefore, when a pattern is +compiled and matched in the same process, this field should never be set. In +this (the most common) case, the correct table pointer is automatically passed +with the compiled pattern from pcre_compile() to pcre_exec().

    If PCRE_EXTRA_MARK is set in the flags field, the mark field must @@ -1816,10 +1932,10 @@ unanchored match must start with a specific character, it searches the subject for that character, and fails immediately if it cannot find it, without actually running the main matching function. This means that a special item such as (*COMMIT) at the start of a pattern is not considered until after a -suitable starting point for the match has been found. When callouts or (*MARK) -items are in use, these "start-up" optimizations can cause them to be skipped -if the pattern is never actually used. The start-up optimizations are in effect -a pre-scan of the subject that takes place before the pattern is run. +suitable starting point for the match has been found. Also, when callouts or +(*MARK) items are in use, these "start-up" optimizations can cause them to be +skipped if the pattern is never actually used. The start-up optimizations are +in effect a pre-scan of the subject that takes place before the pattern is run.

    The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, possibly @@ -1827,8 +1943,9 @@ causing performance to suffer, but ensuring that in cases where the result is "no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) are considered at every possible starting position in the subject string. If PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching -time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, -matching is always done using interpretively. +time. The use of PCRE_NO_START_OPTIMIZE at matching time (that is, passing it +to pcre_exec()) disables JIT execution; in this situation, matching is +always done using interpretively.

    Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. @@ -1888,7 +2005,7 @@ 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. +undefined. Your program may crash or loop.

       PCRE_PARTIAL_HARD
       PCRE_PARTIAL_SOFT
    @@ -1922,13 +2039,19 @@ 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, -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 subject). Unlike the -pattern string, the subject may contain binary zero bytes. +subject, a length in length, and a starting offset in +startoffset. The units for length and startoffset are bytes +for the 8-bit library, 16-bit data items for the 16-bit library, and 32-bit +data items for the 32-bit library. +

    +

    +If startoffset is negative or greater than the length of the subject, +pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is +zero, the search for a match starts at the beginning of the subject, and this +is by far the most common case. In UTF-8 or UTF-16 mode, the offset must point +to the start of a character, or the end of the subject (in UTF-32 mode, one +data unit equals one character, so all offsets are valid). Unlike the pattern +string, the subject may contain binary zeroes.

    A non-zero starting offset is useful when searching for another match in the @@ -1996,10 +2119,12 @@ rounded down. When a match is successful, information about captured substrings is returned in pairs of integers, starting at the beginning of ovector, and continuing up to two-thirds of its length at the most. The first element of -each pair is set to the byte offset of the first character in a substring, and -the second is set to the byte offset of the first character after the end of a -substring. Note: these values are always byte offsets, even in UTF-8 -mode. They are not character counts. +each pair is set to the offset of the first character in a substring, and the +second is set to the offset of the first character after the end of a +substring. These values are always data unit offsets, even in UTF mode. They +are byte offsets in the 8-bit library, 16-bit data item offsets in the 16-bit +library, and 32-bit data item offsets in the 32-bit library. Note: they +are not character counts.

    The first pair of integers, ovector[0] and ovector[1], identify the @@ -2332,25 +2457,27 @@ character. The first byte of a character has the value 0xfe or 0xff. These values can never occur in a valid UTF-8 string.

    -  PCRE_UTF8_ERR2
    +  PCRE_UTF8_ERR22
     
    -Non-character. These are the last two characters in each plane (0xfffe, 0xffff, -0x1fffe, 0x1ffff .. 0x10fffe, 0x10ffff), and the characters 0xfdd0..0xfdef. +This error code was formerly used when the presence of a so-called +"non-character" caused an error. Unicode corrigendum #9 makes it clear that +such characters should not cause a string to be rejected, and so this code is +no longer in use and is never returned.


    EXTRACTING CAPTURED SUBSTRINGS BY NUMBER

    int pcre_copy_substring(const char *subject, int *ovector, -int stringcount, int stringnumber, char *buffer, -int buffersize); -

    -

    + int stringcount, int stringnumber, char *buffer, + int buffersize); +
    +
    int pcre_get_substring(const char *subject, int *ovector, -int stringcount, int stringnumber, -const char **stringptr); -

    -

    + int stringcount, int stringnumber, + const char **stringptr); +
    +
    int pcre_get_substring_list(const char *subject, -int *ovector, int stringcount, const char ***listptr); + int *ovector, int stringcount, const char ***listptr);

    Captured substrings can be accessed directly by using the offsets returned by @@ -2435,19 +2562,19 @@ provided.
    EXTRACTING CAPTURED SUBSTRINGS BY NAME

    int pcre_get_stringnumber(const pcre *code, -const char *name); -

    -

    + const char *name); +
    +
    int pcre_copy_named_substring(const pcre *code, -const char *subject, int *ovector, -int stringcount, const char *stringname, -char *buffer, int buffersize); -

    -

    + const char *subject, int *ovector, + int stringcount, const char *stringname, + char *buffer, int buffersize); +
    +
    int pcre_get_named_substring(const pcre *code, -const char *subject, int *ovector, -int stringcount, const char *stringname, -const char **stringptr); + const char *subject, int *ovector, + int stringcount, const char *stringname, + const char **stringptr);

    To extract a substring by name, you first have to find associated number. @@ -2499,7 +2626,7 @@ same number causes an error at compile time.
    DUPLICATE SUBPATTERN NAMES

    int pcre_get_stringtable_entries(const pcre *code, -const char *name, char **first, char **last); + const char *name, char **first, char **last);

    When a pattern is compiled with the PCRE_DUPNAMES option, names for subpatterns @@ -2580,9 +2707,9 @@ 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, -const char *subject, int length, int startoffset, -int options, int *ovector, int ovecsize, -int *workspace, int wscount); + const char *subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + int *workspace, int wscount);

    The function pcre_dfa_exec() is called to match a subject string against @@ -2711,6 +2838,15 @@ matching string is given first. If there were too many matches to fit into the longest matches. Unlike pcre_exec(), pcre_dfa_exec() can use the entire ovector for returning matched strings.

    +

    +NOTE: PCRE's "auto-possessification" optimization usually applies to character +repeats at the end of a pattern (as well as internally). For example, the +pattern "a\d+" is compiled as if it were "a\d++" because there is no point +even considering the possibility of backtracking into the repeated digits. For +DFA matching, this means that only one possible match is found. If you really +do want multiple matches in such cases, either use an ungreedy repeat +("a\d+?") or set the PCRE_NO_AUTO_POSSESS option when compiling. +


    Error returns from pcre_dfa_exec()
    @@ -2777,9 +2913,9 @@ Cambridge CB2 3QH, England.


    REVISION

    -Last updated: 08 November 2012 +Last updated: 09 February 2014
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2014 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcrebuild.html b/tools/pcre/doc/html/pcrebuild.html index 6eb169b3..03c8cbe0 100644 --- a/tools/pcre/doc/html/pcrebuild.html +++ b/tools/pcre/doc/html/pcrebuild.html @@ -13,46 +13,63 @@ from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

    -
    PCRE BUILD-TIME OPTIONS
    +
    BUILDING PCRE

    -This document describes the optional features of PCRE that can be selected when -the library is compiled. It assumes use of the configure script, where -the optional features are selected or deselected by providing options to -configure before running the make command. However, the same -options can be selected in both Unix-like and non-Unix-like environments using -the GUI facility of cmake-gui if you are using CMake instead of -configure to build PCRE. +PCRE is distributed with a configure script that can be used to build the +library in Unix-like environments using the applications known as Autotools. +Also in the distribution are files to support building using CMake +instead of configure. The text file +README +contains general information about building with Autotools (some of which is +repeated below), and also has some comments about building on various operating +systems. There is a lot more information about building PCRE without using +Autotools (including information about using CMake and building "by +hand") in the text file called +NON-AUTOTOOLS-BUILD. +You should consult this file as well as the +README +file if you are building in a non-Unix-like environment. +

    +
    PCRE BUILD-TIME OPTIONS
    +

    +The rest of this document describes the optional features of PCRE that can be +selected when the library is compiled. It assumes use of the configure +script, where the optional features are selected or deselected by providing +options to configure before running the make command. However, the +same options can be selected in both Unix-like and non-Unix-like environments +using the GUI facility of cmake-gui if you are using CMake instead +of configure to build PCRE.

    -There is a lot more information about building PCRE without using -configure (including information about using CMake or building "by -hand") in the file called NON-AUTOTOOLS-BUILD, which is part of the PCRE -distribution. You should consult this file as well as the README file if -you are building in a non-Unix-like environment. +If you are not using Autotools or CMake, option selection can be done by +editing the config.h file, or by passing parameter settings to the +compiler, as described in +NON-AUTOTOOLS-BUILD.

    The complete list of options for configure (which includes the standard @@ -67,7 +84,7 @@ The following sections include descriptions of options whose names begin with --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.

    -
    BUILDING 8-BIT, 16-BIT AND 32-BIT LIBRARIES
    +
    BUILDING 8-BIT, 16-BIT AND 32-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 @@ -78,7 +95,7 @@ strings, by adding

       --enable-pcre16
     
    -to the configure command. You can also build a separate +to the configure command. You can also build yet another separate library, called libpcre32, in which strings are contained in vectors of 32-bit data units and interpreted either as single-unit characters or UTF-32 strings, by adding @@ -94,17 +111,17 @@ 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 or 32-bit libraries.

    -
    BUILDING SHARED AND STATIC LIBRARIES
    +
    BUILDING SHARED AND STATIC LIBRARIES

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

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

    -
    C++ SUPPORT
    +
    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 @@ -115,7 +132,7 @@ strings). You can disable this by adding

    to the configure command.

    -
    UTF-8, UTF-16 AND UTF-32 SUPPORT
    +
    UTF-8, UTF-16 AND UTF-32 SUPPORT

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

    @@ -143,7 +160,7 @@ 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
    +
    UNICODE CHARACTER PROPERTY SUPPORT

    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 @@ -163,7 +180,7 @@ supported. Details are given in the pcrepattern documentation.

    -
    JUST-IN-TIME COMPILER SUPPORT
    +
    JUST-IN-TIME COMPILER SUPPORT

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

    @@ -180,7 +197,7 @@ pcregrep automatically makes use of it, unless you add
     
    to the "configure" command.

    -
    CODE VALUE OF NEWLINE
    +
    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 @@ -213,7 +230,7 @@ Whatever line ending convention is selected when PCRE is built can be 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 @@ -224,7 +241,7 @@ the default is changed so that \R matches only CR, LF, or CRLF. Whatever is selected when PCRE is built can be overridden when the library functions are called.

    -
    POSIX MALLOC USAGE
    +
    POSIX MALLOC USAGE

    When the 8-bit library is called through the POSIX interface (see the pcreposix @@ -240,7 +257,7 @@ such as

    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 @@ -259,7 +276,7 @@ longer offsets slows down the operation of PCRE because it has to load additional data when handling them. For the 32-bit library the value is always 4 and cannot be overridden; the value of --with-link-size is ignored.

    -
    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 @@ -290,7 +307,7 @@ 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
    +
    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() @@ -319,7 +336,7 @@ constraints. However, you can set a lower limit by adding, for example,

    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 @@ -336,7 +353,7 @@ 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 @@ -367,7 +384,7 @@ The options that select newline behaviour, such as --enable-newline-is-cr, and equivalent run-time options, refer to these character values in an EBCDIC environment.

    -
    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 @@ -380,7 +397,7 @@ to the configure command. These options naturally require that the relevant libraries are installed on your system. Configuration will fail if they are not.

    -
    PCREGREP BUFFER SIZE
    +
    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 @@ -395,7 +412,7 @@ parameter value by adding, for example, 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
    +
    PCRETEST OPTION FOR LIBREADLINE SUPPORT

    If you add

    @@ -426,7 +443,7 @@ automatically included, you may need to add something like
     
    immediately before the configure command.

    -
    DEBUGGING WITH VALGRIND SUPPORT
    +
    DEBUGGING WITH VALGRIND SUPPORT

    By adding the

    @@ -436,7 +453,7 @@ option to to the configure command, PCRE will use valgrind annotations
     to mark certain memory regions as unaddressable. This allows it to detect
     invalid memory accesses, and is mostly useful for debugging PCRE itself.
     

    -
    CODE COVERAGE REPORTING
    +
    CODE COVERAGE REPORTING

    If your C compiler is gcc, you can build a version of PCRE that can generate a code coverage report for its test suite. To enable this, you must install @@ -493,11 +510,11 @@ This cleans all coverage data including the generated coverage report. For more information about code coverage, see the gcov and lcov documentation.

    -
    SEE ALSO
    +
    SEE ALSO

    pcreapi(3), pcre16, pcre32, pcre_config(3).

    -
    AUTHOR
    +
    AUTHOR

    Philip Hazel
    @@ -506,11 +523,11 @@ University Computing Service Cambridge CB2 3QH, England.

    -
    REVISION
    +
    REVISION

    -Last updated: 30 October 2012 +Last updated: 12 May 2013
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2013 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcrecallout.html b/tools/pcre/doc/html/pcrecallout.html index b28e347f..53a937f5 100644 --- a/tools/pcre/doc/html/pcrecallout.html +++ b/tools/pcre/doc/html/pcrecallout.html @@ -64,23 +64,63 @@ it is processed as if it were

    Notice that there is a callout before and after each parenthesis and -alternation bar. Automatic callouts can be used for tracking the progress of -pattern matching. The -pcretest -command has an option that sets automatic callouts; when it is used, the output -indicates how the pattern is matched. This is useful information when you are -trying to optimize the performance of a particular pattern. +alternation bar. If the pattern contains a conditional group whose condition is +an assertion, an automatic callout is inserted immediately before the +condition. Such a callout may also be inserted explicitly, for example: +

    +  (?(?C9)(?=a)ab|de)
    +
    +This applies only to assertion conditions (because they are themselves +independent groups).

    -The use of callouts in a pattern makes it ineligible for optimization by the -just-in-time compiler. Studying such a pattern with the PCRE_STUDY_JIT_COMPILE -option always fails. +Automatic callouts can be used for tracking the progress of pattern matching. +The +pcretest +program has a pattern qualifier (/C) that sets automatic callouts; when it is +used, the output indicates how the pattern is being matched. This is useful +information when you are trying to optimize the performance of a particular +pattern.


    MISSING CALLOUTS

    -You should be aware that, because of optimizations in the way PCRE matches -patterns by default, callouts sometimes do not happen. For example, if the -pattern is +You should be aware that, because of optimizations in the way PCRE compiles and +matches patterns, callouts sometimes do not happen exactly as you might expect. +

    +

    +At compile time, PCRE "auto-possessifies" repeated items when it knows that +what follows cannot be part of the repeat. For example, a+[bc] is compiled as +if it were a++[bc]. The pcretest output when this pattern is anchored and +then applied with automatic callouts to the string "aaaa" is: +

    +  --->aaaa
    +   +0 ^        ^
    +   +1 ^        a+
    +   +3 ^   ^    [bc]
    +  No match
    +
    +This indicates that when matching [bc] fails, there is no backtracking into a+ +and therefore the callouts that would be taken for the backtracks do not occur. +You can disable the auto-possessify feature by passing PCRE_NO_AUTO_POSSESS +to pcre_compile(), or starting the pattern with (*NO_AUTO_POSSESS). If +this is done in pcretest (using the /O qualifier), the output changes to +this: +
    +  --->aaaa
    +   +0 ^        ^
    +   +1 ^        a+
    +   +3 ^   ^    [bc]
    +   +3 ^  ^     [bc]
    +   +3 ^ ^      [bc]
    +   +3 ^^       [bc]
    +  No match
    +
    +This time, when matching [bc] fails, the matcher backtracks into a+ and tries +again, repeatedly, until a+ itself fails. +

    +

    +Other optimizations that provide fast "no match" results also affect callouts. +For example, if the pattern is

       ab(?C4)cd
     
    @@ -104,11 +144,11 @@ 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 or pcre[16|32]_callout is called -(if it is set). This applies to both normal and DFA matching. The only -argument to the callout function is a pointer to a pcre_callout -or pcre[16|32]_callout block. -These structures contains the following fields: +defined by pcre_callout or pcre[16|32]_callout is called (if it is +set). This applies to both normal and DFA matching. The only argument to the +callout function is a pointer to a pcre_callout or +pcre[16|32]_callout block. These structures contains the following +fields:

       int           version;
       int           callout_number;
    @@ -141,10 +181,10 @@ automatically generated callouts).
     

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

    The subject and subject_length fields contain copies of the values @@ -171,8 +211,10 @@ 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 for the DFA matching functions. +substring. However, when a recursion exits, the value reverts to what it was +outside the recursion, as do the values of all captured substrings. If no +substrings have been captured, the value of capture_last is -1. This is +always the case for the DFA matching functions.

    The callout_data field contains a value that is passed to a matching @@ -203,11 +245,12 @@ 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 pcre[16|32]_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. +callouts from pcre_exec() or pcre[16|32]_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

    @@ -234,9 +277,9 @@ Cambridge CB2 3QH, England.


    REVISION

    -Last updated: 24 June 2012 +Last updated: 12 November 2013
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2013 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcrecompat.html b/tools/pcre/doc/html/pcrecompat.html index 0637781b..3e622669 100644 --- a/tools/pcre/doc/html/pcrecompat.html +++ b/tools/pcre/doc/html/pcrecompat.html @@ -36,10 +36,8 @@ these do not seem to have any use.

    3. Capturing subpatterns that occur inside negative lookahead assertions 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 succeeding), but only if the -negative lookahead assertion contains just one branch. +counted, but their entries in the offsets vector are never set. Perl sometimes +(but not always) sets its numerical variables from inside negative assertions.

    4. Though binary zero characters are supported in the subject string, they are @@ -102,24 +100,32 @@ in the page.

    -10. If any of the backtracking control verbs are used in an assertion or in a -subpattern that is called as a subroutine (whether or not recursively), their -effect is confined to that subpattern; it does not extend to the surrounding -pattern. This is not always the case in Perl. In particular, if (*THEN) is -present in a group that is called as a subroutine, its action is limited to -that group, even if the group does not contain any | characters. There is one -exception to this: the name from a *(MARK), (*PRUNE), or (*THEN) that is -encountered in a 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. +10. If any of the backtracking control verbs are used in a subpattern that is +called as a subroutine (whether or not recursively), their effect is confined +to that subpattern; it does not extend to the 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. Note that such subpatterns are +processed as anchored at the point where they are tested.

    -11. There are some differences that are concerned with the settings of captured +11. If a pattern contains more than one backtracking control verb, the first +one that is backtracked onto acts. For example, in the pattern +A(*COMMIT)B(*PRUNE)C a failure in B triggers (*COMMIT), but a failure in C +triggers (*PRUNE). Perl's behaviour is more complex; in many cases it is the +same as PCRE, but there are examples where it differs. +

    +

    +12. Most backtracking verbs in assertions have their normal actions. They are +not confined to the assertion. +

    +

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

    -12. PCRE's handling of duplicate subpattern numbers and duplicate subpattern +14. 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), @@ -130,13 +136,26 @@ names map to capturing subpattern number 1. To avoid this confusing situation, an error is given at compile time.

    -13. Perl recognizes comments in some places that PCRE does not, for example, +15. Perl recognizes comments in some places that PCRE does not, for example, between the ( and ? at the start of a subpattern. If the /x modifier is set, -Perl allows white space between ( and ? but PCRE never does, even if the -PCRE_EXTENDED option is set. +Perl allows white space between ( and ? (though current Perls warn that this is +deprecated) but PCRE never does, even if the PCRE_EXTENDED option is set.

    -14. PCRE provides some extensions to the Perl regular expression facilities. +16. Perl, when in warning mode, gives warnings for character classes such as +[A-\d] or [a-[:digit:]]. It then treats the hyphens as literals. PCRE has no +warning features, so it gives an error in these cases because they are almost +certainly user mistakes. +

    +

    +17. In PCRE, the upper/lower case character properties Lu and Ll are not +affected when case-independent matching is specified. For example, \p{Lu} +always matches an upper case letter. I think Perl has changed in this respect; +in the release at the time of writing (5.16), \p{Lu} and \p{Ll} match all +letters, regardless of case, when case independence is specified. +

    +

    +18. PCRE provides some extensions to the Perl regular expression 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: @@ -207,9 +226,9 @@ Cambridge CB2 3QH, England. REVISION

    -Last updated: 25 August 2012 +Last updated: 10 November 2013
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2013 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcregrep.html b/tools/pcre/doc/html/pcregrep.html index bac8f9a4..dacbb499 100644 --- a/tools/pcre/doc/html/pcregrep.html +++ b/tools/pcre/doc/html/pcregrep.html @@ -37,8 +37,10 @@ man page, in case the conversion went wrong. pcregrep searches files for character patterns, in the same way as other grep commands do, but it uses the PCRE regular expression library to support patterns that are compatible with the regular expressions of Perl 5. See +pcresyntax(3) +for a quick-reference summary of pattern syntax, or pcrepattern(3) -for a full description of syntax and semantics of the regular expressions +for a full description of the syntax and semantics of the regular expressions that PCRE supports.

    @@ -748,9 +750,9 @@ Cambridge CB2 3QH, England.


    REVISION

    -Last updated: 13 September 2012 +Last updated: 03 April 2014
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2014 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcrejit.html b/tools/pcre/doc/html/pcrejit.html index 6286fccb..210f1da0 100644 --- a/tools/pcre/doc/html/pcrejit.html +++ b/tools/pcre/doc/html/pcrejit.html @@ -172,15 +172,9 @@ 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. +The only unsupported pattern items are \C (match a single data unit) when +running in a UTF mode, and a callout immediately before an assertion condition +in a conditional group.


    RETURN VALUES FROM JIT EXECUTION

    @@ -449,9 +443,9 @@ Cambridge CB2 3QH, England.


    REVISION

    -Last updated: 31 October 2012 +Last updated: 17 March 2013
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2013 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcrelimits.html b/tools/pcre/doc/html/pcrelimits.html index b83a8010..ee5ebf03 100644 --- a/tools/pcre/doc/html/pcrelimits.html +++ b/tools/pcre/doc/html/pcrelimits.html @@ -21,9 +21,10 @@ practice be relevant.

    The maximum length of a compiled pattern is approximately 64K data units (bytes -for the 8-bit library, 32-bit units for the 32-bit library, and 32-bit units for -the 32-bit library) if PCRE is compiled with the default internal linkage size -of 2 bytes. If you want to process regular expressions that are truly enormous, +for the 8-bit library, 16-bit units for the 16-bit library, and 32-bit units for +the 32-bit library) if PCRE is compiled with the default internal linkage size, +which is 2 bytes for the 8-bit and 16-bit libraries, and 4 bytes for the 32-bit +library. If you want to process regular expressions that are truly enormous, you can compile PCRE with an internal linkage size of 3 or 4 (when building the 16-bit or 32-bit library, 3 is rounded up to 4). See the README file in the source distribution and the @@ -36,7 +37,10 @@ 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. +no more than 65535 capturing subpatterns. There is, however, a limit to the +depth of nesting of parenthesized subpatterns of all kinds. This is imposed in +order to limit the amount of system stack used at compile time. The limit can +be specified when PCRE is built; the default is 250.

    There is a limit to the number of forward references to subsequent subpatterns @@ -50,7 +54,7 @@ maximum number of named subpatterns is 10000.

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

    The maximum length of a subject string is the largest positive number that an @@ -77,9 +81,9 @@ Cambridge CB2 3QH, England. REVISION

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

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcrematching.html b/tools/pcre/doc/html/pcrematching.html index f1854314..a1af39b6 100644 --- a/tools/pcre/doc/html/pcrematching.html +++ b/tools/pcre/doc/html/pcrematching.html @@ -126,6 +126,15 @@ character of the subject. The algorithm does not automatically move on to find matches that start at later positions.

    +PCRE's "auto-possessification" optimization usually applies to character +repeats at the end of a pattern (as well as internally). For example, the +pattern "a\d+" is compiled as if it were "a\d++" because there is no point +even considering the possibility of backtracking into the repeated digits. For +DFA matching, this means that only one possible match is found. If you really +do want multiple matches in such cases, either use an ungreedy repeat +("a\d+?") or set the PCRE_NO_AUTO_POSSESS option when compiling. +

    +

    There are a number of features of PCRE regular expressions that are not supported by the alternative matching algorithm. They are as follows:

    @@ -224,7 +233,7 @@ Cambridge CB2 3QH, England.


    REVISION

    -Last updated: 08 January 2012 +Last updated: 12 November 2013
    Copyright © 1997-2012 University of Cambridge.
    diff --git a/tools/pcre/doc/html/pcrepartial.html b/tools/pcre/doc/html/pcrepartial.html index 298f92e0..4faeafcb 100644 --- a/tools/pcre/doc/html/pcrepartial.html +++ b/tools/pcre/doc/html/pcrepartial.html @@ -81,33 +81,36 @@ strings. This optimization is also disabled for partial matching.
    PARTIAL MATCHING USING pcre_exec() OR pcre[16|32]_exec()

    A partial match occurs during a call to pcre_exec() or -pcre[16|32]_exec() when the end of the subject string is reached 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. +pcre[16|32]_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. +subject so that a substring can easily be identified. If there are at least +three slots in the offsets vector, the third slot is set to the offset of the +character where matching started.

    -For the majority of patterns, the first offset identifies the start of the -partially matched string. However, for patterns that contain lookbehind -assertions, or \K, or begin with \b or \B, earlier characters have been -inspected while carrying out the match. For example: +For the majority of patterns, the contents of the first and third slots will be +the same. However, for patterns that contain lookbehind assertions, or begin +with \b or \B, characters before the one where matching started may have been +inspected while carrying out the match. For example, consider this pattern:

       /(?<=abc)123/
     
    This pattern matches "123", but only if it is preceded by "abc". If the subject -string is "xyzabc12", the offsets after a partial match are for the substring -"abc12", because all these characters are needed if another match is tried -with extra characters added to the subject. +string is "xyzabc12", the first two offsets after a partial match are for the +substring "abc12", because all these characters were inspected. However, the +third offset is set to 6, because that is the offset where matching began.

    What happens when a partial match is identified depends on which of the two @@ -303,6 +306,16 @@ not retain the previously partially-matched string. It is up to the calling program to do that if it needs to.

    +That means that, for an unanchored pattern, if a continued match fails, it is +not possible to try again at a new starting point. All this facility is capable +of doing is continuing with the previous match attempt. In the previous +example, if the second set of data is "ug23" the result is no match, even +though there would be a match for "aug23" if the entire string were given at +once. Depending on the application, this may or may not be what you want. +The only way to allow for starting again at the next character is to retain the +matched part of the subject and try a new complete match. +

    +

    You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with PCRE_DFA_RESTART to continue partial matching over multiple segments. This facility can be used to pass very long subject strings to the DFA matching @@ -334,10 +347,9 @@ 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. +characters that precede the start of what would be returned for a complete +match, because it contains all the characters that were inspected during the +partial match.


    ISSUES WITH MULTI-SEGMENT MATCHING

    @@ -356,12 +368,35 @@ includes the effect of PCRE_NOTEOL. 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 pcre[16|32]_fullinfo() functions to obtain the length -of the largest lookbehind in the pattern. This length is given in characters, -not bytes. If you always retain at least that many characters before the -partially matched string, all should be well. (Of course, near the start of the -subject, fewer characters may be present; in that case all characters should be -retained.) +pcre_fullinfo() or pcre[16|32]_fullinfo() functions to obtain the +length of the longest lookbehind in the pattern. This length is given in +characters, not bytes. If you always retain at least that many characters +before the partially matched string, all should be well. (Of course, near the +start of the subject, fewer characters may be present; in that case all +characters should be retained.) +

    +

    +From release 8.33, there is a more accurate way of deciding which characters to +retain. Instead of subtracting the length of the longest lookbehind from the +earliest inspected character (offsets[0]), the match start position +(offsets[2]) should be used, and the next match attempt started at the +offsets[2] character by setting the startoffset argument of +pcre_exec() or pcre_dfa_exec(). +

    +

    +For example, if the pattern "(?<=123)abc" is partially +matched against the string "xx123a", the three offset values returned are 2, 6, +and 5. This indicates that the matching process that gave a partial match +started at offset 5, but the characters "123a" were all inspected. The maximum +lookbehind for that pattern is 3, so taking that away from 5 shows that we need +only keep "123a", and the next match attempt can be started at offset 3 (that +is, at "a") when further characters have been added. When the match start is +not the earliest inspected character, pcretest shows it explicitly: +

    +    re> "(?<=123)abc"
    +  data> xx123a\P\P
    +  Partial match at offset 5: 123a
    +

    3. Because a partial match must always contain at least one character, what @@ -465,9 +500,9 @@ Cambridge CB2 3QH, England.


    REVISION

    -Last updated: 24 June 2012 +Last updated: 02 July 2013
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2013 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcrepattern.html b/tools/pcre/doc/html/pcrepattern.html index ee55d06e..c06d1e03 100644 --- a/tools/pcre/doc/html/pcrepattern.html +++ b/tools/pcre/doc/html/pcrepattern.html @@ -14,8 +14,8 @@ man page, in case the conversion went wrong.


    PCRE REGULAR EXPRESSION DETAILS

    @@ -61,6 +62,30 @@ published by O'Reilly, covers regular expressions in great detail. This description of PCRE's regular expressions is intended as reference material.

    +This document discusses the patterns that are supported by PCRE when one its +main matching functions, pcre_exec() (8-bit) or pcre[16|32]_exec() +(16- or 32-bit), is used. PCRE also has alternative matching functions, +pcre_dfa_exec() and pcre[16|32_dfa_exec(), which match using a +different algorithm that is not Perl-compatible. Some of the features discussed +below are not available when DFA matching is used. The advantages and +disadvantages of the alternative functions, and how they differ from the normal +functions, are discussed in the +pcrematching +page. +

    +
    SPECIAL START-OF-PATTERN ITEMS
    +

    +A number of options that can be passed to pcre_compile() can also be set +by special items at the start of a pattern. These are not Perl-compatible, but +are provided to make these options accessible to pattern writers who are not +able to change the program that processes the pattern. Any number of these +items may appear, but they must all be together right at the start of the +pattern string, and the letters must be in upper case. +

    +
    +UTF support +
    +

    The original operation of PCRE was on strings of one-byte characters. However, there is now also support for UTF-8 strings in the original library, an extra library that supports 16-bit and UTF-16 character strings, and a @@ -77,50 +102,52 @@ these special sequences:

    (*UTF) is a generic sequence that can be used with any of the libraries. Starting a pattern with such a sequence is equivalent to setting the relevant -option. This feature is not Perl-compatible. How setting a UTF mode affects -pattern matching is mentioned in several places below. There is also a summary -of features in the +option. How setting a UTF mode affects pattern matching is mentioned in several +places below. There is also a summary of features in the pcreunicode page.

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

    -  (*UCP)
    -
    +Some applications that allow their users to supply patterns may wish to +restrict them to non-UTF data for security reasons. If the PCRE_NEVER_UTF +option is set at compile time, (*UTF) etc. are not allowed, and their +appearance causes an error. +

    +
    +Unicode property support +
    +

    +Another special sequence that may appear at the start of a pattern is (*UCP). This has the same effect as setting the PCRE_UCP option: it causes sequences such as \d and \w to use Unicode properties to determine character types, instead of recognizing only characters with codes less than 128 via a lookup table.

    +
    +Disabling auto-possessification +
    +

    +If a pattern starts with (*NO_AUTO_POSSESS), it has the same effect as setting +the PCRE_NO_AUTO_POSSESS option at compile time. This stops PCRE from making +quantifiers possessive when what follows cannot match the repeated item. For +example, by default a+b is treated as a++b. For more details, see the +pcreapi +documentation. +

    +
    +Disabling start-up optimizations +

    If a pattern starts with (*NO_START_OPT), it has the same effect as setting the -PCRE_NO_START_OPTIMIZE option either at compile or matching time. There are -also some more of these special sequences that are concerned with the handling -of newlines; they are described below. -

    -

    -The remainder of this document discusses the patterns that are supported by -PCRE when one its main matching functions, pcre_exec() (8-bit) or -pcre[16|32]_exec() (16- or 32-bit), is used. PCRE also has alternative -matching functions, pcre_dfa_exec() and pcre[16|32_dfa_exec(), -which match using a different algorithm that is not Perl-compatible. Some of -the features discussed below are not available when DFA matching is used. The -advantages and disadvantages of the alternative functions, and how they differ -from the normal functions, are discussed in the -pcrematching -page. -

    -
    EBCDIC CHARACTER CODES
    -

    -PCRE can be compiled to run in an environment that uses EBCDIC as its character -code rather than ASCII or Unicode (typically a mainframe system). In the -sections below, character code values are ASCII or Unicode; in an EBCDIC -environment these characters may have different code values, and there are no -code points greater than 255. +PCRE_NO_START_OPTIMIZE option either at compile or matching time. This disables +several optimizations for quickly reaching "no match" results. For more +details, see the +pcreapi +documentation.

    -
    NEWLINE CONVENTIONS
    +
    +Newline conventions +

    PCRE supports five different conventions for indicating line breaks in strings: a single CR (carriage return) character, a single LF (linefeed) @@ -148,9 +175,7 @@ example, on a Unix system where LF is the default newline sequence, the pattern (*CR)a.b

    changes the convention to CR. That pattern matches "a\nb" because LF is no -longer a newline. Note that these special settings, which are not -Perl-compatible, are recognized only at the very start of a pattern, and that -they must be in upper case. If more than one of them is present, the last one +longer a newline. If more than one of these settings is present, the last one is used.

    @@ -164,6 +189,36 @@ description of \R in the section entitled below. A change of \R setting can be combined with a change of newline convention.

    +
    +Setting match and recursion limits +
    +

    +The caller of pcre_exec() can set a limit on the number of times the +internal match() function is called and on the maximum depth of +recursive calls. These facilities are provided to catch runaway matches that +are provoked by patterns with huge matching trees (a typical example is a +pattern with nested unlimited repeats) and to avoid running out of system stack +by too much recursion. When one of these limits is reached, pcre_exec() +gives an error return. The limits can also be set by items at the start of the +pattern of the form +

    +  (*LIMIT_MATCH=d)
    +  (*LIMIT_RECURSION=d)
    +
    +where d is any number of decimal digits. However, the value of the setting must +be less than the value set (or defaulted) by the caller of pcre_exec() +for it to have any effect. In other words, the pattern writer can lower the +limits set by the programmer, but not raise them. If there is more than one +setting of one of these limits, the lower value is used. +

    +
    EBCDIC CHARACTER CODES
    +

    +PCRE can be compiled to run in an environment that uses EBCDIC as its character +code rather than ASCII or Unicode (typically a mainframe system). In the +sections below, character code values are ASCII or Unicode; in an EBCDIC +environment these characters may have different code values, and there are no +code points greater than 255. +


    CHARACTERS AND METACHARACTERS

    A regular expression is a pattern that is matched against a subject string from @@ -241,10 +296,11 @@ backslash. All other characters (in particular, those whose codepoints are greater than 127) are treated as literals.

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

    If you want to remove the special meaning from a sequence of characters, you @@ -282,7 +338,9 @@ one of the following escape sequences than the binary character it represents: \n linefeed (hex 0A) \r carriage return (hex 0D) \t tab (hex 09) + \0dd character with octal code 0dd \ddd character with octal code ddd, or back reference + \o{ddd..} character with octal code ddd.. \xhh character with hex code hh \x{hhh..} character with hex code hhh.. (non-JavaScript mode) \uhhhh character with hex code hhhh (JavaScript mode only) @@ -305,42 +363,6 @@ the EBCDIC letters are disjoint, \cZ becomes hex 29 (Z is E9), and other characters also generate different values.

    -By default, after \x, from zero to two hexadecimal digits are read (letters -can be in upper or lower case). Any number of hexadecimal 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
    -  32-bit non-UTF mode   less than 0x80000000
    -  32-bit UTF-32 mode    less than 0x10ffff and a valid codepoint
    -
    -Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called -"surrogate" codepoints), and 0xffef. -

    -

    -If characters other than hexadecimal digits appear between \x{ and }, or if -there is no terminating }, this form of escape is not recognized. Instead, the -initial \x will be interpreted as a basic hexadecimal escape, with no -following digits, giving a character whose value is zero. -

    -

    -If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \x is -as just described only when it is followed by two hexadecimal 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 (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 digits, just those that are present are used. Thus the sequence \0\x\07 specifies two binary zeros followed by a BEL character (code value 7). Make @@ -348,9 +370,23 @@ sure you supply two digits after the initial zero if the pattern character that follows is itself an octal digit.

    -The handling of a backslash followed by a digit other than 0 is complicated. -Outside a character class, PCRE reads it and any following digits as a decimal -number. If the number is less than 10, or if there have been at least that many +The escape \o must be followed by a sequence of octal digits, enclosed in +braces. An error occurs if this is not the case. This escape is a recent +addition to Perl; it provides way of specifying character code points as octal +numbers greater than 0777, and it also allows octal numbers and back references +to be unambiguously specified. +

    +

    +For greater clarity and unambiguity, it is best to avoid following \ by a +digit greater than zero. Instead, use \o{} or \x{} to specify character +numbers, and \g{} to specify back references. The following paragraphs +describe the old, ambiguous syntax. +

    +

    +The handling of a backslash followed by a digit other than 0 is complicated, +and Perl has changed in recent releases, causing PCRE also to change. Outside a +character class, PCRE reads the digit and any following digits as a decimal +number. If the number is less than 8, or if there have been at least that many previous capturing left parentheses in the expression, the entire sequence is taken as a back reference. A description of how this works is given later, @@ -358,12 +394,11 @@ following the discussion of parenthesized subpatterns.

    -Inside a character class, or if the decimal number is greater than 9 and there -have not been that many capturing subpatterns, PCRE re-reads up to three octal -digits following the backslash, and uses them to generate a data character. Any -subsequent digits stand for themselves. The value of the character is -constrained in the same way as characters specified in hexadecimal. -For example: +Inside a character class, or if the decimal number following \ is greater than +7 and there have not been that many capturing subpatterns, PCRE handles \8 and +\9 as the literal characters "8" and "9", and otherwise re-reads up to three +octal digits following the backslash, using them to generate a data character. +Any subsequent digits stand for themselves. For example:

       \040   is another way of writing an ASCII space
       \40    is the same, provided there are fewer than 40 previous capturing subpatterns
    @@ -373,12 +408,53 @@ For example:
       \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 value 255 (decimal)
    -  \81    is either a back reference, or a binary zero followed by the two characters "8" and "1"
    +  \81    is either a back reference, or the two characters "8" and "1"
     
    -Note that octal values of 100 or greater must not be introduced by a leading -zero, because no more than three octal digits are ever read. +Note that octal values of 100 or greater that are specified using this syntax +must not be introduced by a leading zero, because no more than three octal +digits are ever read.

    +By default, after \x that is not followed by {, from zero to two hexadecimal +digits are read (letters can be in upper or lower case). Any number of +hexadecimal digits may appear between \x{ and }. If a character other than +a hexadecimal digit appears between \x{ and }, or if there is no terminating +}, an error occurs. +

    +

    +If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \x is +as just described only when it is followed by two hexadecimal 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. +

    +

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

    +
    +Constraints on character values +
    +

    +Characters that are specified using octal or hexadecimal numbers are +limited to certain values, as follows: +

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

    +
    +Escape sequences in character classes +
    +

    All the sequences that define a single character value can be used both inside and outside character classes. In addition, inside a character class, \b is interpreted as the backspace character (hex 08). @@ -456,11 +532,14 @@ matching point is at the end of the subject string, all of them fail, because there is no character to match.

    -For compatibility with Perl, \s does not match the VT character (code 11). -This makes it different from the the POSIX "space" class. The \s characters -are HT (9), LF (10), FF (12), CR (13), and space (32). If "use locale;" is -included in a Perl script, \s may match the VT character. In PCRE, it never -does. +For compatibility with Perl, \s did not used to match the VT character (code +11), which made it different from the the POSIX "space" class. However, Perl +added VT at release 5.18, and PCRE followed suit at release 8.34. The default +\s characters are now HT (9), LF (10), VT (11), FF (12), CR (13), and space +(32), which are defined as white space in the "C" locale. This list may vary if +locale-specific matching is taking place. For example, in some locales the +"non-breaking space" character (\xA0) is recognized as white space, and in +others the VT character is not.

    A "word" character is an underscore or any character that is a letter or digit. @@ -471,21 +550,23 @@ place (see in the pcreapi page). For example, in a French locale such as "fr_FR" in Unix-like systems, -or "french" in Windows, some character codes greater than 128 are used for +or "french" in Windows, some character codes greater than 127 are used for accented letters, and these are then matched by \w. The use of locales with Unicode is discouraged.

    -By default, in a UTF mode, characters with values greater than 128 never match -\d, \s, or \w, and always match \D, \S, and \W. These sequences retain -their original meanings from before UTF support was available, mainly for -efficiency reasons. However, if PCRE is compiled with Unicode property support, -and the PCRE_UCP option is set, the behaviour is changed so that Unicode -properties are used to determine character types, as follows: +By default, characters whose code points are greater than 127 never match \d, +\s, or \w, and always match \D, \S, and \W, although this may vary for +characters in the range 128-255 when locale-specific matching is happening. +These escape sequences retain their original meanings from before Unicode +support was available, mainly for efficiency reasons. 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:

    -  \d  any character that \p{Nd} matches (decimal digit)
    -  \s  any character that \p{Z} matches, plus HT, LF, FF, CR
    -  \w  any character that \p{L} or \p{N} matches, plus underscore
    +  \d  any character that matches \p{Nd} (decimal digit)
    +  \s  any character that matches \p{Z} or \h or \v
    +  \w  any character that matches \p{L} or \p{N}, plus underscore
     
    The upper case escapes match the inverse sets of characters. Note that \d matches only decimal digits, whereas \w matches any Unicode digit, as well as @@ -496,7 +577,7 @@ is noticeably slower when PCRE_UCP is set.

    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, +characters by default, these always match certain high-valued code points, whether or not PCRE_UCP is set. The horizontal space characters are:

       U+0009     Horizontal tab (HT)
    @@ -806,7 +887,8 @@ Unicode table.
     

    Specifying caseless matching does not affect these escape sequences. For -example, \p{Lu} always matches only upper case letters. +example, \p{Lu} always matches only upper case letters. This is different from +the behaviour of current versions of Perl.

    Matching characters by Unicode property is not fast, because PCRE has to do a @@ -870,8 +952,9 @@ PCRE's additional properties

    As well as the standard Unicode properties described above, PCRE supports four more that make it possible to convert traditional escape sequences such as \w -and \s and POSIX character classes to use Unicode properties. PCRE uses these -non-standard, non-Perl properties internally when PCRE_UCP is set. They are: +and \s to use Unicode properties. PCRE uses these non-standard, non-Perl +properties internally when PCRE_UCP is set. However, they may also be used +explicitly. These properties are:

       Xan   Any alphanumeric character
       Xps   Any POSIX space character
    @@ -881,8 +964,19 @@ non-standard, non-Perl properties internally when PCRE_UCP is set. They are:
     Xan matches characters that have either the L (letter) or the N (number)
     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.
    +Xsp is the same as Xps; it used to exclude vertical tab, for Perl
    +compatibility, but Perl changed, and so PCRE followed at release 8.34. Xwd
    +matches the same characters as Xan, plus underscore.
    +

    +

    +There is another non-standard property, Xuc, which matches any character that +can be represented by a Universal Character Name in C++ and other programming +languages. These are the characters $, @, ` (grave accent), and all characters +with Unicode code points greater than or equal to U+00A0, except for the +surrogates U+D800 to U+DFFF. Note that most base (ASCII) characters are +excluded. (Universal Character Names are of the form \uHHHH or \UHHHHHHHH +where H is a hexadecimal digit. Note that the Xuc property does not match these +sequences but the characters that they represent.)


    Resetting the match start @@ -909,7 +1003,9 @@ 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 assertions, but is -ignored in negative assertions. +ignored in negative assertions. Note that when a pattern such as (?=ab\K) +matches, the reported start of the match can be greater than the end of the +match.


    Simple assertions @@ -1164,7 +1260,9 @@ The minus (hyphen) character can be used to specify a range of characters 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. +indicating a range, typically as the first or last character in the class, or +immediately after a range. For example, [b-d-z] matches letters in the range b +to d, a hyphen character, or z.

    It is not possible to have the literal character "]" as the end character of a @@ -1176,6 +1274,12 @@ followed by two other characters. The octal or hexadecimal representation of "]" can also be used to end a range.

    +An error is generated if a POSIX character class (see below) or an escape +sequence other than one that defines a single character appears at a point +where a range ending character is expected. For example, [z-\xff] is valid, +but [A-\d] and [A-[:digit:]] are not. +

    +

    Ranges operate in the collating sequence of character values. They can also be used for characters specified numerically, for example [\000-\037]. Ranges can include any characters that are valid for the current mode. @@ -1215,9 +1319,9 @@ 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, escaping other non-alphanumeric characters -does no harm. +introducing a POSIX class name, or for a special compatibility feature - see +the next two sections), and the terminating closing square bracket. However, +escaping other non-alphanumeric characters does no harm.


    POSIX CHARACTER CLASSES

    @@ -1240,15 +1344,17 @@ are: lower lower case letters print printing characters, including space punct printing characters, excluding letters and digits and space - space white space (not quite the same as \s) + space white space (the same as \s from PCRE 8.34) upper upper case letters word "word" characters (same as \w) xdigit hexadecimal digits

    -The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), and -space (32). Notice that this list includes the VT character (code 11). This -makes "space" different to \s, which does not include VT (for Perl -compatibility). +The default "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), +and space (32). If locale-specific matching is taking place, the list of space +characters may be different; there may be fewer or more of them. "Space" used +to be different to \s, which did not include VT, for Perl compatibility. +However, Perl changed at release 5.18, and PCRE followed at release 8.34. +"Space" and \s now match the same set of characters.

    The name "word" is a Perl extension, and "blank" is a GNU extension from Perl @@ -1262,11 +1368,11 @@ syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not supported, and an error is given if they are encountered.

    -By default, in UTF modes, characters with values greater than 128 do not match -any of the POSIX character classes. However, if the PCRE_UCP option is passed -to pcre_compile(), some of the classes are changed so that Unicode -character properties are used. This is achieved by replacing the POSIX classes -by other sequences, as follows: +By default, characters with values greater than 128 do not match any of the +POSIX character classes. However, if the PCRE_UCP option is passed to +pcre_compile(), some of the classes are changed so that Unicode character +properties are used. This is achieved by replacing certain POSIX classes by +other sequences, as follows:

       [:alnum:]  becomes  \p{Xan}
       [:alpha:]  becomes  \p{L}
    @@ -1277,11 +1383,56 @@ by other sequences, as follows:
       [:upper:]  becomes  \p{Lu}
       [:word:]   becomes  \p{Xwd}
     
    -Negated versions, such as [:^alpha:] use \P instead of \p. The other POSIX -classes are unchanged, and match only characters with code points less than -128. +Negated versions, such as [:^alpha:] use \P instead of \p. Three other POSIX +classes are handled specially in UCP mode:

    -
    VERTICAL BAR
    +

    +[:graph:] +This matches characters that have glyphs that mark the page when printed. In +Unicode property terms, it matches all characters with the L, M, N, P, S, or Cf +properties, except for: +

    +  U+061C           Arabic Letter Mark
    +  U+180E           Mongolian Vowel Separator
    +  U+2066 - U+2069  Various "isolate"s
    +
    +
    +

    +

    +[:print:] +This matches the same characters as [:graph:] plus space characters that are +not controls, that is, characters with the Zs property. +

    +

    +[:punct:] +This matches all characters that have the Unicode P (punctuation) property, +plus those characters whose code points are less than 128 that have the S +(Symbol) property. +

    +

    +The other POSIX classes are unchanged, and match only characters with code +points less than 128. +

    +
    COMPATIBILITY FEATURE FOR WORD BOUNDARIES
    +

    +In the POSIX.2 compliant library that was included in 4.4BSD Unix, the ugly +syntax [[:<:]] and [[:>:]] is used for matching "start of word" and "end of +word". PCRE treats these items as follows: +

    +  [[:<:]]  is converted to  \b(?=\w)
    +  [[:>:]]  is converted to  \b(?<=\w)
    +
    +Only these exact character sequences are recognized. A sequence such as +[a[:<:]b] provokes error for an unrecognized POSIX class name. This support is +not compatible with Perl. It is provided to help migrations from other +environments, and is best not used in any new patterns. Note that \b matches +at the start and the end of a word (see +"Simple assertions" +above), and in a Perl-style pattern the preceding or following character +normally shows which is wanted, without the need for the assertions that are +used above in order to give exactly the POSIX behaviour. +

    +
    VERTICAL BAR

    Vertical bar characters are used to separate alternative patterns. For example, the pattern @@ -1296,7 +1447,7 @@ that succeeds is used. If the alternatives are within a subpattern "succeeds" means matching the rest of the main pattern as well as the alternative in the subpattern.

    -
    INTERNAL OPTION SETTING
    +
    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 @@ -1356,9 +1507,10 @@ above. There are also the (*UTF8), (*UTF16),(*UTF32), 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, PCRE_UTF32 and the PCRE_UCP options, respectively. The (*UTF) sequence is a generic version that can be -used with any of the libraries. +used with any of the libraries. However, the application can set the +PCRE_NEVER_UTF option, which locks out the use of the (*UTF) sequences.

    -
    SUBPATTERNS
    +
    SUBPATTERNS

    Subpatterns are delimited by parentheses (round brackets), which can be nested. Turning part of a pattern into a subpattern does two things: @@ -1414,7 +1566,7 @@ 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
    +
    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 @@ -1458,7 +1610,7 @@ true if any of the subpatterns of that number have matched. An alternative approach to using this "branch reset" feature is to use duplicate named subpatterns, as described in the next section.

    -
    NAMED SUBPATTERNS
    +
    NAMED SUBPATTERNS

    Identifying capturing parentheses by number is simple, but it can be very hard to keep track of the numbers in complicated regular expressions. Furthermore, @@ -1480,11 +1632,12 @@ and can be made by name as well as by number.

    -Names consist of up to 32 alphanumeric characters and underscores. Named -capturing parentheses are still allocated numbers as well as names, exactly as -if the names were not present. The PCRE API provides function calls for -extracting the name-to-number translation table from a compiled pattern. There -is also a convenience function for extracting a captured substring by name. +Names consist of up to 32 alphanumeric characters and underscores, but must +start with a non-digit. Named capturing parentheses are still allocated numbers +as well as names, exactly as if the names were not present. The PCRE API +provides function calls for extracting the name-to-number translation table +from a compiled pattern. There is also a convenience function for extracting a +captured substring by name.

    By default, a name must be unique within a pattern, but it is possible to relax @@ -1513,9 +1666,23 @@ 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 occurrence of the name is -used. In the absence of duplicate numbers (see the previous section) this is -the one with the lowest number. If you use a named reference in a condition +the pattern, the subpatterns to which the name refers are checked in the order +in which they appear in the overall pattern. The first one that is set is used +for the reference. For example, this pattern matches both "foofoo" and +"barbar" but not "foobar" or "barfoo": +

    +  (?:(?<n>foo)|(?<n>bar))\k<n>
    +
    +
    +

    +

    +If you make a subroutine call to a non-unique named subpattern, the one that +corresponds to the first occurrence of the name is used. In the absence of +duplicate numbers (see the previous section) this is the one with the lowest +number. +

    +

    +If you use a named reference in a condition test (see the section about conditions below), either to check whether a subpattern has matched, or to check for @@ -1530,10 +1697,11 @@ documentation. Warning: You cannot use different names to distinguish between two subpatterns with the same number because PCRE uses only the numbers when matching. For this reason, an error is given at compile time if different 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. +are given to subpatterns with the same number. However, you can always give the +same name to subpatterns with the same number, even when PCRE_DUPNAMES is not +set.

    -
    REPETITION
    +
    REPETITION

    Repetition is specified by quantifiers, which can follow any of the following items: @@ -1701,7 +1869,7 @@ example, after

    matches "aba" the value of the second captured substring is "b".

    -
    ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
    +
    ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS

    With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy") repetition, failure of what follows normally causes the repeated item to be @@ -1805,7 +1973,7 @@ an atomic group, like this:

    sequences of non-digits cannot be broken, and failure happens quickly.

    -
    BACK REFERENCES
    +
    BACK REFERENCES

    Outside a character class, a backslash followed by a digit greater than 0 (and possibly further digits) is a back reference to a capturing subpattern earlier @@ -1933,7 +2101,7 @@ as an Once the whole group has been matched, a subsequent matching failure cannot cause backtracking into the middle of the group.

    -
    ASSERTIONS
    +
    ASSERTIONS

    An assertion is a test on the characters following or preceding the current matching point that does not actually consume any characters. The simple @@ -1950,8 +2118,8 @@ except that it does not cause the current matching position to be changed. 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. +capturing is carried out only for positive assertions. (Perl sometimes, but not +always, does do capturing in negative assertions.)

    For compatibility with Perl, assertion subpatterns may be repeated; though @@ -2123,7 +2291,7 @@ preceded by "foo", while is another pattern that matches "foo" preceded by three digits and any three characters that are not "999".

    -
    CONDITIONAL SUBPATTERNS
    +
    CONDITIONAL SUBPATTERNS

    It is possible to cause the matching process to obey a subpattern conditionally or to choose between two alternative subpatterns, depending on @@ -2197,12 +2365,7 @@ Checking for a used subpattern by name

    Perl uses the syntax (?(<name>)...) or (?('name')...) to test for a used subpattern by name. For compatibility with earlier versions of PCRE, which had -this facility before Perl, the syntax (?(name)...) is also recognized. However, -there is a possible ambiguity with this syntax, 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 number, which must be greater than zero. Using subpattern -names that consist entirely of digits is not recommended. +this facility before Perl, the syntax (?(name)...) is also recognized.

    Rewriting the above example to use a named subpattern gives this: @@ -2278,7 +2441,7 @@ subject is matched against the first alternative; otherwise it is matched against the second. This pattern matches strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits.

    -
    COMMENTS
    +
    COMMENTS

    There are two ways of including comments in patterns that are processed by PCRE. In both cases, the start of the comment must not be in a character class, @@ -2307,7 +2470,7 @@ a newline in the pattern. The sequence \n is still literal at this stage, so it does not terminate the comment. Only an actual character with the code value 0x0a (the default newline) does so.

    -
    RECURSIVE PATTERNS
    +
    RECURSIVE PATTERNS

    Consider the problem of matching a string in parentheses, allowing for unlimited nested parentheses. Without the use of recursion, the best that can @@ -2522,7 +2685,7 @@ 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
    +
    SUBPATTERNS AS SUBROUTINES

    If the syntax for a recursive subpattern call (either by number or by name) is used outside the parentheses to which it refers, it operates like a @@ -2563,7 +2726,7 @@ different calls. For example, consider this pattern: It matches "abcabc". It does not match "abcABC" because the change of processing option does not affect the called subpattern.

    -
    ONIGURUMA SUBROUTINE SYNTAX
    +
    ONIGURUMA SUBROUTINE SYNTAX

    For compatibility with Oniguruma, the non-Perl syntax \g followed by a name or a number enclosed either in angle brackets or single quotes, is an alternative @@ -2581,7 +2744,7 @@ plus or a minus sign it is taken as a relative reference. For example: Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not synonymous. The former is a back reference; the latter is a subroutine call.

    -
    CALLOUTS
    +
    CALLOUTS

    Perl has a feature whereby using the sequence (?{...}) causes arbitrary Perl code to be obeyed in the middle of matching a regular expression. This makes it @@ -2605,53 +2768,65 @@ For example, this pattern has two callout points: 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. +255. If there is a conditional group in the pattern whose condition is an +assertion, an additional callout is inserted just before the condition. An +explicit callout may also be set at this position, as in this example: +

    +  (?(?C9)(?=a)abc|def)
    +
    +Note that this applies only to assertion conditions, not to other types of +condition.

    During matching, when PCRE reaches a callout point, the external 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 +backtrack, or to fail altogether. +

    +

    +By default, PCRE implements a number of optimizations at compile time and +matching time, and one side-effect is that sometimes callouts are skipped. If +you need all possible callouts to happen, you need to set options that disable +the relevant optimizations. More details, and a complete description of the +interface to the callout function, are given in the pcrecallout documentation.

    -
    BACKTRACKING CONTROL
    +
    BACKTRACKING CONTROL

    Perl 5.10 introduced a number of "Special Backtracking Control Verbs", which -are described in the Perl documentation as "experimental and subject to change -or removal in a future version of Perl". It goes on to say: "Their usage in -production code should be noted to avoid problems during upgrades." The same +are still described in the Perl documentation as "experimental and subject to +change or removal in a future version of Perl". It goes on to say: "Their usage +in production code should be noted to avoid problems during upgrades." The same remarks apply to the PCRE features described in this section.

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

    -

    -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. A name is any sequence of -characters that does not include a closing parenthesis. The maximum length of -name is 255 in the 8-bit library and 65535 in the 16-bit and 32-bit library. -If the name is empty, that is, if the 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, possibly behaving +differently depending on whether or not a name is present. A name is any +sequence of characters that does not include a closing parenthesis. The maximum +length of name is 255 in the 8-bit library and 65535 in the 16-bit and 32-bit +libraries. If the name is empty, that is, if the closing parenthesis +immediately follows the colon, the effect is as if the colon were not there. +Any number of these verbs may occur in a pattern. +

    +

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

    +

    +The behaviour of these verbs in +repeated groups, +assertions, +and in +subpatterns called as subroutines +(whether or not recursively) is documented below.


    Optimizations that affect backtracking verbs @@ -2660,7 +2835,7 @@ 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 minimum length of matching subject, or that a particular character must be -present. When one of these optimizations suppresses the running of a match, any +present. When one of these optimizations bypasses the running of a match, any included backtracking verbs will not, of course, be processed. You can suppress the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_compile() or pcre_exec(), or by starting the @@ -2687,8 +2862,12 @@ followed by a name. 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: +at the outer level. If (*ACCEPT) in triggered in a positive assertion, the +assertion succeeds; in a negative assertion, the assertion fails. +

    +

    +If (*ACCEPT) is inside capturing parentheses, the data so far is captured. For +example:

       A((?:A|B(*ACCEPT)|C)D)
     
    @@ -2722,8 +2901,9 @@ A name is always required with this verb. There may be as many instances of (*MARK) as you like in a pattern, and their names do not have to be unique.

    -When a match succeeds, the name of the last-encountered (*MARK) on the matching -path is passed back to the caller as described in the section entitled +When a match succeeds, the name of the last-encountered (*MARK:NAME), +(*PRUNE:NAME), or (*THEN:NAME) on the matching path is passed back to the +caller as described in the section entitled "Extra data for pcre_exec()" in the pcreapi @@ -2744,13 +2924,13 @@ of obtaining this information than putting each alternative in its own capturing parentheses.

    -If (*MARK) is encountered in a positive assertion, its name is recorded and -passed back if it is the last-encountered. This does not happen for negative -assertions. +If a verb with a name is encountered in a positive assertion that is true, the +name is recorded and passed back if it is the last-encountered. This does not +happen for negative assertions or failing positive 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: +After a partial match or a failed match, the last encountered name in the +entire match process is returned. For example:

         re> /X(*MARK:A)Y|X(*MARK:B)Z/K
       data> XP
    @@ -2774,23 +2954,28 @@ Verbs that act after backtracking
     The following verbs do nothing when they are encountered. Matching continues
     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 backtracking 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.)
    +the verb. However, when one of these verbs appears inside an atomic group or an
    +assertion that is true, its effect is confined to that group, because once the
    +group has been matched, there is never any backtracking into it. In this
    +situation, backtracking can "jump back" to the left of the entire atomic group
    +or assertion. (Remember also, as stated above, that this localization also
    +applies in subroutine calls.)
     

    These verbs differ in exactly what kind of failure occurs when backtracking -reaches them. +reaches them. The behaviour described below is what happens when the verb is +not in a subroutine or an assertion. Subsequent sections cover these special +cases.

       (*COMMIT)
     
    This verb, which may not be followed by a name, causes the whole match to fail -outright if the rest of the pattern does not match. Even if the pattern is -unanchored, no further attempts to find a match by advancing the starting point -take place. Once (*COMMIT) has been passed, pcre_exec() is committed to -finding a match at the current starting point, or not at all. For example: +outright if there is a later matching failure that causes backtracking to reach +it. Even if the pattern is unanchored, no further attempts to find a match by +advancing the starting point take place. If (*COMMIT) is the only backtracking +verb that is encountered, once it has been passed pcre_exec() is +committed to finding a match at the current starting point, or not at all. For +example:
       a+(*COMMIT)b
     
    @@ -2800,34 +2985,47 @@ recently passed (*MARK) in the path is passed back when (*COMMIT) forces a match failure.

    +If there is more than one backtracking verb in a pattern, a different one that +follows (*COMMIT) may be triggered first, so merely passing (*COMMIT) during a +match does not always guarantee that a match must be at this starting point. +

    +

    Note that (*COMMIT) at the start of a pattern is not the same as an anchor, unless PCRE's start-of-match optimizations are turned off, as shown in this -pcretest example: +output from pcretest:

         re> /(*COMMIT)abc/
       data> xyzabc
        0: abc
    -  xyzabc\Y
    +  data> 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 the second subject, the match -starts at "x" and so the (*COMMIT) causes it to fail without trying any other -starting points. +For this pattern, PCRE knows that any match must start with "a", so the +optimization skips along the subject to "a" before applying the pattern to the +first set of data. The match attempt then succeeds. In the second set of data, +the escape sequence \Y is interpreted by the pcretest program. It causes +the PCRE_NO_START_OPTIMIZE option to be set when pcre_exec() is called. +This disables the optimization that skips along to the first character. The +pattern is now applied starting at "x", and so the (*COMMIT) causes the match +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 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). In an -anchored pattern (*PRUNE) has the same effect as (*COMMIT). +subject if there is a later matching failure that causes backtracking to reach +it. If the pattern is unanchored, the normal "bumpalong" advance to the next +starting character then happens. Backtracking can occur as usual to the left of +(*PRUNE), before it is reached, or when matching to the right of (*PRUNE), but +if there is no match to the right, backtracking cannot cross (*PRUNE). In +simple cases, the use of (*PRUNE) is just an alternative to an atomic group or +possessive quantifier, but there are some uses of (*PRUNE) that cannot be +expressed in any other way. In an anchored pattern (*PRUNE) has the same effect +as (*COMMIT). +

    +

    +The behaviour of (*PRUNE:NAME) is the not the same as (*MARK:NAME)(*PRUNE). +It is like (*MARK:NAME) in that the name is remembered for passing back to the +caller. However, (*SKIP:NAME) searches only for names set with (*MARK).

       (*SKIP)
     
    @@ -2848,31 +3046,41 @@ instead of skipping on to "c".
       (*SKIP:NAME)
     
    -When (*SKIP) has an associated name, its behaviour is modified. If the -following pattern fails to match, the previous path through the pattern is -searched for the most recent (*MARK) that has the same name. If one is found, -the "bumpalong" advance is to the subject position that corresponds to that -(*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a -matching name is found, the (*SKIP) is ignored. +When (*SKIP) has an associated name, its behaviour is modified. When it is +triggered, the previous path through the pattern is searched for the most +recent (*MARK) that has the same name. If one is found, the "bumpalong" advance +is to the subject position that corresponds to that (*MARK) instead of to where +(*SKIP) was encountered. If no (*MARK) with a matching name is found, the +(*SKIP) is ignored. +

    +

    +Note that (*SKIP:NAME) searches only for names set by (*MARK:NAME). It ignores +names that are set by (*PRUNE:NAME) or (*THEN:NAME).

       (*THEN) or (*THEN:NAME)
     
    -This verb causes a skip to the next innermost alternative if the rest of the -pattern does not match. That is, it cancels pending 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: +This verb causes a skip to the next innermost alternative when backtracking +reaches it. That is, it cancels any further backtracking within the current +alternative. Its name comes from the observation that it can be used for a +pattern-based if-then-else block:
       ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ...
     
    If the COND1 pattern matches, FOO is tried (and possibly further items after the end of the group if FOO succeeds); on failure, the matcher skips to the -second alternative and tries COND2, without backtracking into COND1. The -behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN). -If (*THEN) is not inside an alternation, it acts like (*PRUNE). +second alternative and tries COND2, without backtracking into COND1. If that +succeeds and BAR fails, COND3 is tried. If subsequently BAZ fails, there are no +more alternatives, so there is a backtrack to whatever came before the entire +group. 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 +The behaviour of (*THEN:NAME) is the not the same as (*MARK:NAME)(*THEN). +It is like (*MARK:NAME) in that the name is remembered for passing back to the +caller. However, (*SKIP:NAME) searches only for names set with (*MARK). +

    +

    +A subpattern that does not contain a | character is just a part of the +enclosing alternative; it is not a nested alternation with only one alternative. The effect of (*THEN) extends beyond such a subpattern to the enclosing alternative. Consider this pattern, where A, B, etc. are complex pattern fragments that do not contain any | characters at this level: @@ -2892,7 +3100,7 @@ because there are no more alternatives to try. In this case, matching does now backtrack into A.

    -Note also that a conditional subpattern is not considered as having two +Note that a conditional subpattern is not considered as having two alternatives, because only one is ever used. In other words, the | character in a conditional subpattern has a different meaning. Ignoring white space, consider: @@ -2916,24 +3124,98 @@ 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.

    +
    +More than one backtracking verb +

    -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: +If more than one backtracking verb is present in a pattern, the one that is +backtracked onto first acts. For example, consider this pattern, where A, B, +etc. are complex pattern fragments:

    -  (A(*COMMIT)B(*THEN)C|D)
    +  (A(*COMMIT)B(*THEN)C|ABD)
     
    -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 alternative (that is, D) does not happen because (*COMMIT) -overrides. +If A matches but B fails, the backtrack to (*COMMIT) causes the entire match to +fail. However, if A and B match, but C fails, the backtrack to (*THEN) causes +the next alternative (ABD) to be tried. This behaviour is consistent, but is +not always the same as Perl's. It means that if two or more backtracking verbs +appear in succession, all the the last of them has no effect. Consider this +example: +
    +  ...(*COMMIT)(*PRUNE)...
    +
    +If there is a matching failure to the right, backtracking onto (*PRUNE) causes +it to be triggered, and its action is taken. There can never be a backtrack +onto (*COMMIT). +

    +
    +Backtracking verbs in repeated groups +
    +

    +PCRE differs from Perl in its handling of backtracking verbs in repeated +groups. For example, consider: +

    +  /(a(*COMMIT)b)+ac/
    +
    +If the subject is "abac", Perl matches, but PCRE fails because the (*COMMIT) in +the second repeat of the group acts. +

    +
    +Backtracking verbs in assertions +
    +

    +(*FAIL) in an assertion has its normal effect: it forces an immediate backtrack.

    -
    SEE ALSO
    +

    +(*ACCEPT) in a positive assertion causes the assertion to succeed without any +further processing. In a negative assertion, (*ACCEPT) causes the assertion to +fail without any further processing. +

    +

    +The other backtracking verbs are not treated specially if they appear in a +positive assertion. In particular, (*THEN) skips to the next alternative in the +innermost enclosing group that has alternations, whether or not this is within +the assertion. +

    +

    +Negative assertions are, however, different, in order to ensure that changing a +positive assertion into a negative assertion changes its result. Backtracking +into (*COMMIT), (*SKIP), or (*PRUNE) causes a negative assertion to be true, +without considering any further alternative branches in the assertion. +Backtracking into (*THEN) causes it to skip to the next enclosing alternative +within the assertion (the normal behaviour), but if the assertion does not have +such an alternative, (*THEN) behaves like (*PRUNE). +

    +
    +Backtracking verbs in subroutines +
    +

    +These behaviours occur whether or not the subpattern is called recursively. +Perl's treatment of subroutines is different in some cases. +

    +

    +(*FAIL) in a subpattern called as a subroutine has its normal effect: it forces +an immediate backtrack. +

    +

    +(*ACCEPT) in a subpattern called as a subroutine causes the subroutine match to +succeed without any further processing. Matching then continues after the +subroutine call. +

    +

    +(*COMMIT), (*SKIP), and (*PRUNE) in a subpattern called as a subroutine cause +the subroutine match to fail. +

    +

    +(*THEN) skips to the next alternative in the innermost enclosing group within +the subpattern that has alternatives. If there is no such group within the +subpattern, (*THEN) causes the subroutine match to fail. +

    +
    SEE ALSO

    pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3), pcre16(3), pcre32(3).

    -
    AUTHOR
    +
    AUTHOR

    Philip Hazel
    @@ -2942,11 +3224,11 @@ University Computing Service Cambridge CB2 3QH, England.

    -
    REVISION
    +
    REVISION

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

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcreposix.html b/tools/pcre/doc/html/pcreposix.html index 0e5b296a..18924cf7 100644 --- a/tools/pcre/doc/html/pcreposix.html +++ b/tools/pcre/doc/html/pcreposix.html @@ -13,7 +13,7 @@ from the original man page. If there is any nonsense in it, please consult the man page, in case the conversion went wrong.

    -
    SYNOPSIS OF POSIX API
    +
    SYNOPSIS

    #include <pcreposix.h>

    int regcomp(regex_t *preg, const char *pattern, -int cflags); -

    -

    + int cflags); +
    +
    int regexec(regex_t *preg, const char *string, -size_t nmatch, regmatch_t pmatch[], int eflags); -

    -

    -size_t regerror(int errcode, const regex_t *preg, -char *errbuf, size_t errbuf_size); -

    -

    + size_t nmatch, regmatch_t pmatch[], int eflags); + size_t regerror(int errcode, const regex_t *preg, + char *errbuf, size_t errbuf_size); +
    +
    void regfree(regex_t *preg);


    DESCRIPTION
    diff --git a/tools/pcre/doc/html/pcreprecompile.html b/tools/pcre/doc/html/pcreprecompile.html index beb9e242..decb1d6c 100644 --- a/tools/pcre/doc/html/pcreprecompile.html +++ b/tools/pcre/doc/html/pcreprecompile.html @@ -102,8 +102,8 @@ study data.
    RE-USING A PRECOMPILED PATTERN

    Re-using a precompiled pattern is straightforward. Having reloaded it into main -memory, called pcre[16|32]_pattern_to_host_byte_order() if necessary, -you pass its pointer to pcre[16|32]_exec() or pcre[16|32]_dfa_exec() in +memory, called pcre[16|32]_pattern_to_host_byte_order() if necessary, you +pass its pointer to pcre[16|32]_exec() or pcre[16|32]_dfa_exec() in the usual way.

    @@ -119,6 +119,11 @@ in the documentation.

    +Warning: The tables that pcre_exec() and pcre_dfa_exec() use +must be the same as those that were used when the pattern was compiled. If this +is not the case, the behaviour is undefined. +

    +

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

    If you saved study data with the compiled pattern, you need to create your own -pcre[16|32]_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|32]_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|32]_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. @@ -149,9 +154,9 @@ Cambridge CB2 3QH, England.


    REVISION

    -Last updated: 24 June 2012 +Last updated: 12 November 2013
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2013 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcresyntax.html b/tools/pcre/doc/html/pcresyntax.html index 22a253e2..89f35737 100644 --- a/tools/pcre/doc/html/pcresyntax.html +++ b/tools/pcre/doc/html/pcresyntax.html @@ -29,13 +29,13 @@ man page, in case the conversion went wrong.

  • ATOMIC GROUPS
  • COMMENT
  • OPTION SETTING -
  • LOOKAHEAD AND LOOKBEHIND ASSERTIONS -
  • BACKREFERENCES -
  • SUBROUTINE REFERENCES (POSSIBLY RECURSIVE) -
  • CONDITIONAL PATTERNS -
  • BACKTRACKING CONTROL -
  • NEWLINE CONVENTIONS -
  • WHAT \R MATCHES +
  • NEWLINE CONVENTION +
  • WHAT \R MATCHES +
  • LOOKAHEAD AND LOOKBEHIND ASSERTIONS +
  • BACKREFERENCES +
  • SUBROUTINE REFERENCES (POSSIBLY RECURSIVE) +
  • CONDITIONAL PATTERNS +
  • BACKTRACKING CONTROL
  • CALLOUTS
  • SEE ALSO
  • AUTHOR @@ -65,10 +65,14 @@ documentation. This document contains a quick-reference summary of the syntax. \n newline (hex 0A) \r carriage return (hex 0D) \t tab (hex 09) + \0dd character with octal code 0dd \ddd character with octal code ddd, or backreference + \o{ddd..} character with octal code ddd.. \xhh character with hex code hh \x{hhh..} character with hex code hhh.. -
  • + +Note that \0dd is always an octal code, and that \8 and \9 are the literal +characters "8" and "9".


    CHARACTER TYPES

    @@ -92,9 +96,11 @@ documentation. This document contains a quick-reference summary of the syntax. \W a "non-word" character \X a Unicode extended grapheme cluster -In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII -characters, even in a UTF mode. However, this can be changed by setting the -PCRE_UCP option. +By default, \d, \s, and \w match only ASCII characters, even in UTF-8 mode +or in the 16- bit and 32-bit libraries. However, if locale-specific matching is +happening, \s and \w may also match characters with code points in the range +128-255. If the PCRE_UCP option is set, the behaviour of these escape sequences +is changed to use Unicode properties and they match many more characters.


    GENERAL CATEGORY PROPERTIES FOR \p and \P

    @@ -150,9 +156,13 @@ PCRE_UCP option.

       Xan        Alphanumeric: union of properties L and N
       Xps        POSIX space: property Z or tab, NL, VT, FF, CR
    -  Xsp        Perl space: property Z or tab, NL, FF, CR
    +  Xsp        Perl space: property Z or tab, NL, VT, FF, CR
    +  Xuc        Univerally-named character: one that can be
    +               represented by a Universal Character Name
       Xwd        Perl word: property Xan or underscore
    -
    + +Perl and POSIX space are now the same. Perl added VT to its space character set +at release 5.18 and PCRE changed at release 8.34.


    SCRIPT NAMES FOR \p AND \P

    @@ -329,7 +339,8 @@ but some of them use Unicode properties if PCRE_UCP is set. You can use

       \K          reset start of match
    -
    + +\K is honoured in positive assertions, but ignored in negative ones.


    ALTERNATION

    @@ -372,18 +383,45 @@ but some of them use Unicode properties if PCRE_UCP is set. You can use (?x) extended (ignore white space) (?-...) unset option(s) -The following are recognized only at the start of a pattern or after one of the -newline-setting options with similar syntax: +The following are recognized only at the very start of a pattern or after one +of the newline or \R options with similar syntax. More than one of them may +appear.

    +  (*LIMIT_MATCH=d) set the match limit to d (decimal number)
    +  (*LIMIT_RECURSION=d) set the recursion limit to d (decimal number)
    +  (*NO_AUTO_POSSESS) no auto-possessification (PCRE_NO_AUTO_POSSESS)
       (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
       (*UTF8)         set UTF-8 mode: 8-bit library (PCRE_UTF8)
       (*UTF16)        set UTF-16 mode: 16-bit library (PCRE_UTF16)
       (*UTF32)        set UTF-32 mode: 32-bit library (PCRE_UTF32)
       (*UTF)          set appropriate UTF mode for the library in use
       (*UCP)          set PCRE_UCP (use Unicode properties for \d etc)
    +
    +Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value of the +limits set by the caller of pcre_exec(), not increase them. +

    +
    NEWLINE CONVENTION
    +

    +These are recognized only at the very start of the pattern or after option +settings with a similar syntax. +

    +  (*CR)           carriage return only
    +  (*LF)           linefeed only
    +  (*CRLF)         carriage return followed by linefeed
    +  (*ANYCRLF)      all three of the above
    +  (*ANY)          any Unicode newline sequence
     

    -
    LOOKAHEAD AND LOOKBEHIND ASSERTIONS
    +
    WHAT \R MATCHES
    +

    +These are recognized only at the very start of the pattern or after option +setting with a similar syntax. +

    +  (*BSR_ANYCRLF)  CR, LF, or CRLF
    +  (*BSR_UNICODE)  any Unicode newline sequence
    +
    +

    +
    LOOKAHEAD AND LOOKBEHIND ASSERTIONS

       (?=...)         positive look ahead
    @@ -393,7 +431,7 @@ newline-setting options with similar syntax:
     
    Each top-level branch of a look behind must be of a fixed length.

    -
    BACKREFERENCES
    +
    BACKREFERENCES

       \n              reference by number (can be ambiguous)
    @@ -407,7 +445,7 @@ Each top-level branch of a look behind must be of a fixed length.
       (?P=name)       reference by name (Python)
     

    -
    SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)
    +
    SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)

       (?R)            recurse whole pattern
    @@ -426,7 +464,7 @@ Each top-level branch of a look behind must be of a fixed length.
       \g'-n'          call subpattern by relative number (PCRE extension)
     

    -
    CONDITIONAL PATTERNS
    +
    CONDITIONAL PATTERNS

       (?(condition)yes-pattern)
    @@ -445,7 +483,7 @@ Each top-level branch of a look behind must be of a fixed length.
       (?(assert)...   assertion condition
     

    -
    BACKTRACKING CONTROL
    +
    BACKTRACKING CONTROL

    The following act immediately they are reached:

    @@ -468,27 +506,6 @@ pattern is not anchored.
       (*THEN:NAME)    equivalent to (*MARK:NAME)(*THEN)
     

    -
    NEWLINE CONVENTIONS
    -

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

    -  (*CR)           carriage return only
    -  (*LF)           linefeed only
    -  (*CRLF)         carriage return followed by linefeed
    -  (*ANYCRLF)      all three of the above
    -  (*ANY)          any Unicode newline sequence
    -
    -

    -
    WHAT \R MATCHES
    -

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

    -  (*BSR_ANYCRLF)  CR, LF, or CRLF
    -  (*BSR_UNICODE)  any Unicode newline sequence
    -
    -


    CALLOUTS

    @@ -512,9 +529,9 @@ Cambridge CB2 3QH, England.
     


    REVISION

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

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcretest.html b/tools/pcre/doc/html/pcretest.html index 8423ba5a..839fabf1 100644 --- a/tools/pcre/doc/html/pcretest.html +++ b/tools/pcre/doc/html/pcretest.html @@ -14,21 +14,22 @@ man page, in case the conversion went wrong.


    SYNOPSIS

    @@ -63,25 +64,34 @@ conjunction with the test script and data files that are distributed as part of PCRE, and are unlikely to be of use otherwise. They are all documented here, but without much justification.

    -
    PCRE's 8-BIT, 16-BIT AND 32-BIT LIBRARIES
    +
    INPUT DATA FORMAT
    +

    +Input to pcretest is processed line by line, either by calling the C +library's fgets() function, or via the libreadline library (see +below). In Unix-like environments, fgets() treats any bytes other than +newline as data characters. However, in some Windows environments character 26 +(hex 1A) causes an immediate end of file, and no further data is read. For +maximum portability, therefore, it is safest to use only ASCII characters in +pcretest input files. +

    +
    PCRE's 8-BIT, 16-BIT AND 32-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. From release 8.32, a third -library can be built, supporting character strings encoded in 32-bit units. -The pcretest program can be -used to test all three libraries. However, it is itself still an 8-bit program, -reading 8-bit input and writing 8-bit output. When testing the 16-bit or 32-bit -library, the patterns and data strings are converted to 16- or 32-bit format -before being passed to the PCRE library functions. Results are converted to -8-bit for output. +character strings encoded in 16-bit units. From release 8.32, a third library +can be built, supporting character strings encoded in 32-bit units. The +pcretest program can be used to test all three libraries. However, it is +itself still an 8-bit program, reading 8-bit input and writing 8-bit output. +When testing the 16-bit or 32-bit library, the patterns and data strings are +converted to 16- or 32-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|32]_xx below -mean "pcre_xx when using the 8-bit library or pcre16_xx when using -the 16-bit library". +mean "pcre_xx when using the 8-bit library, pcre16_xx when using +the 16-bit library, or pcre32_xx when using the 32-bit library".

    -
    COMMAND LINE OPTIONS
    +
    COMMAND LINE OPTIONS

    -8 If both the 8-bit library has been built, this option causes the 8-bit library @@ -110,23 +120,30 @@ 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. All other options -are ignored. +about the optional features that are included, and then exit with zero exit +code. 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: +following options output the value and set the exit code as indicated:

       ebcdic-nl  the code for LF (= NL) in an EBCDIC environment:
                    0x15 or 0x25
                    0 if used in an ASCII environment
    -  linksize   the internal link size (2, 3, or 4)
    +               exit code is always 0
    +  linksize   the configured internal link size (2, 3, or 4)
    +               exit code is set to the link size
       newline    the default newline setting:
                    CR, LF, CRLF, ANYCRLF, or ANY
    +               exit code is always 0
    +  bsr        the default setting for what \R matches:
    +               ANYCRLF or ANY
    +               exit code is always 0
     
    -The following options output 1 for true or zero for false: +The following options output 1 for true or 0 for false, and set the exit code +to the same value:
       ebcdic     compiled for an EBCDIC environment
       jit        just-in-time support is available
    @@ -134,8 +151,10 @@ The following options output 1 for true or zero for false:
       pcre32     the 32-bit library was built
       pcre8      the 8-bit library was built
       ucp        Unicode property support is available
    -  utf        UTF-8 and/or UTF-16 and/or UTF-32 support is available
    -
    + utf UTF-8 and/or UTF-16 and/or UTF-32 support + is available +
    +If an unknown option is given, an error message is output; the exit code is 0.

    -d @@ -171,6 +190,11 @@ equivalent to adding /M to each regular expression. The size is given in bytes for both libraries.

    +-O +Behave as if each pattern has the /O modifier, that is disable +auto-possessification for all patterns. +

    +

    -o osize Set the number of elements in the output vector that is used when calling pcre[16|32]_exec() or pcre[16|32]_dfa_exec() to be osize. The @@ -240,20 +264,25 @@ 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 --t, because you will then get the size output a zillion times, and the -timing will be distorted. You can control the number of iterations that are -used for timing by following -t with a number (as a separate item on the -command line). For example, "-t 1000" would iterate 1000 times. The default is -to iterate 500000 times. +Run each compile, study, and match many times with a timer, and output the +resulting times per compile, study, or match (in milliseconds). Do not set +-m with -t, because you will then get the size output a zillion +times, and the timing will be distorted. You can control the number of +iterations that are used for timing by following -t with a number (as a +separate item on the command line). For example, "-t 1000" iterates 1000 times. +The default is to iterate 500000 times.

    -tm This is like -t except that it times only the matching phase, not the compile or study phases.

    -
    DESCRIPTION
    +

    +-T -TM +These behave like -t and -tm, but in addition, at the end of a run, +the total times for all compiles, studies, and matches are output. +

    +
    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 @@ -271,7 +300,7 @@ option states whether or not readline() will be used.

    The program handles any number of sets of input on a single input file. Each set starts with a regular expression, and continues with any number of data -lines to be matched against the pattern. +lines to be matched against that pattern.

    Each data line is matched separately and independently. If you want to do @@ -310,7 +339,7 @@ backslash, because 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, though some of these can be qualified by further characters. @@ -323,6 +352,7 @@ fall into several groups that are described in detail in the following sections.

       /8              set UTF mode
    +  /9              set PCRE_NEVER_UTF (locks out UTF mode)
       /?              disable UTF validity check
       /+              show remainder of subject after match
       /=              show all captures (not just those that are set)
    @@ -344,7 +374,9 @@ sections.
       /M              show compiled memory size
       /m              set PCRE_MULTILINE
       /N              set PCRE_NO_AUTO_CAPTURE
    +  /O              set PCRE_NO_AUTO_POSSESS
       /P              use the POSIX wrapper
    +  /Q              test external stack check function
       /S              study the pattern after compilation
       /s              set PCRE_DOTALL
       /T              select character tables
    @@ -395,12 +427,14 @@ options that do not correspond to anything in Perl:
       /8              PCRE_UTF32          ) when using the 32-bit
       /?              PCRE_NO_UTF32_CHECK )   library
     
    +  /9              PCRE_NEVER_UTF
       /A              PCRE_ANCHORED
       /C              PCRE_AUTO_CALLOUT
       /E              PCRE_DOLLAR_ENDONLY
       /f              PCRE_FIRSTLINE
       /J              PCRE_DUPNAMES
       /N              PCRE_NO_AUTO_CAPTURE
    +  /O              PCRE_NO_AUTO_POSSESS
       /U              PCRE_UNGREEDY
       /W              PCRE_UCP
       /X              PCRE_EXTRA
    @@ -504,7 +538,10 @@ 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[16|32]_fullinfo() after compiling a
    -pattern. If the pattern is studied, the results of that are also output.
    +pattern. If the pattern is studied, the results of that are also output. In
    +this output, the word "char" means a non-UTF character, that is, the value of a
    +single data item (8-bit, 16-bit, or 32-bit, depending on the library that is
    +being tested).
     

    The /K modifier requests pcretest to show names from backtracking @@ -538,14 +575,22 @@ successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the JIT compiled code is also output.

    +The /Q modifier is used to test the use of pcre_stack_guard. It +must be followed by '0' or '1', specifying the return code to be given from an +external function that is passed to PCRE and used for stack checking during +compilation (see the +pcreapi +documentation for details). +

    +

    The /S modifier causes pcre[16|32]_study() to be called after the expression has been compiled, and the results used when the expression is matched. There are a number of qualifying characters that may follow /S. They may appear in any order.

    -If S is followed by an exclamation mark, pcre[16|32]_study() is called -with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a +If /S is followed by an exclamation mark, pcre[16|32]_study() is +called with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a pcre_extra block, even when studying discovers no useful information.

    @@ -624,7 +669,38 @@ function: The /+ modifier works as described above. All other modifiers are ignored.

    -
    DATA LINES
    +
    +Locking out certain modifiers +
    +

    +PCRE can be compiled with or without support for certain features such as +UTF-8/16/32 or Unicode properties. Accordingly, the standard tests are split up +into a number of different files that are selected for running depending on +which features are available. When updating the tests, it is all too easy to +put a new test into the wrong file by mistake; for example, to put a test that +requires UTF support into a file that is used when it is not available. To help +detect such mistakes as early as possible, there is a facility for locking out +specific modifiers. If an input line for pcretest starts with the string +"< forbid " the following sequence of characters is taken as a list of +forbidden modifiers. For example, in the test files that must not use UTF or +Unicode property support, this line appears: +

    +  < forbid 8W
    +
    +This locks out the /8 and /W modifiers. An immediate error is given if they are +subsequently encountered. If the character string contains < but not >, all the +multi-character modifiers that begin with < are locked out. Otherwise, such +modifiers must be explicitly listed, for example: +
    +  < forbid <JS><cr>
    +
    +There must be a single space between < and "forbid" for this feature to be +recognised. If there is not, the line is interpreted either as a request to +re-load a pre-compiled pattern (see "SAVING AND RELOADING COMPILED PATTERNS" +below) or, if there is a another < character, as a pattern that uses < as its +delimiter. +

    +
    DATA LINES

    Before each data line is passed to pcre[16|32]_exec(), leading and trailing white space is removed, and it is then scanned for \ escapes. Some of these @@ -644,6 +720,7 @@ recognized: \v vertical tab (\x0b) \nnn octal character (up to 3 octal digits); always a byte unless > 255 in UTF-8 or 16-bit or 32-bit mode + \o{dd...} octal character (any number of octal digits} \xhh hexadecimal byte (up to 2 hex digits) \x{hh...} hexadecimal character (any number of hex digits) \A pass the PCRE_ANCHORED option to pcre[16|32]_exec() or pcre[16|32]_dfa_exec() @@ -748,7 +825,7 @@ 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 ALTERNATIVE MATCHING FUNCTION
    +
    THE ALTERNATIVE MATCHING FUNCTION

    By default, pcretest uses the standard PCRE matching function, pcre[16|32]_exec() to match each data line. PCRE also supports an @@ -765,7 +842,7 @@ 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[16|32]_exec(), is being used. @@ -856,7 +933,7 @@ prompt is used for continuations), data lines may not. However newlines 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
    +
    OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION

    When the alternative matching function, pcre[16|32]_dfa_exec(), is used (by means of the \D escape sequence or the -dfa command line option), the @@ -892,7 +969,7 @@ at the end of the longest match. For example: 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 @@ -909,7 +986,7 @@ For further information about partial matching, see the 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, @@ -970,7 +1047,7 @@ the 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 @@ -982,7 +1059,7 @@ 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
    +
    SAVING AND RELOADING COMPILED PATTERNS

    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 @@ -1013,10 +1090,9 @@ 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: +name instead of a pattern. There must be no space between < and the file name, +which must not contain a < character, as otherwise pcretest will +interpret the line as a pattern delimited by < characters. For example:

        re> </some/file
       Compiled pattern loaded from /some/file
    @@ -1055,14 +1131,14 @@ string using a reloaded pattern is likely to cause pcretest to crash.
     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), pcre16(3), pcre32(3), pcreapi(3), pcrecallout(3), pcrejit, pcrematching(3), pcrepartial(d), pcrepattern(3), pcreprecompile(3).

    -
    AUTHOR
    +
    AUTHOR

    Philip Hazel
    @@ -1071,11 +1147,11 @@ University Computing Service Cambridge CB2 3QH, England.

    -
    REVISION
    +
    REVISION

    -Last updated: 10 September 2012 +Last updated: 09 February 2014
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2014 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/html/pcreunicode.html b/tools/pcre/doc/html/pcreunicode.html index c3c51eac..ab36bc61 100644 --- a/tools/pcre/doc/html/pcreunicode.html +++ b/tools/pcre/doc/html/pcreunicode.html @@ -85,7 +85,9 @@ 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 the surrogate area and the non-characters. +to U+10FFFF, excluding the surrogate area. (From release 8.33 the so-called +"non-character" code points are no longer excluded because Unicode corrigendum +#9 makes it clear that they should not be.)

    Characters in the "Surrogate Area" of Unicode are reserved for use by UTF-16, @@ -96,10 +98,6 @@ surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8 and UTF-32.)

    -Also excluded are the "Non-Character" code points, which are U+FDD0 to U+FDEF -and the last two code points in each plane, U+??FFFE and U+??FFFF. -

    -

    If an invalid UTF-8 string is passed to PCRE, an error return is given. At compile time, the only additional information is the offset to the first byte of the failing character. The run-time functions pcre_exec() and @@ -135,10 +133,6 @@ U+D800 to U+DFFF are independent code points. Values in the surrogate range must be used in pairs in the correct manner.

    -Excluded are the "Non-Character" code points, which are U+FDD0 to U+FDEF -and the last two code points in each plane, U+??FFFE and U+??FFFF. -

    -

    If an invalid UTF-16 string is passed to PCRE, an error return is given. At compile time, the only additional information is the offset to the first data unit of the failing character. The run-time functions pcre16_exec() and @@ -160,9 +154,7 @@ Validity of UTF-32 strings When you set the PCRE_UTF32 flag, the strings of 32-bit data units that are passed as patterns and subjects are (by default) checked for validity on entry to the relevant functions. This check allows only values in the range U+0 -to U+10FFFF, excluding the surrogate area U+D800 to U+DFFF, and the -"Non-Character" code points, which are U+FDD0 to U+FDEF and the last two -characters in each plane, U+??FFFE and U+??FFFF. +to U+10FFFF, excluding the surrogate area U+D800 to U+DFFF.

    If an invalid UTF-32 string is passed to PCRE, an error return is given. At @@ -261,9 +253,9 @@ Cambridge CB2 3QH, England. REVISION

    -Last updated: 11 November 2012 +Last updated: 27 February 2013
    -Copyright © 1997-2012 University of Cambridge. +Copyright © 1997-2013 University of Cambridge.

    Return to the PCRE index page. diff --git a/tools/pcre/doc/index.html.src b/tools/pcre/doc/index.html.src index c7bc196b..887f4d75 100644 --- a/tools/pcre/doc/index.html.src +++ b/tools/pcre/doc/index.html.src @@ -11,27 +11,29 @@

    Perl-compatible Regular Expressions (PCRE)

    -The HTML documentation for PCRE comprises the following pages: +The HTML documentation for PCRE consists of a number of pages that are listed +below in alphabetical order. If you are new to PCRE, please read the first one +first.

    pcre   Introductory page
    pcre-config  Information about the installation configuration
    pcre16   Discussion of the 16-bit PCRE library
    pcre32   Discussion of the 32-bit PCRE library
    pcre-config  Information about the installation configuration
    pcreapi   PCRE's native API
    pcrebuild  Options for building PCRE
      Building PCRE
    pcrecallout   The callout facility
      Some comments on performance
    pcreposix  The POSIX API to the PCRE library
      The POSIX API to the PCRE 8-bit library
    pcreprecompile   How to save and re-use compiled patterns
      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_free_study  Free study data
    pcre_free_substring   Free extracted substring
    pcre_get_stringnumber   Convert captured string name to number
    pcre_get_stringtable_entries  Find table entries for given string name
    pcre_get_substring   Extract numbered substring into new memory
    pcre_get_substring_list   Extract all substrings into new memory
    pcre_info  Obsolete information extraction function
    pcre_jit_exec  Fast path interface to JIT matching
    pcre_jit_stack_alloc   Create a stack for JIT matching
    + + + - - - - + @@ -67,7 +69,7 @@ The HTML documentation for PCRE comprises the following pages: - + @@ -118,13 +120,13 @@ functions. - - - + + + @@ -140,14 +142,17 @@ functions. + + + - - + + diff --git a/tools/pcre/doc/pcre-config.1 b/tools/pcre/doc/pcre-config.1 index 92a4b58b..52eb4fb2 100644 --- a/tools/pcre/doc/pcre-config.1 +++ b/tools/pcre/doc/pcre-config.1 @@ -4,11 +4,11 @@ pcre-config - program to return PCRE configuration .SH SYNOPSIS .rs .sp +.nf .B pcre-config [--prefix] [--exec-prefix] [--version] [--libs] -.ti +5n -.B [--libs16] [--libs32] [--libs-cpp] [--libs-posix] -.ti +5n -.B [--cflags] [--cflags-posix] +.B " [--libs16] [--libs32] [--libs-cpp] [--libs-posix]" +.B " [--cflags] [--cflags-posix]" +.fi . . .SH DESCRIPTION diff --git a/tools/pcre/doc/pcre-config.txt b/tools/pcre/doc/pcre-config.txt index 3ee9777b..8503ab0e 100644 --- a/tools/pcre/doc/pcre-config.txt +++ b/tools/pcre/doc/pcre-config.txt @@ -1,4 +1,4 @@ -PCRE-CONFIG(1) PCRE-CONFIG(1) +PCRE-CONFIG(1) General Commands Manual PCRE-CONFIG(1) @@ -8,8 +8,8 @@ NAME SYNOPSIS pcre-config [--prefix] [--exec-prefix] [--version] [--libs] - [--libs16] [--libs32] [--libs-cpp] [--libs-posix] - [--cflags] [--cflags-posix] + [--libs16] [--libs32] [--libs-cpp] [--libs-posix] + [--cflags] [--cflags-posix] DESCRIPTION diff --git a/tools/pcre/doc/pcre.3 b/tools/pcre/doc/pcre.3 index 84928f49..4eda404c 100644 --- a/tools/pcre/doc/pcre.3 +++ b/tools/pcre/doc/pcre.3 @@ -1,4 +1,4 @@ -.TH PCRE 3 "11 November 2012" "PCRE 8.32" +.TH PCRE 3 "08 January 2014" "PCRE 8.35" .SH NAME PCRE - Perl-compatible regular expressions .SH INTRODUCTION @@ -19,9 +19,9 @@ built. The majority of the work to make this possible was done by Zoltan Herczeg. .P Starting with release 8.32 it is possible to compile a third separate PCRE -library, which supports 32-bit character strings (including -UTF-32 strings). The build process allows any set of the 8-, 16- and 32-bit -libraries. The work to make this possible was done by Christian Persch. +library that supports 32-bit character strings (including UTF-32 strings). The +build process allows any combination of the 8-, 16- and 32-bit libraries. The +work to make this possible was done by Christian Persch. .P The three libraries contain identical sets of functions, except that the names in the 16-bit library start with \fBpcre16_\fP instead of \fBpcre_\fP, and the @@ -44,7 +44,7 @@ The current implementation of PCRE corresponds approximately with Perl 5.12, including support for UTF-8/16/32 encoded strings and Unicode general category properties. However, UTF-8/16/32 and Unicode support has to be explicitly enabled; it is not the default. The Unicode tables correspond to Unicode -release 6.2.0. +release 6.3.0. .P In addition to the Perl-compatible matching function, PCRE contains an alternative function that matches the same compiled patterns in a different @@ -68,6 +68,7 @@ in the \fIContrib\fP directory at the primary FTP site, which is: .\" HTML .\" ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre +.\" .P Details of exactly which Perl regular expression features are and are not supported by PCRE are given in separate documents. See the @@ -95,8 +96,17 @@ available. The features themselves are described in the \fBpcrebuild\fP .\" page. Documentation about building PCRE for various operating systems can be -found in the \fBREADME\fP and \fBNON-AUTOTOOLS_BUILD\fP files in the source -distribution. +found in the +.\" HTML +.\" +\fBREADME\fP +.\" +and +.\" HTML +.\" +\fBNON-AUTOTOOLS_BUILD\fP +.\" +files in the source distribution. .P 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 @@ -121,8 +131,11 @@ checked for UTF-8 validity. If the data string is very long, such a check might use sufficiently many resources as to cause your application to lose performance. .P -The best way of guarding against this possibility is to use the +One way of guarding against this possibility is to use the \fBpcre_fullinfo()\fP function to check the compiled pattern's options for UTF. +Alternatively, from release 8.33, you can set the PCRE_NEVER_UTF option at +compile time. This causes an compile time error if a pattern contains a +UTF-setting sequence. .P If your application is one that supports UTF, be aware that validity checking can take time. If the same data string is to be matched many times, you can use @@ -145,15 +158,18 @@ page. The user documentation for PCRE comprises a number of different sections. 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 \fBpcredemo\fP section, are concatenated, for ease -of searching. The sections are as follows: +the descriptions of the \fBpcregrep\fP and \fBpcretest\fP programs are in files +called \fBpcregrep.txt\fP and \fBpcretest.txt\fP, respectively. The remaining +sections, except for the \fBpcredemo\fP section (which is a program listing), +are concatenated in \fBpcre.txt\fP, for ease of searching. The sections are as +follows: .sp pcre this document + pcre-config show PCRE installation configuration information pcre16 details of the 16-bit library pcre32 details of the 32-bit library - pcre-config show PCRE installation configuration information pcreapi details of PCRE's native C API - pcrebuild options for building PCRE + pcrebuild building PCRE pcrecallout details of the callout feature pcrecompat discussion of Perl compatibility pcrecpp details of the C++ wrapper for the 8-bit library @@ -175,8 +191,8 @@ of searching. The sections are as follows: pcretest description of the \fBpcretest\fP testing command pcreunicode discussion of Unicode and UTF-8/16/32 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. +In the "man" and HTML formats, there is also a short page for each C library +function, listing its arguments and results. . . .SH AUTHOR @@ -197,6 +213,6 @@ two digits 10, at the domain cam.ac.uk. .rs .sp .nf -Last updated: 11 November 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 08 January 2014 +Copyright (c) 1997-2014 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcre.txt b/tools/pcre/doc/pcre.txt index 2a2a82c7..14cbb8bf 100644 --- a/tools/pcre/doc/pcre.txt +++ b/tools/pcre/doc/pcre.txt @@ -8,13 +8,13 @@ pcretest commands. ----------------------------------------------------------------------------- -PCRE(3) PCRE(3) +PCRE(3) Library Functions Manual PCRE(3) + NAME PCRE - Perl-compatible regular expressions - INTRODUCTION The PCRE library is a set of functions that implement regular expres- @@ -33,110 +33,115 @@ INTRODUCTION possible was done by Zoltan Herczeg. Starting with release 8.32 it is possible to compile a third separate - PCRE library, which supports 32-bit character strings (including UTF-32 - strings). The build process allows any set of the 8-, 16- and 32-bit - libraries. The work to make this possible was done by Christian Persch. + PCRE library that supports 32-bit character strings (including UTF-32 + strings). The build process allows any combination of the 8-, 16- and + 32-bit libraries. The work to make this possible was done by Christian + Persch. - The three libraries contain identical sets of functions, except that - the names in the 16-bit library start with pcre16_ instead of pcre_, - and the names in the 32-bit library start with pcre32_ instead of - pcre_. To avoid over-complication and reduce the documentation mainte- + The three libraries contain identical sets of functions, except that + the names in the 16-bit library start with pcre16_ instead of pcre_, + and the names in the 32-bit library start with pcre32_ instead of + pcre_. To avoid over-complication and reduce the documentation mainte- nance load, most of the documentation describes the 8-bit library, with - the differences for the 16-bit and 32-bit libraries described sepa- - rately in the pcre16 and pcre32 pages. References to functions or - structures of the form pcre[16|32]_xxx should be read as meaning - "pcre_xxx when using the 8-bit library, pcre16_xxx when using the + the differences for the 16-bit and 32-bit libraries described sepa- + rately in the pcre16 and pcre32 pages. References to functions or + structures of the form pcre[16|32]_xxx should be read as meaning + "pcre_xxx when using the 8-bit library, pcre16_xxx when using the 16-bit library, or pcre32_xxx when using the 32-bit library". - The current implementation of PCRE corresponds approximately with Perl - 5.12, including support for UTF-8/16/32 encoded strings and Unicode - general category properties. However, UTF-8/16/32 and Unicode support + The current implementation of PCRE corresponds approximately with Perl + 5.12, including support for UTF-8/16/32 encoded strings and Unicode + general category properties. However, UTF-8/16/32 and Unicode support has to be explicitly enabled; it is not the default. The Unicode tables - correspond to Unicode release 6.2.0. + correspond to Unicode release 6.3.0. - In addition to the Perl-compatible matching function, PCRE contains an - alternative function that matches the same compiled patterns in a dif- + In addition to the Perl-compatible matching function, PCRE contains an + alternative function that matches the same compiled patterns in a dif- ferent way. In certain circumstances, the alternative function has some - advantages. For a discussion of the two matching algorithms, see the + advantages. For a discussion of the two matching algorithms, see the pcrematching page. - PCRE is written in C and released as a C library. A number of people - have written wrappers and interfaces of various kinds. In particular, - Google Inc. have provided a comprehensive C++ wrapper for the 8-bit - library. This is now included as part of the PCRE distribution. The - pcrecpp page has details of this interface. Other people's contribu- - tions can be found in the Contrib directory at the primary FTP site, + PCRE is written in C and released as a C library. A number of people + have written wrappers and interfaces of various kinds. In particular, + Google Inc. have provided a comprehensive C++ wrapper for the 8-bit + library. This is now included as part of the PCRE distribution. The + pcrecpp page has details of this interface. Other people's contribu- + tions can be found in the Contrib directory at the primary FTP site, which is: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre - Details of exactly which Perl regular expression features are and are + Details of exactly which Perl regular expression features are and are not supported by PCRE are given in separate documents. See the pcrepat- - tern and pcrecompat pages. There is a syntax summary in the pcresyntax + tern and pcrecompat pages. There is a syntax summary in the pcresyntax page. - Some features of PCRE can be included, excluded, or changed when the - library is built. The pcre_config() function makes it possible for a - client to discover which features are available. The features them- - selves are described in the pcrebuild page. Documentation about build- - ing PCRE for various operating systems can be found in the README and + Some features of PCRE can be included, excluded, or changed when the + library is built. The pcre_config() function makes it possible for a + client to discover which features are available. The features them- + selves are described in the pcrebuild page. Documentation about build- + ing PCRE for various operating systems can be found in the README and NON-AUTOTOOLS_BUILD files in the source distribution. - The libraries contains a number of undocumented internal functions and - data tables that are used by more than one of the exported external - functions, but which are not intended for use by external callers. - Their names all begin with "_pcre_" or "_pcre16_" or "_pcre32_", which - hopefully will not provoke any name clashes. In some environments, it - is possible to control which external symbols are exported when a - shared library is built, and in these cases the undocumented symbols + The libraries contains a number of undocumented internal functions and + data tables that are used by more than one of the exported external + functions, but which are not intended for use by external callers. + Their names all begin with "_pcre_" or "_pcre16_" or "_pcre32_", which + hopefully will not provoke any name clashes. In some environments, it + is possible to control which external symbols are exported when a + shared library is built, and in these cases the undocumented symbols are not exported. SECURITY CONSIDERATIONS - If you are using PCRE in a non-UTF application that permits users to - supply arbitrary patterns for compilation, you should be aware of a + If you are using PCRE in a non-UTF application that permits users to + supply arbitrary patterns for compilation, you should be aware of a feature that allows users to turn on UTF support from within a pattern, - provided that PCRE was built with UTF support. For example, an 8-bit - pattern that begins with "(*UTF8)" or "(*UTF)" turns on UTF-8 mode, - which interprets patterns and subjects as strings of UTF-8 characters - instead of individual 8-bit characters. This causes both the pattern + provided that PCRE was built with UTF support. For example, an 8-bit + pattern that begins with "(*UTF8)" or "(*UTF)" turns on UTF-8 mode, + which interprets patterns and subjects as strings of UTF-8 characters + instead of individual 8-bit characters. This causes both the pattern and any data against which it is matched to be checked for UTF-8 valid- - ity. If the data string is very long, such a check might use suffi- - ciently many resources as to cause your application to lose perfor- + ity. If the data string is very long, such a check might use suffi- + ciently many resources as to cause your application to lose perfor- mance. - The best way of guarding against this possibility is to use the - pcre_fullinfo() function to check the compiled pattern's options for - UTF. + One way of guarding against this possibility is to use the + pcre_fullinfo() function to check the compiled pattern's options for + UTF. Alternatively, from release 8.33, you can set the PCRE_NEVER_UTF + option at compile time. This causes an compile time error if a pattern + contains a UTF-setting sequence. - If your application is one that supports UTF, be aware that validity - checking can take time. If the same data string is to be matched many + If your application is one that supports UTF, be aware that validity + checking can take time. If the same data string is to be matched many times, you can use the PCRE_NO_UTF[8|16|32]_CHECK option for the second and subsequent matches to save redundant checks. - Another way that performance can be hit is by running a pattern that - has a very large search tree against a string that will never match. - Nested unlimited repeats in a pattern are a common example. PCRE pro- + Another way that performance can be hit is by running a pattern that + has a very large search tree against a string that will never match. + Nested unlimited repeats in a pattern are a common example. PCRE pro- vides some protection against this: see the PCRE_EXTRA_MATCH_LIMIT fea- ture in the pcreapi page. USER DOCUMENTATION - The user documentation for PCRE comprises a number of different sec- - tions. In the "man" format, each of these is a separate "man page". In - the HTML format, each is a separate page, linked from the index page. - In the plain text format, all the sections, except the pcredemo sec- - tion, are concatenated, for ease of searching. The sections are as fol- - lows: + 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, the descriptions of the pcregrep and pcretest + programs are in files called pcregrep.txt and pcretest.txt, respec- + tively. The remaining sections, except for the pcredemo section (which + is a program listing), are concatenated in pcre.txt, for ease of + searching. The sections are as follows: pcre this document + pcre-config show PCRE installation configuration information pcre16 details of the 16-bit library pcre32 details of the 32-bit library - pcre-config show PCRE installation configuration information pcreapi details of PCRE's native C API - pcrebuild options for building PCRE + pcrebuild building PCRE pcrecallout details of the callout feature pcrecompat discussion of Perl compatibility pcrecpp details of the C++ wrapper for the 8-bit library @@ -157,8 +162,8 @@ USER DOCUMENTATION pcretest description of the pcretest testing command pcreunicode discussion of Unicode and UTF-8/16/32 support - In addition, in the "man" and HTML formats, there is a short page for - each C library function, listing its arguments and results. + In the "man" and HTML formats, there is also a short page for each C + library function, listing its arguments and results. AUTHOR @@ -167,19 +172,20 @@ AUTHOR University Computing Service Cambridge CB2 3QH, England. - Putting an actual email address here seems to have been a spam magnet, - so I've taken it away. If you want to email me, use my two initials, + Putting an actual email address here seems to have been a spam magnet, + so I've taken it away. If you want to email me, use my two initials, followed by the two digits 10, at the domain cam.ac.uk. REVISION - Last updated: 11 November 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 08 January 2014 + Copyright (c) 1997-2014 University of Cambridge. ------------------------------------------------------------------------------ -PCRE(3) PCRE(3) +PCRE(3) Library Functions Manual PCRE(3) + NAME @@ -389,8 +395,10 @@ STRUCTURE TYPES SUBJECT STRING OFFSETS - The offsets within subject strings that are returned by the matching - functions are in 16-bit units rather than bytes. + The lengths and starting offsets of subject strings must be specified + in 16-bit data units, and the offsets within subject strings that are + returned by the matching functions are in also 16-bit units rather than + bytes. NAMED SUBPATTERNS @@ -503,12 +511,13 @@ AUTHOR REVISION - Last updated: 08 November 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 12 May 2013 + Copyright (c) 1997-2013 University of Cambridge. ------------------------------------------------------------------------------ -PCRE(3) PCRE(3) +PCRE(3) Library Functions Manual PCRE(3) + NAME @@ -525,7 +534,6 @@ PCRE 32-BIT API BASIC FUNCTIONS pcre32 *pcre32_compile2(PCRE_SPTR32 pattern, int options, int *errorcodeptr, - const char **errptr, int *erroffset, const unsigned char *tableptr); pcre32_extra *pcre32_study(const pcre32 *code, int options, @@ -718,8 +726,10 @@ STRUCTURE TYPES SUBJECT STRING OFFSETS - The offsets within subject strings that are returned by the matching - functions are in 32-bit units rather than bytes. + The lengths and starting offsets of subject strings must be specified + in 32-bit data units, and the offsets within subject strings that are + returned by the matching functions are in also 32-bit units rather than + bytes. NAMED SUBPATTERNS @@ -829,33 +839,46 @@ AUTHOR REVISION - Last updated: 08 November 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 12 May 2013 + Copyright (c) 1997-2013 University of Cambridge. ------------------------------------------------------------------------------ -PCREBUILD(3) PCREBUILD(3) +PCREBUILD(3) Library Functions Manual PCREBUILD(3) + NAME PCRE - Perl-compatible regular expressions +BUILDING PCRE + + PCRE is distributed with a configure script that can be used to build + the library in Unix-like environments using the applications known as + Autotools. Also in the distribution are files to support building + using CMake instead of configure. The text file README contains general + information about building with Autotools (some of which is repeated + below), and also has some comments about building on various operating + systems. There is a lot more information about building PCRE without + using Autotools (including information about using CMake and building + "by hand") in the text file called NON-AUTOTOOLS-BUILD. You should + consult this file as well as the README file if you are building in a + non-Unix-like environment. + PCRE BUILD-TIME OPTIONS - This document describes the optional features of PCRE that can be - selected when the library is compiled. It assumes use of the configure - script, where the optional features are selected or deselected by pro- - viding options to configure before running the make command. However, - the same options can be selected in both Unix-like and non-Unix-like - environments using the GUI facility of cmake-gui if you are using CMake - instead of configure to build PCRE. + The rest of this document describes the optional features of PCRE that + can be selected when the library is compiled. It assumes use of the + configure script, where the optional features are selected or dese- + lected by providing options to configure before running the make com- + mand. However, the same options can be selected in both Unix-like and + non-Unix-like environments using the GUI facility of cmake-gui if you + are using CMake instead of configure to build PCRE. - There is a lot more information about building PCRE without using con- - figure (including information about using CMake or building "by hand") - in the file called NON-AUTOTOOLS-BUILD, which is part of the PCRE dis- - tribution. You should consult this file as well as the README file if - you are building in a non-Unix-like environment. + If you are not using Autotools or CMake, option selection can be done + by editing the config.h file, or by passing parameter settings to the + compiler, as described in NON-AUTOTOOLS-BUILD. The complete list of options for configure (which includes the standard ones such as the selection of the installation directory) can be @@ -882,10 +905,10 @@ BUILDING 8-BIT, 16-BIT AND 32-BIT LIBRARIES --enable-pcre16 - to the configure command. You can also build a separate library, called - libpcre32, in which strings are contained in vectors of 32-bit data - units and interpreted either as single-unit characters or UTF-32 - strings, by adding + to the configure command. You can also build yet another separate + library, called libpcre32, in which strings are contained in vectors of + 32-bit data units and interpreted either as single-unit characters or + UTF-32 strings, by adding --enable-pcre32 @@ -901,9 +924,9 @@ BUILDING 8-BIT, 16-BIT AND 32-BIT LIBRARIES BUILDING SHARED AND STATIC LIBRARIES - The PCRE building process uses libtool to build both shared and static - Unix libraries by default. You can suppress one of these by adding one - of + The Autotools PCRE building process uses libtool to build both shared + and static libraries by default. You can suppress one of these by + adding one of --disable-shared --disable-static @@ -1319,18 +1342,18 @@ AUTHOR REVISION - Last updated: 30 October 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 12 May 2013 + Copyright (c) 1997-2013 University of Cambridge. ------------------------------------------------------------------------------ -PCREMATCHING(3) PCREMATCHING(3) +PCREMATCHING(3) Library Functions Manual PCREMATCHING(3) + NAME PCRE - Perl-compatible regular expressions - PCRE MATCHING ALGORITHMS This document describes the two different algorithms that are available @@ -1436,72 +1459,81 @@ THE ALTERNATIVE MATCHING ALGORITHM at the fifth character of the subject. The algorithm does not automati- cally move on to find matches that start at later positions. + PCRE's "auto-possessification" optimization usually applies to charac- + ter repeats at the end of a pattern (as well as internally). For exam- + ple, the pattern "a\d+" is compiled as if it were "a\d++" because there + is no point even considering the possibility of backtracking into the + repeated digits. For DFA matching, this means that only one possible + match is found. If you really do want multiple matches in such cases, + either use an ungreedy repeat ("a\d+?") or set the PCRE_NO_AUTO_POSSESS + option when compiling. + There are a number of features of PCRE regular expressions that are not supported by the alternative matching algorithm. They are as follows: - 1. Because the algorithm finds all possible matches, the greedy or - ungreedy nature of repetition quantifiers is not relevant. Greedy and + 1. Because the algorithm finds all possible matches, the greedy or + ungreedy nature of repetition quantifiers is not relevant. Greedy and ungreedy quantifiers are treated in exactly the same way. However, pos- - sessive quantifiers can make a difference when what follows could also + sessive quantifiers can make a difference when what follows could also match what is quantified, for example in a pattern like this: ^a++\w! - This pattern matches "aaab!" but not "aaa!", which would be matched by - a non-possessive quantifier. Similarly, if an atomic group is present, - it is matched as if it were a standalone pattern at the current point, - and the longest match is then "locked in" for the rest of the overall + This pattern matches "aaab!" but not "aaa!", which would be matched by + a non-possessive quantifier. Similarly, if an atomic group is present, + it is matched as if it were a standalone pattern at the current point, + and the longest match is then "locked in" for the rest of the overall pattern. 2. When dealing with multiple paths through the tree simultaneously, it - is not straightforward to keep track of captured substrings for the - different matching possibilities, and PCRE's implementation of this + is not straightforward to keep track of captured substrings for the + different matching possibilities, and PCRE's implementation of this algorithm does not attempt to do this. This means that no captured sub- strings are available. - 3. Because no substrings are captured, back references within the pat- + 3. Because no substrings are captured, back references within the pat- tern are not supported, and cause errors if encountered. - 4. For the same reason, conditional expressions that use a backrefer- - ence as the condition or test for a specific group recursion are not + 4. For the same reason, conditional expressions that use a backrefer- + ence as the condition or test for a specific group recursion are not supported. - 5. Because many paths through the tree may be active, the \K escape + 5. Because many paths through the tree may be active, the \K escape sequence, which resets the start of the match when encountered (but may - be on some paths and not on others), is not supported. It causes an + be on some paths and not on others), is not supported. It causes an error if encountered. - 6. Callouts are supported, but the value of the capture_top field is + 6. Callouts are supported, but the value of the capture_top field is always 1, and the value of the capture_last field is always -1. - 7. The \C escape sequence, which (in the standard algorithm) always - matches a single data unit, even in UTF-8, UTF-16 or UTF-32 modes, is - not supported in these modes, because the alternative algorithm moves + 7. The \C escape sequence, which (in the standard algorithm) always + matches a single data unit, even in UTF-8, UTF-16 or UTF-32 modes, is + not supported in these modes, because the alternative algorithm moves through the subject string one character (not data unit) at a time, for all active paths through the tree. - 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) - are not supported. (*FAIL) is supported, and behaves like a failing + 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) + are not supported. (*FAIL) is supported, and behaves like a failing negative assertion. ADVANTAGES OF THE ALTERNATIVE ALGORITHM - Using the alternative matching algorithm provides the following advan- + Using the alternative matching algorithm provides the following advan- tages: 1. All possible matches (at a single point in the subject) are automat- - ically found, and in particular, the longest match is found. To find + ically found, and in particular, the longest match is found. To find more than one match using the standard algorithm, you have to do kludgy things with callouts. - 2. Because the alternative algorithm scans the subject string just + 2. Because the alternative algorithm scans the subject string just once, and never needs to backtrack (except for lookbehinds), it is pos- - sible to pass very long subject strings to the matching function in + sible to pass very long subject strings to the matching function in several pieces, checking for partial matching each time. Although it is - possible to do multi-segment matching using the standard algorithm by - retaining partially matched substrings, it is more complicated. The - pcrepartial documentation gives details of partial matching and dis- + possible to do multi-segment matching using the standard algorithm by + retaining partially matched substrings, it is more complicated. The + pcrepartial documentation gives details of partial matching and dis- cusses multi-segment matching. @@ -1509,8 +1541,8 @@ DISADVANTAGES OF THE ALTERNATIVE ALGORITHM The alternative algorithm suffers from a number of disadvantages: - 1. It is substantially slower than the standard algorithm. This is - partly because it has to search for all possible matches, but is also + 1. It is substantially slower than the standard algorithm. This is + partly because it has to search for all possible matches, but is also because it is less susceptible to optimization. 2. Capturing parentheses and back references are not supported. @@ -1528,12 +1560,13 @@ AUTHOR REVISION - Last updated: 08 January 2012 + Last updated: 12 November 2013 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ -PCREAPI(3) PCREAPI(3) +PCREAPI(3) Library Functions Manual PCREAPI(3) + NAME @@ -1643,6 +1676,8 @@ PCRE NATIVE API INDIRECTED FUNCTIONS int (*pcre_callout)(pcre_callout_block *); + int (*pcre_stack_guard)(void); + PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES @@ -1663,68 +1698,67 @@ PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES ues. References to bytes and UTF-8 in this document should be read as refer- - ences to 16-bit data quantities and UTF-16 when using the 16-bit - library, or 32-bit data quantities and UTF-32 when using the 32-bit - library, unless specified otherwise. More details of the specific dif- - ferences for the 16-bit and 32-bit libraries are given in the pcre16 - and pcre32 pages. + ences to 16-bit data units and UTF-16 when using the 16-bit library, or + 32-bit data units and UTF-32 when using the 32-bit library, unless + specified otherwise. More details of the specific differences for the + 16-bit and 32-bit libraries are given in the pcre16 and pcre32 pages. PCRE API OVERVIEW PCRE has its own native API, which is described in this document. There - are also some wrapper functions (for the 8-bit library only) that cor- - respond to the POSIX regular expression API, but they do not give - access to all the functionality. They are described in the pcreposix - documentation. Both of these APIs define a set of C function calls. A + are also some wrapper functions (for the 8-bit library only) that cor- + respond to the POSIX regular expression API, but they do not give + access to all the functionality. They are described in the pcreposix + documentation. Both of these APIs define a set of C function calls. A C++ wrapper (again for the 8-bit library only) is also distributed with PCRE. It is documented in the pcrecpp page. - The native API C function prototypes are defined in the header file - pcre.h, and on Unix-like systems the (8-bit) library itself is called - libpcre. It can normally be accessed by adding -lpcre to the command - for linking an application that uses PCRE. The header file defines the + The native API C function prototypes are defined in the header file + pcre.h, and on Unix-like systems the (8-bit) library itself is called + libpcre. It can normally be accessed by adding -lpcre to the command + for linking an application that uses PCRE. The header file defines the macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release - numbers for the library. Applications can use these to include support + numbers for the library. Applications can use these to include support for different releases of PCRE. In a Windows environment, if you want to statically link an application - program against a non-dll pcre.a file, you must define PCRE_STATIC - before including pcre.h or pcrecpp.h, because otherwise the pcre_mal- + program against a non-dll pcre.a file, you must define PCRE_STATIC + before including pcre.h or pcrecpp.h, because otherwise the pcre_mal- loc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results. - The functions pcre_compile(), pcre_compile2(), pcre_study(), and - pcre_exec() are used for compiling and matching regular expressions in - a Perl-compatible manner. A sample program that demonstrates the sim- - plest way of using them is provided in the file called pcredemo.c in + The functions pcre_compile(), pcre_compile2(), pcre_study(), and + pcre_exec() are used for compiling and matching regular expressions in + a Perl-compatible manner. A sample program that demonstrates the sim- + plest way of using them is provided in the file called pcredemo.c in the PCRE source distribution. A listing of this program is given in the - pcredemo documentation, and the pcresample documentation describes how + pcredemo documentation, and the pcresample documentation describes how to compile and run it. - Just-in-time compiler support is an optional feature of PCRE that can + Just-in-time compiler support is an optional feature of PCRE that can be built in appropriate hardware environments. It greatly speeds up the - matching performance of many patterns. Simple programs can easily - request that it be used if available, by setting an option that is - ignored when it is not relevant. More complicated programs might need - to make use of the functions pcre_jit_stack_alloc(), - pcre_jit_stack_free(), and pcre_assign_jit_stack() in order to control + matching performance of many patterns. Simple programs can easily + request that it be used if available, by setting an option that is + ignored when it is not relevant. More complicated programs might need + to make use of the functions pcre_jit_stack_alloc(), + pcre_jit_stack_free(), and pcre_assign_jit_stack() in order to control the JIT code's memory usage. - From release 8.32 there is also a direct interface for JIT execution, - which gives improved performance. The JIT-specific functions are dis- + From release 8.32 there is also a direct interface for JIT execution, + which gives improved performance. The JIT-specific functions are dis- cussed in the pcrejit documentation. A second matching function, pcre_dfa_exec(), which is not Perl-compati- - ble, is also provided. This uses a different algorithm for the match- - ing. The alternative algorithm finds all possible matches (at a given - point in the subject), and scans the subject just once (unless there - are lookbehind assertions). However, this algorithm does not return - captured substrings. A description of the two matching algorithms and - their advantages and disadvantages is given in the pcrematching docu- + ble, is also provided. This uses a different algorithm for the match- + ing. The alternative algorithm finds all possible matches (at a given + point in the subject), and scans the subject just once (unless there + are lookbehind assertions). However, this algorithm does not return + captured substrings. A description of the two matching algorithms and + their advantages and disadvantages is given in the pcrematching docu- mentation. - In addition to the main compiling and matching functions, there are + In addition to the main compiling and matching functions, there are convenience functions for extracting captured substrings from a subject string that is matched by pcre_exec(). They are: @@ -1739,87 +1773,96 @@ PCRE API OVERVIEW pcre_free_substring() and pcre_free_substring_list() are also provided, to free the memory used for extracted strings. - The function pcre_maketables() is used to build a set of character - tables in the current locale for passing to pcre_compile(), - pcre_exec(), or pcre_dfa_exec(). This is an optional facility that is - provided for specialist use. Most commonly, no special tables are - passed, in which case internal tables that are generated when PCRE is + The function pcre_maketables() is used to build a set of character + tables in the current locale for passing to pcre_compile(), + pcre_exec(), or pcre_dfa_exec(). This is an optional facility that is + provided for specialist use. Most commonly, no special tables are + passed, in which case internal tables that are generated when PCRE is built are used. - The function pcre_fullinfo() is used to find out information about a - compiled pattern. The function pcre_version() returns a pointer to a + The function pcre_fullinfo() is used to find out information about a + compiled pattern. The function pcre_version() returns a pointer to a string containing the version of PCRE and its date of release. - The function pcre_refcount() maintains a reference count in a data - block containing a compiled pattern. This is provided for the benefit + The function pcre_refcount() maintains a reference count in a data + block containing a compiled pattern. This is provided for the benefit of object-oriented applications. - The global variables pcre_malloc and pcre_free initially contain the - entry points of the standard malloc() and free() functions, respec- + The global variables pcre_malloc and pcre_free initially contain the + entry points of the standard malloc() and free() functions, respec- tively. PCRE calls the memory management functions via these variables, - so a calling program can replace them if it wishes to intercept the + so a calling program can replace them if it wishes to intercept the calls. This should be done before calling any PCRE functions. - The global variables pcre_stack_malloc and pcre_stack_free are also - indirections to memory management functions. These special functions - are used only when PCRE is compiled to use the heap for remembering + The global variables pcre_stack_malloc and pcre_stack_free are also + indirections to memory management functions. These special functions + are used only when PCRE is compiled to use the heap for remembering data, instead of recursive function calls, when running the pcre_exec() - function. See the pcrebuild documentation for details of how to do - this. It is a non-standard way of building PCRE, for use in environ- - ments that have limited stacks. Because of the greater use of memory - management, it runs more slowly. Separate functions are provided so - that special-purpose external code can be used for this case. When - used, these functions are always called in a stack-like manner (last - obtained, first freed), and always for memory blocks of the same size. - There is a discussion about PCRE's stack usage in the pcrestack docu- + function. See the pcrebuild documentation for details of how to do + this. It is a non-standard way of building PCRE, for use in environ- + ments that have limited stacks. Because of the greater use of memory + management, it runs more slowly. Separate functions are provided so + that special-purpose external code can be used for this case. When + used, these functions are always called in a stack-like manner (last + obtained, first freed), and always for memory blocks of the same size. + There is a discussion about PCRE's stack usage in the pcrestack docu- mentation. The global variable pcre_callout initially contains NULL. It can be set - by the caller to a "callout" function, which PCRE will then call at - specified points during a matching operation. Details are given in the + by the caller to a "callout" function, which PCRE will then call at + specified points during a matching operation. Details are given in the pcrecallout documentation. + The global variable pcre_stack_guard initially contains NULL. It can be + set by the caller to a function that is called by PCRE whenever it + starts to compile a parenthesized part of a pattern. When parentheses + are nested, PCRE uses recursive function calls, which use up the system + stack. This function is provided so that applications with restricted + stacks can force a compilation error if the stack runs out. The func- + tion should return zero if all is well, or non-zero to force an error. + NEWLINES - PCRE supports five different conventions for indicating line breaks in - strings: a single CR (carriage return) character, a single LF (line- + PCRE supports five different conventions for indicating line breaks in + strings: a single CR (carriage return) character, a single LF (line- feed) character, the two-character sequence CRLF, any of the three pre- - ceding, or any Unicode newline sequence. The Unicode newline sequences - are the three just mentioned, plus the single characters VT (vertical + ceding, or any Unicode newline sequence. The Unicode newline sequences + are the three just mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). - Each of the first three conventions is used by at least one operating - system as its standard newline sequence. When PCRE is built, a default - can be specified. The default default is LF, which is the Unix stan- - dard. When PCRE is run, the default can be overridden, either when a + Each of the first three conventions is used by at least one operating + system as its standard newline sequence. When PCRE is built, a default + can be specified. The default default is LF, which is the Unix stan- + dard. When PCRE is run, the default can be overridden, either when a pattern is compiled, or when it is matched. At compile time, the newline convention can be specified by the options - argument of pcre_compile(), or it can be specified by special text at + argument of pcre_compile(), or it can be specified by special text at the start of the pattern itself; this overrides any other settings. See the pcrepattern page for details of the special character sequences. In the PCRE documentation the word "newline" is used to mean "the char- - acter or pair of characters that indicate a line break". The choice of - newline convention affects the handling of the dot, circumflex, and + acter or pair of characters that indicate a line break". The choice of + newline convention affects the handling of the dot, circumflex, and dollar metacharacters, the handling of #-comments in /x mode, and, when - CRLF is a recognized line ending sequence, the match position advance- + CRLF is a recognized line ending sequence, the match position advance- ment for a non-anchored pattern. There is more detail about this in the section on pcre_exec() options below. - The choice of newline convention does not affect the interpretation of - the \n or \r escape sequences, nor does it affect what \R matches, + The choice of newline convention does not affect the interpretation of + the \n or \r escape sequences, nor does it affect what \R matches, which is controlled in a similar way, but by separate options. MULTITHREADING - The PCRE functions can be used in multi-threading applications, with + The PCRE functions can be used in multi-threading applications, with the proviso that the memory management functions pointed to by pcre_malloc, pcre_free, pcre_stack_malloc, and pcre_stack_free, and the - callout function pointed to by pcre_callout, are shared by all threads. + callout and stack-checking functions pointed to by pcre_callout and + pcre_stack_guard, are shared by all threads. 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 @@ -1936,6 +1979,16 @@ CHECKING BUILD-TIME OPTIONS POSIX interface uses malloc() for output vectors. Further details are given in the pcreposix documentation. + PCRE_CONFIG_PARENS_LIMIT + + The output is a long integer that gives the maximum depth of nesting of + parentheses (of any kind) in a pattern. This limit is imposed to cap + the amount of system stack used when a pattern is compiled. It is spec- + ified when PCRE is built; the default is 250. This limit does not take + into account the stack that may already be used by the calling applica- + tion. For finer control over compilation stack usage, you can set a + pointer to an external checking function in pcre_stack_guard. + PCRE_CONFIG_MATCH_LIMIT The output is a long integer that gives the default limit for the num- @@ -2008,15 +2061,17 @@ COMPILING A PATTERN sets the variable pointed to by errptr to point to a textual error mes- sage. This is a static string that is part of the library. You must not try to free it. Normally, the offset from the start of the pattern to - the byte that was being processed when the error was discovered is + the data unit that was being processed when the error was discovered is placed in the variable pointed to by erroffset, which must not be NULL (if it is, an immediate error is given). However, for an invalid UTF-8 - string, the offset is that of the first byte of the failing character. + or UTF-16 string, the offset is that of the first data unit of the + failing character. - Some errors are not detected until the whole pattern has been scanned; - in these cases, the offset passed back is the length of the pattern. - Note that the offset is in bytes, not characters, even in UTF-8 mode. - It may sometimes point into the middle of a UTF-8 character. + Some errors are not detected until the whole pattern has been scanned; + in these cases, the offset passed back is the length of the pattern. + Note that the offset is in data units, not characters, even in a UTF + mode. It may sometimes point into the middle of a UTF-8 or UTF-16 char- + acter. If pcre_compile2() is used instead of pcre_compile(), and the error- codeptr argument is not NULL, a non-zero error code number is returned @@ -2027,9 +2082,9 @@ COMPILING A PATTERN character tables that are built when PCRE is compiled, using the default C locale. Otherwise, tableptr must be an address that is the result of a call to pcre_maketables(). This value is stored with the - compiled pattern, and used again by pcre_exec(), unless another table - pointer is passed to it. For more discussion, see the section on locale - support below. + compiled pattern, and used again by pcre_exec() and pcre_dfa_exec() + when the pattern is matched. For more discussion, see the section on + locale support below. This code fragment shows a typical straightforward call to pcre_com- pile(): @@ -2113,13 +2168,23 @@ COMPILING A PATTERN PCRE_EXTENDED - If this bit is set, white space data characters in the pattern are - totally ignored except when escaped or inside a character class. White - space does not include the VT character (code 11). In addition, charac- - ters between an unescaped # outside a character class and the next new- - line, inclusive, are also ignored. This is equivalent to Perl's /x - option, and it can be changed within a pattern by a (?x) option set- - ting. + If this bit is set, most white space characters in the pattern are + totally ignored except when escaped or inside a character class. How- + ever, white space is not allowed within sequences such as (?> that + introduce various parenthesized subpatterns, nor within a numerical + quantifier such as {1,3}. However, ignorable white space is permitted + between an item and a following quantifier and between a quantifier and + a following + that indicates possessiveness. + + White space did not used to include the VT character (code 11), because + Perl did not treat this character as white space. However, Perl changed + at release 5.18, so PCRE followed at release 8.34, and VT is now + treated as white space. + + PCRE_EXTENDED also causes characters between an unescaped # outside a + character class and the next newline, inclusive, to be ignored. + PCRE_EXTENDED is equivalent to Perl's /x option, and it can be changed + within a pattern by a (?x) option setting. Which characters are interpreted as newlines is controlled by the options passed to pcre_compile() or by a special sequence at the start @@ -2186,21 +2251,33 @@ COMPILING A PATTERN PCRE_MULTILINE - By default, PCRE treats the subject string as consisting of a single - line of characters (even if it actually contains newlines). The "start - of line" metacharacter (^) matches only at the start of the string, - while the "end of line" metacharacter ($) matches only at the end of - the string, or before a terminating newline (unless PCRE_DOLLAR_ENDONLY - is set). This is the same as Perl. + By default, for the purposes of matching "start of line" and "end of + line", PCRE treats the subject string as consisting of a single line of + characters, even if it actually contains newlines. The "start of line" + metacharacter (^) matches only at the start of the string, and the "end + of line" metacharacter ($) matches only at the end of the string, or + before a terminating newline (except when PCRE_DOLLAR_ENDONLY is set). + Note, however, that unless PCRE_DOTALL is set, the "any character" + metacharacter (.) does not match at a newline. This behaviour (for ^, + $, and dot) is the same as Perl. - When PCRE_MULTILINE it is set, the "start of line" and "end of line" - constructs match immediately following or immediately before internal - newlines in the subject string, respectively, as well as at the very - start and end. This is equivalent to Perl's /m option, and it can be + When PCRE_MULTILINE it is set, the "start of line" and "end of line" + constructs match immediately following or immediately before internal + newlines in the subject string, respectively, as well as at the very + start and end. This is equivalent to Perl's /m option, and it can be changed within a pattern by a (?m) option setting. If there are no new- - lines in a subject string, or no occurrences of ^ or $ in a pattern, + lines in a subject string, or no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no effect. + PCRE_NEVER_UTF + + This option locks out interpretation of the pattern as UTF-8 (or UTF-16 + or UTF-32 in the 16-bit and 32-bit libraries). In particular, it pre- + vents the creator of the pattern from switching to UTF interpretation + by starting the pattern with (*UTF). This may be useful in applications + that process patterns from external sources. The combination of + PCRE_UTF8 and PCRE_NEVER_UTF also causes an error. + PCRE_NEWLINE_CR PCRE_NEWLINE_LF PCRE_NEWLINE_CRLF @@ -2255,63 +2332,74 @@ COMPILING A PATTERN be used for capturing (and they acquire numbers in the usual way). There is no equivalent of this option in Perl. - NO_START_OPTIMIZE + PCRE_NO_AUTO_POSSESS + + If this option is set, it disables "auto-possessification". This is an + optimization that, for example, turns a+b into a++b in order to avoid + backtracks into a+ that can never be successful. However, if callouts + are in use, auto-possessification means that some of them are never + taken. You can set this option if you want the matching functions to do + a full unoptimized search and run all the callouts, but it is mainly + provided for testing purposes. + + PCRE_NO_START_OPTIMIZE This is an option that acts at matching time; that is, it is really an option for pcre_exec() or pcre_dfa_exec(). If it is set at compile time, it is remembered with the compiled pattern and assumed at match- - ing time. For details see the discussion of PCRE_NO_START_OPTIMIZE - below. + ing time. This is necessary if you want to use JIT execution, because + the JIT compiler needs to know whether or not this option is set. For + details see the discussion of PCRE_NO_START_OPTIMIZE below. PCRE_UCP - This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W, - \w, and some of the POSIX character classes. By default, only ASCII - characters are recognized, but if PCRE_UCP is set, Unicode properties - are used instead to classify characters. More details are given in the - section on generic character types in the pcrepattern page. If you set - PCRE_UCP, matching one of the items it affects takes much longer. The - option is available only if PCRE has been compiled with Unicode prop- + This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W, + \w, and some of the POSIX character classes. By default, only ASCII + characters are recognized, but if PCRE_UCP is set, Unicode properties + are used instead to classify characters. More details are given in the + section on generic character types in the pcrepattern page. If you set + PCRE_UCP, matching one of the items it affects takes much longer. The + option is available only if PCRE has been compiled with Unicode prop- erty support. PCRE_UNGREEDY - This option inverts the "greediness" of the quantifiers so that they - are not greedy by default, but become greedy if followed by "?". It is - not compatible with Perl. It can also be set by a (?U) option setting + This option inverts the "greediness" of the quantifiers so that they + are not greedy by default, but become greedy if followed by "?". It is + not compatible with Perl. It can also be set by a (?U) option setting within the pattern. PCRE_UTF8 - This option causes PCRE to regard both the pattern and the subject as + This option causes PCRE to regard both the pattern and the subject as strings of UTF-8 characters instead of single-byte strings. However, it - is available only when PCRE is built to include UTF support. If not, - the use of this option provokes an error. Details of how this option + is available only when PCRE is built to include UTF support. If not, + the use of this option provokes an error. Details of how this option changes the behaviour of PCRE are given in the pcreunicode page. PCRE_NO_UTF8_CHECK When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is - automatically checked. There is a discussion about the validity of - UTF-8 strings in the pcreunicode page. If an invalid UTF-8 sequence is - found, pcre_compile() returns an error. If you already know that your - pattern is valid, and you want to skip this check for performance rea- - sons, you can set the PCRE_NO_UTF8_CHECK option. When it is set, the + automatically checked. There is a discussion about the validity of + UTF-8 strings in the pcreunicode page. If an invalid UTF-8 sequence is + found, pcre_compile() returns an error. If you already know that your + pattern is valid, and you want to skip this check for performance rea- + sons, you can set the PCRE_NO_UTF8_CHECK option. When it is set, the effect of passing an invalid UTF-8 string as a pattern is undefined. It - may cause your program to crash. Note that this option can also be - passed to pcre_exec() and pcre_dfa_exec(), to suppress the validity - checking of subject strings only. If the same string is being matched - many times, the option can be safely set for the second and subsequent + may cause your program to crash or loop. Note that this option can also + be passed to pcre_exec() and pcre_dfa_exec(), to suppress the validity + checking of subject strings only. If the same string is being matched + many times, the option can be safely set for the second and subsequent matchings to improve performance. COMPILATION ERROR CODES - The following table lists the error codes than may be returned by - pcre_compile2(), along with the error messages that may be returned by - both compiling functions. Note that error messages are always 8-bit - ASCII strings, even in 16-bit or 32-bit mode. As PCRE has developed, - some error codes have fallen out of use. To avoid confusion, they have + The following table lists the error codes than may be returned by + pcre_compile2(), along with the error messages that may be returned by + both compiling functions. Note that error messages are always 8-bit + ASCII strings, even in 16-bit or 32-bit mode. As PCRE has developed, + some error codes have fallen out of use. To avoid confusion, they have not been re-used. 0 no error @@ -2348,7 +2436,7 @@ COMPILATION ERROR CODES 31 POSIX collating elements are not supported 32 this version of PCRE is compiled without UTF support 33 [this code is not in use] - 34 character value in \x{...} sequence is too large + 34 character value in \x{} or \o{} is too large 35 invalid condition (?(0) 36 \C not allowed in lookbehind assertion 37 PCRE does not support \L, \l, \N{name}, \U, or \u @@ -2376,7 +2464,7 @@ COMPILATION ERROR CODES name/number or by a plain number 58 a numbered reference must not be zero 59 an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) - 60 (*VERB) not recognized + 60 (*VERB) not recognized or malformed 61 number is too big 62 subpattern name expected 63 digit expected after (?+ @@ -2396,74 +2484,82 @@ COMPILATION ERROR CODES 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) 76 character value in \u.... sequence is too large 77 invalid UTF-32 string (specifically UTF-32) + 78 setting UTF is disabled by the application + 79 non-hex character in \x{} (closing brace missing?) + 80 non-octal character in \o{} (closing brace missing?) + 81 missing opening brace after \o + 82 parentheses are too deeply nested + 83 invalid range in character class + 84 group name must start with a non-digit + 85 parentheses are too deeply nested (stack check) - The numbers 32 and 10000 in errors 48 and 49 are defaults; different + The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may be used if the limits were changed when PCRE was built. STUDYING A PATTERN - pcre_extra *pcre_study(const pcre *code, int options + pcre_extra *pcre_study(const pcre *code, int options, const char **errptr); - If a compiled pattern is going to be used several times, it is worth + If a compiled pattern is going to be used several times, it is worth spending more time analyzing it in order to speed up the time taken for - matching. The function pcre_study() takes a pointer to a compiled pat- + matching. The function pcre_study() takes a pointer to a compiled pat- tern as its first argument. If studying the pattern produces additional - information that will help speed up matching, pcre_study() returns a - pointer to a pcre_extra block, in which the study_data field points to + information that will help speed up matching, pcre_study() returns a + pointer to a pcre_extra block, in which the study_data field points to the results of the study. The returned value from pcre_study() can be passed directly to - pcre_exec() or pcre_dfa_exec(). However, a pcre_extra block also con- - tains other fields that can be set by the caller before the block is + pcre_exec() or pcre_dfa_exec(). However, a pcre_extra block also con- + tains other fields that can be set by the caller before the block is passed; these are described below in the section on matching a pattern. - If studying the pattern does not produce any useful information, - pcre_study() returns NULL by default. In that circumstance, if the + If studying the pattern does not produce any useful information, + pcre_study() returns NULL by default. In that circumstance, if the calling program wants to pass any of the other fields to pcre_exec() or - pcre_dfa_exec(), it must set up its own pcre_extra block. However, if - pcre_study() is called with the PCRE_STUDY_EXTRA_NEEDED option, it + pcre_dfa_exec(), it must set up its own pcre_extra block. However, if + pcre_study() is called with the PCRE_STUDY_EXTRA_NEEDED option, it returns a pcre_extra block even if studying did not find any additional - information. It may still return NULL, however, if an error occurs in + information. It may still return NULL, however, if an error occurs in pcre_study(). - The second argument of pcre_study() contains option bits. There are + The second argument of pcre_study() contains option bits. There are three further options in addition to PCRE_STUDY_EXTRA_NEEDED: PCRE_STUDY_JIT_COMPILE PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE - If any of these are set, and the just-in-time compiler is available, - the pattern is further compiled into machine code that executes much - faster than the pcre_exec() interpretive matching function. If the - just-in-time compiler is not available, these options are ignored. All + If any of these are set, and the just-in-time compiler is available, + the pattern is further compiled into machine code that executes much + faster than the pcre_exec() interpretive matching function. If the + just-in-time compiler is not available, these options are ignored. All undefined bits in the options argument must be zero. - JIT compilation is a heavyweight optimization. It can take some time - for patterns to be analyzed, and for one-off matches and simple pat- - terns the benefit of faster execution might be offset by a much slower + JIT compilation is a heavyweight optimization. It can take some time + for patterns to be analyzed, and for one-off matches and simple pat- + terns the benefit of faster execution might be offset by a much slower study time. Not all patterns can be optimized by the JIT compiler. For - those that cannot be handled, matching automatically falls back to the - pcre_exec() interpreter. For more details, see the pcrejit documenta- + those that cannot be handled, matching automatically falls back to the + pcre_exec() interpreter. For more details, see the pcrejit documenta- tion. - The third argument for pcre_study() is a pointer for an error message. - If studying succeeds (even if no data is returned), the variable it - points to is set to NULL. Otherwise it is set to point to a textual + The third argument for pcre_study() is a pointer for an error message. + If studying succeeds (even if no data is returned), the variable it + points to is set to NULL. Otherwise it is set to point to a textual error message. This is a static string that is part of the library. You - must not try to free it. You should test the error pointer for NULL + must not try to free it. You should test the error pointer for NULL after calling pcre_study(), to be sure that it has run successfully. - When you are finished with a pattern, you can free the memory used for + When you are finished with a pattern, you can free the memory used for the study data by calling pcre_free_study(). This function was added to - the API for release 8.20. For earlier versions, the memory could be - freed with pcre_free(), just like the pattern itself. This will still - work in cases where JIT optimization is not used, but it is advisable + the API for release 8.20. For earlier versions, the memory could be + freed with pcre_free(), just like the pattern itself. This will still + work in cases where JIT optimization is not used, but it is advisable to change to the new function when convenient. - This is a typical way in which pcre_study() is used (except that in a + This is a typical way in which pcre_study() is used (except that in a real application there should be tests for errors): int rc; @@ -2483,41 +2579,50 @@ STUDYING A PATTERN Studying a pattern does two things: first, a lower bound for the length of subject string that is needed to match the pattern is computed. This does not mean that there are any strings of that length that match, but - it does guarantee that no shorter strings match. The value is used to + it does guarantee that no shorter strings match. The value is used to avoid wasting time by trying to match strings that are shorter than the - lower bound. You can find out the value in a calling program via the + lower bound. You can find out the value in a calling program via the pcre_fullinfo() function. Studying a pattern is also useful for non-anchored patterns that do not - have a single fixed starting character. A bitmap of possible starting - bytes is created. This speeds up finding a position in the subject at + have a single fixed starting character. A bitmap of possible starting + bytes is created. This speeds up finding a position in the subject at which to start matching. (In 16-bit mode, the bitmap is used for 16-bit - values less than 256. In 32-bit mode, the bitmap is used for 32-bit + values less than 256. In 32-bit mode, the bitmap is used for 32-bit values less than 256.) - These two optimizations apply to both pcre_exec() and pcre_dfa_exec(), - and the information is also used by the JIT compiler. The optimiza- - tions can be disabled by setting the PCRE_NO_START_OPTIMIZE option when - calling pcre_exec() or pcre_dfa_exec(), but if this is done, JIT execu- - tion is also disabled. You might want to do this if your pattern con- - tains callouts or (*MARK) and you want to make use of these facilities - in cases where matching fails. See the discussion of - PCRE_NO_START_OPTIMIZE below. + These two optimizations apply to both pcre_exec() and pcre_dfa_exec(), + and the information is also used by the JIT compiler. The optimiza- + tions can be disabled by setting the PCRE_NO_START_OPTIMIZE option. + You might want to do this if your pattern contains callouts or (*MARK) + and you want to make use of these facilities in cases where matching + fails. + + PCRE_NO_START_OPTIMIZE can be specified at either compile time or exe- + cution time. However, if PCRE_NO_START_OPTIMIZE is passed to + pcre_exec(), (that is, after any JIT compilation has happened) JIT exe- + cution is disabled. For JIT execution to work with PCRE_NO_START_OPTI- + MIZE, the option must be set at compile time. + + There is a longer discussion of PCRE_NO_START_OPTIMIZE below. LOCALE SUPPORT - PCRE handles caseless matching, and determines whether characters are - letters, digits, or whatever, by reference to a set of tables, indexed - by character value. When running in UTF-8 mode, this applies only to - characters with codes less than 128. By default, higher-valued codes - never match escapes such as \w or \d, but they can be tested with \p if - PCRE is built with Unicode character property support. Alternatively, - the PCRE_UCP option can be set at compile time; this causes \w and - friends to use Unicode property support instead of built-in tables. The - use of locales with Unicode is discouraged. If you are handling charac- - ters with codes greater than 128, you should either use UTF-8 and Uni- - code, or use locales, but not try to mix the two. + PCRE handles caseless matching, and determines whether characters are + letters, digits, or whatever, by reference to a set of tables, indexed + by character code point. When running in UTF-8 mode, or in the 16- or + 32-bit libraries, this applies only to characters with code points less + than 256. By default, higher-valued code points never match escapes + such as \w or \d. However, if PCRE is built with Unicode property sup- + port, all characters can be tested with \p and \P, or, alternatively, + the PCRE_UCP option can be set when a pattern is compiled; this causes + \w and friends to use Unicode property support instead of the built-in + tables. + + The use of locales with Unicode is discouraged. If you are handling + characters with code points greater than 128, you should either use + Unicode support, or use locales, but not try to mix the two. PCRE contains an internal set of tables that are used when the final argument of pcre_compile() is NULL. These are sufficient for many @@ -2533,10 +2638,10 @@ LOCALE SUPPORT External tables are built by calling the pcre_maketables() function, which has no arguments, in the relevant locale. The result can then be - passed to pcre_compile() or pcre_exec() as often as necessary. For - example, to build and use tables that are appropriate for the French - locale (where accented characters with values greater than 128 are - treated as letters), the following code could be used: + passed to pcre_compile() as often as necessary. For example, to build + and use tables that are appropriate for the French locale (where + accented characters with values greater than 128 are treated as let- + ters), the following code could be used: setlocale(LC_CTYPE, "fr_FR"); tables = pcre_maketables(); @@ -2552,15 +2657,19 @@ LOCALE SUPPORT The pointer that is passed to pcre_compile() is saved with the compiled pattern, and the same tables are used via this pointer by pcre_study() - and normally also by pcre_exec(). Thus, by default, for any single pat- + and also by pcre_exec() and pcre_dfa_exec(). Thus, for any single pat- tern, compilation, studying and matching all happen in the same locale, - but different patterns can be compiled in different locales. + but different patterns can be processed in different locales. It is possible to pass a table pointer or NULL (indicating the use of - the internal tables) to pcre_exec(). Although not intended for this - purpose, this facility could be used to match a pattern in a different - locale from the one in which it was compiled. Passing table pointers at - run time is discussed below in the section on matching a pattern. + the internal tables) to pcre_exec() or pcre_dfa_exec() (see the discus- + sion below in the section on matching a pattern). This facility is pro- + vided for use with pre-compiled patterns that have been saved and + reloaded. Character tables are not saved with patterns, so if a non- + standard table was used at compile time, it must be provided again when + the reloaded pattern is matched. Attempting to use this facility to + match a pattern in a different locale from the one in which it was com- + piled is likely to lead to anomalous (usually incorrect) results. INFORMATION ABOUT A PATTERN @@ -2585,6 +2694,7 @@ INFORMATION ABOUT A PATTERN PCRE_ERROR_BADENDIANNESS the pattern was compiled with different endianness PCRE_ERROR_BADOPTION the value of what was invalid + PCRE_ERROR_UNSET the requested field is not set The "magic number" is placed at the start of each compiled pattern as an simple check against passing an arbitrary memory pointer. The endi- @@ -2622,12 +2732,16 @@ INFORMATION ABOUT A PATTERN tion. External callers can cause PCRE to use its internal tables by passing a NULL table pointer. - PCRE_INFO_FIRSTBYTE + PCRE_INFO_FIRSTBYTE (deprecated) 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. + 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. Negative values are used for special cases. How- + ever, this means that when the 32-bit library is in non-UTF-32 mode, + the full 32-bit range of characters cannot be returned. For this rea- + son, this value is deprecated; use PCRE_INFO_FIRSTCHARACTERFLAGS and + PCRE_INFO_FIRSTCHARACTER instead. 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 @@ -2647,10 +2761,38 @@ INFORMATION ABOUT A PATTERN of a subject string or after any newline within the string. Otherwise -2 is returned. For anchored patterns, -2 is returned. - Since for the 32-bit library using the non-UTF-32 mode, this function - is unable to return the full 32-bit range of the character, this value - is deprecated; instead the PCRE_INFO_FIRSTCHARACTERFLAGS and - PCRE_INFO_FIRSTCHARACTER values should be used. + PCRE_INFO_FIRSTCHARACTER + + Return the value of the first data unit (non-UTF character) of any + matched string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS + returns 1; otherwise return 0. The fourth argument should point to an + uint_t variable. + + In the 8-bit library, the value is always less than 256. In the 16-bit + library the value can be up to 0xffff. In the 32-bit library in UTF-32 + mode the value can be up to 0x10ffff, and up to 0xffffffff when not + using UTF-32 mode. + + PCRE_INFO_FIRSTCHARACTERFLAGS + + Return information about the first data unit of any matched string, for + a non-anchored pattern. The fourth argument should point to an int + variable. + + If there is a fixed first value, for example, the letter "c" from a + pattern such as (cat|cow|coyote), 1 is returned, and the character + value can be retrieved using PCRE_INFO_FIRSTCHARACTER. If there is no + fixed first value, and if either + + (a) the pattern was compiled with the PCRE_MULTILINE option, and every + branch starts with "^", or + + (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not + set (if it were set, the pattern would be anchored), + + 2 is returned, indicating that the pattern matches only at the start of + a subject string or after any newline within the string. Otherwise 0 is + returned. For anchored patterns, 0 is returned. PCRE_INFO_FIRSTTABLE @@ -2700,23 +2842,41 @@ INFORMATION ABOUT A PATTERN /^a\dz\d/ the returned value is -1. Since for the 32-bit library using the non-UTF-32 mode, this function - is unable to return the full 32-bit range of the character, this value - is deprecated; instead the PCRE_INFO_REQUIREDCHARFLAGS and + is unable to return the full 32-bit range of characters, this value is + deprecated; instead the PCRE_INFO_REQUIREDCHARFLAGS and PCRE_INFO_REQUIREDCHAR values should be used. + PCRE_INFO_MATCH_EMPTY + + Return 1 if the pattern can match an empty string, otherwise 0. The + fourth argument should point to an int variable. + + PCRE_INFO_MATCHLIMIT + + If the pattern set a match limit by including an item of the form + (*LIMIT_MATCH=nnnn) at the start, the value is returned. The fourth + argument should point to an unsigned 32-bit integer. If no such value + has been set, the call to pcre_fullinfo() returns the error + PCRE_ERROR_UNSET. + PCRE_INFO_MAXLOOKBEHIND - Return the number of characters (NB not bytes) in the longest lookbe- - hind assertion in the pattern. Note that the simple assertions \b and - \B require a one-character lookbehind. This information is useful when - doing multi-segment matching using the partial matching facilities. + Return the number of characters (NB not data units) in the longest + lookbehind assertion in the pattern. This information is useful when + doing multi-segment matching using the partial matching facilities. + Note that the simple assertions \b and \B require a one-character look- + behind. \A also registers a one-character lookbehind, though it does + not actually inspect the previous character. This is to ensure that at + least one character from the old segment is retained when a new segment + is processed. Otherwise, if there are no lookbehinds in the pattern, \A + might match incorrectly at the start of a new segment. PCRE_INFO_MINLENGTH If the pattern was studied and a minimum length for matching subject strings was computed, its value is returned. Otherwise the returned - value is -1. The value is a number of characters, which in UTF-8 mode - may be different from the number of bytes. The fourth argument should + value is -1. The value is a number of characters, which in UTF mode may + be different from the number of data units. The fourth argument should point to an int variable. A non-negative value is a lower bound to the length of any matching string. There may not be any strings of that length that do actually match, but every string that does match is at @@ -2744,30 +2904,31 @@ INFORMATION ABOUT A PATTERN the 8-bit library, where the first two bytes of each entry are the num- ber of the capturing parenthesis, most significant byte first. In the 16-bit library, the pointer points to 16-bit data units, the first of - which contains the parenthesis number. In the 32-bit library, the + which contains the parenthesis number. In the 32-bit library, the pointer points to 32-bit data units, the first of which contains the parenthesis number. The rest of the entry is the corresponding name, zero terminated. - The names are in alphabetical order. Duplicate names may appear if (?| - is used to create multiple groups with the same number, as described in - the section on duplicate subpattern numbers in the pcrepattern page. - Duplicate names for subpatterns with different numbers are permitted - only if PCRE_DUPNAMES is set. In all cases of duplicate names, they - appear in the table in the order in which they were found in the pat- - tern. In the absence of (?| this is the order of increasing number; - when (?| is used this is not necessarily the case because later subpat- - terns may have lower numbers. + The names are in alphabetical order. If (?| is used to create multiple + groups with the same number, as described in the section on duplicate + subpattern numbers in the pcrepattern page, the groups may be given the + same name, but there is only one entry in the table. Different names + for groups of the same number are not permitted. Duplicate names for + subpatterns with different numbers are permitted, but only if PCRE_DUP- + NAMES is set. They appear in the table in the order in which they were + found in the pattern. In the absence of (?| this is the order of + increasing number; when (?| is used this is not necessarily the case + because later subpatterns may have lower numbers. - As a simple example of the name/number table, consider the following + As a simple example of the name/number table, consider the following pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white space - including newlines - is ignored): (? (?(\d\d)?\d\d) - (?\d\d) - (?\d\d) ) - There are four named subpatterns, so the table has four entries, and - each entry in the table is eight bytes long. The table is as follows, + There are four named subpatterns, so the table has four entries, and + each entry in the table is eight bytes long. The table is as follows, with non-printing bytes shows in hexadecimal, and undefined bytes shown as ??: @@ -2776,31 +2937,31 @@ INFORMATION ABOUT A PATTERN 00 04 m o n t h 00 00 02 y e a r 00 ?? - When writing code to extract data from named subpatterns using the - name-to-number map, remember that the length of the entries is likely + When writing code to extract data from named subpatterns using the + name-to-number map, remember that the length of the entries is likely to be different for each compiled pattern. PCRE_INFO_OKPARTIAL - Return 1 if the pattern can be used for partial matching with - pcre_exec(), otherwise 0. The fourth argument should point to an int - variable. From release 8.00, this always returns 1, because the - restrictions that previously applied to partial matching have been - lifted. The pcrepartial documentation gives details of partial match- + Return 1 if the pattern can be used for partial matching with + pcre_exec(), otherwise 0. The fourth argument should point to an int + variable. From release 8.00, this always returns 1, because the + restrictions that previously applied to partial matching have been + lifted. The pcrepartial documentation gives details of partial match- ing. PCRE_INFO_OPTIONS - Return a copy of the options with which the pattern was compiled. The - fourth argument should point to an unsigned long int variable. These + Return a copy of the options with which the pattern was compiled. The + fourth argument should point to an unsigned long int variable. These option bits are those specified in the call to pcre_compile(), modified by any top-level option settings at the start of the pattern itself. In - other words, they are the options that will be in force when matching - starts. For example, if the pattern /(?im)abc(?-i)d/ is compiled with - the PCRE_EXTENDED option, the result is PCRE_CASELESS, PCRE_MULTILINE, + other words, they are the options that will be in force when matching + starts. For example, if the pattern /(?im)abc(?-i)d/ is compiled with + the PCRE_EXTENDED option, the result is PCRE_CASELESS, PCRE_MULTILINE, and PCRE_EXTENDED. - A pattern is automatically anchored by PCRE if all of its top-level + A pattern is automatically anchored by PCRE if all of its top-level alternatives begin with one of the following: ^ unless PCRE_MULTILINE is set @@ -2812,73 +2973,36 @@ INFORMATION ABOUT A PATTERN For such patterns, the PCRE_ANCHORED bit is set in the options returned by pcre_fullinfo(). + PCRE_INFO_RECURSIONLIMIT + + If the pattern set a recursion limit by including an item of the form + (*LIMIT_RECURSION=nnnn) at the start, the value is returned. The fourth + argument should point to an unsigned 32-bit integer. If no such value + has been set, the call to pcre_fullinfo() returns the error + PCRE_ERROR_UNSET. + PCRE_INFO_SIZE - Return the size of the compiled pattern in bytes (for both libraries). - The fourth argument should point to a size_t variable. This value does - not include the size of the pcre structure that is returned by - pcre_compile(). The value that is passed as the argument to pcre_mal- - loc() when pcre_compile() is getting memory in which to place the com- - piled data is the value returned by this option plus the size of the - pcre structure. Studying a compiled pattern, with or without JIT, does - not alter the value returned by this option. + Return the size of the compiled pattern in bytes (for all three + libraries). The fourth argument should point to a size_t variable. This + value does not include the size of the pcre structure that is returned + by pcre_compile(). The value that is passed as the argument to + pcre_malloc() when pcre_compile() is getting memory in which to place + the compiled data is the value returned by this option plus the size of + the pcre structure. Studying a compiled pattern, with or without JIT, + does not alter the value returned by this option. PCRE_INFO_STUDYSIZE - Return the size in bytes of the data block pointed to by the study_data - field in a pcre_extra block. If pcre_extra is NULL, or there is no - study data, zero is returned. The fourth argument should point to a - size_t variable. The study_data field is set by pcre_study() to record - information that will speed up matching (see the section entitled - "Studying a pattern" above). The format of the study_data block is pri- - vate, but its length is made available via this option so that it can - be saved and restored (see the pcreprecompile documentation for - details). - - PCRE_INFO_FIRSTCHARACTERFLAGS - - Return information about the first data unit of any matched string, for - a non-anchored pattern. The fourth argument should point to an int - variable. - - If there is a fixed first value, for example, the letter "c" from a - pattern such as (cat|cow|coyote), 1 is returned, and the character - value can be retrieved using PCRE_INFO_FIRSTCHARACTER. - - If there is no fixed first value, and if either - - (a) the pattern was compiled with the PCRE_MULTILINE option, and every - branch starts with "^", or - - (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not - set (if it were set, the pattern would be anchored), - - 2 is returned, indicating that the pattern matches only at the start of - a subject string or after any newline within the string. Otherwise 0 is - returned. For anchored patterns, 0 is returned. - - PCRE_INFO_FIRSTCHARACTER - - Return the fixed first character value, if PCRE_INFO_FIRSTCHARACTER- - FLAGS returned 1; otherwise returns 0. The fourth argument should point - to an uint_t variable. - - In the 8-bit library, the value is always less than 256. In the 16-bit - library the value can be up to 0xffff. In the 32-bit library in UTF-32 - mode the value can be up to 0x10ffff, and up to 0xffffffff when not - using UTF-32 mode. - - If there is no fixed first value, and if either - - (a) the pattern was compiled with the PCRE_MULTILINE option, and every - branch starts with "^", or - - (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not - set (if it were set, the pattern would be anchored), - - -1 is returned, indicating that the pattern matches only at the start - of a subject string or after any newline within the string. Otherwise - -2 is returned. For anchored patterns, -2 is returned. + Return the size in bytes (for all three libraries) of the data block + pointed to by the study_data field in a pcre_extra block. If pcre_extra + is NULL, or there is no study data, zero is returned. The fourth argu- + ment should point to a size_t variable. The study_data field is set by + pcre_study() to record information that will speed up matching (see the + section entitled "Studying a pattern" above). The format of the + study_data block is private, but its length is made available via this + option so that it can be saved and restored (see the pcreprecompile + documentation for details). PCRE_INFO_REQUIREDCHARFLAGS @@ -3028,38 +3152,60 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION 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 + A value for the match limit may also be supplied by an item at the + start of a pattern of the form + + (*LIMIT_MATCH=d) + + where d is a decimal number. However, such a setting is ignored unless + d is less than the limit set by the caller of pcre_exec() or, if no + such limit is set, less than the default. + + The match_limit_recursion field is similar to match_limit, but instead of limiting the total number of times that match() is called, it limits - the depth of recursion. The recursion depth is a smaller number than - 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 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 + Limiting the recursion depth limits the amount of machine stack that + can be used, or, when PCRE has been compiled to use memory on the heap + instead of the stack, the amount of heap memory that can be used. This + limit is not relevant, and is ignored, when matching is done using JIT compiled code. - The default value for match_limit_recursion can be set when PCRE is - built; the default default is the same value as the default for - match_limit. You can override the default by suppling pcre_exec() with - a pcre_extra block in which match_limit_recursion is set, and - PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the + The default value for match_limit_recursion can be set when PCRE is + built; the default default is the same value as the default for + match_limit. You can override the default by suppling pcre_exec() with + a pcre_extra block in which match_limit_recursion is set, and + PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_RECURSIONLIMIT. + A value for the recursion limit may also be supplied by an item at the + start of a pattern of the form + + (*LIMIT_RECURSION=d) + + where d is a decimal number. However, such a setting is ignored unless + d is less than the limit set by the caller of pcre_exec() or, if no + such limit is set, less than the default. + The callout_data field is used in conjunction with the "callout" fea- ture, and is described in the pcrecallout documentation. - The tables field is used to pass a character tables pointer to - pcre_exec(); this overrides the value that is stored with the compiled - pattern. A non-NULL value is stored with the compiled pattern only if - custom tables were supplied to pcre_compile() via its tableptr argu- - ment. If NULL is passed to pcre_exec() using this mechanism, it forces - PCRE's internal tables to be used. This facility is helpful when re- - using patterns that have been saved after compiling with an external - set of tables, because the external tables might be at a different - address when pcre_exec() is called. See the pcreprecompile documenta- - tion for a discussion of saving compiled patterns for later use. + The tables field is provided for use with patterns that have been pre- + compiled using custom character tables, saved to disc or elsewhere, and + then reloaded, because the tables that were used to compile a pattern + are not saved with it. See the pcreprecompile documentation for a dis- + cussion of saving compiled patterns for later use. If NULL is passed + using this mechanism, it forces PCRE's internal tables to be used. + + Warning: The tables that pcre_exec() uses must be the same as those + that were used when the pattern was compiled. If this is not the case, + the behaviour of pcre_exec() is undefined. Therefore, when a pattern is + compiled and matched in the same process, this field should never be + set. In this (the most common) case, the correct table pointer is auto- + matically passed with the compiled pattern from pcre_compile() to + pcre_exec(). If PCRE_EXTRA_MARK is set in the flags field, the mark field must be set to point to a suitable variable. If the pattern contains any back- @@ -3199,10 +3345,10 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION cannot find it, without actually running the main matching function. This means that a special item such as (*COMMIT) at the start of a pat- tern is not considered until after a suitable starting point for the - match has been found. When callouts or (*MARK) items are in use, these - "start-up" optimizations can cause them to be skipped if the pattern is - never actually used. The start-up optimizations are in effect a pre- - scan of the subject that takes place before the pattern is run. + match has been found. Also, when callouts or (*MARK) items are in use, + these "start-up" optimizations can cause them to be skipped if the pat- + tern is never actually used. The start-up optimizations are in effect a + pre-scan of the subject that takes place before the pattern is run. The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, possibly causing performance to suffer, but ensuring that in cases @@ -3210,101 +3356,107 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION such as (*COMMIT) and (*MARK) are considered at every possible starting position in the subject string. If PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching time. The use of - PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, matching - is always done using interpretively. + PCRE_NO_START_OPTIMIZE at matching time (that is, passing it to + pcre_exec()) disables JIT execution; in this situation, matching is + always done using interpretively. - Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching + Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. Consider the pattern (*COMMIT)ABC - When this is compiled, PCRE records the fact that a match must start - with the character "A". Suppose the subject string is "DEFABC". The - start-up optimization scans along the subject, finds "A" and runs the - first match attempt from there. The (*COMMIT) item means that the pat- - tern must match the current starting position, which in this case, it - does. However, if the same match is run with PCRE_NO_START_OPTIMIZE - set, the initial scan along the subject string does not happen. The - first match attempt is run starting from "D" and when this fails, - (*COMMIT) prevents any further matches being tried, so the overall - result is "no match". If the pattern is studied, more start-up opti- - mizations may be used. For example, a minimum length for the subject + When this is compiled, PCRE records the fact that a match must start + with the character "A". Suppose the subject string is "DEFABC". The + start-up optimization scans along the subject, finds "A" and runs the + first match attempt from there. The (*COMMIT) item means that the pat- + tern must match the current starting position, which in this case, it + does. However, if the same match is run with PCRE_NO_START_OPTIMIZE + set, the initial scan along the subject string does not happen. The + first match attempt is run starting from "D" and when this fails, + (*COMMIT) prevents any further matches being tried, so the overall + result is "no match". If the pattern is studied, more start-up opti- + mizations may be used. For example, a minimum length for the subject may be recorded. Consider the pattern (*MARK:A)(X|Y) - The minimum length for a match is one character. If the subject is - "ABC", there will be attempts to match "ABC", "BC", "C", and then - finally an empty string. If the pattern is studied, the final attempt - does not take place, because PCRE knows that the subject is too short, - and so the (*MARK) is never encountered. In this case, studying the - pattern does not affect the overall match result, which is still "no + The minimum length for a match is one character. If the subject is + "ABC", there will be attempts to match "ABC", "BC", "C", and then + finally an empty string. If the pattern is studied, the final attempt + does not take place, because PCRE knows that the subject is too short, + and so the (*MARK) is never encountered. In this case, studying the + pattern does not affect the overall match result, which is still "no match", but it does affect the auxiliary information that is returned. PCRE_NO_UTF8_CHECK 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 + UTF-8 string is automatically checked when pcre_exec() is subsequently 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 + 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- + 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 + 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. + subject or an invalid value of startoffset is undefined. Your program + may crash or loop. 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, - and this is by far the most common case. In UTF-8 mode, the byte offset - must point to the start of a UTF-8 character (or the end of the sub- - ject). Unlike the pattern string, the subject may contain binary zero - bytes. + The subject string is passed to pcre_exec() as a pointer in subject, a + length in length, and a starting offset in startoffset. The units for + length and startoffset are bytes for the 8-bit library, 16-bit data + items for the 16-bit library, and 32-bit data items for the 32-bit + library. + + If startoffset is negative or greater than the length of the subject, + pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is + zero, the search for a match starts at the beginning of the subject, + and this is by far the most common case. In UTF-8 or UTF-16 mode, the + offset must point to the start of a character, or the end of the sub- + ject (in UTF-32 mode, one data unit equals one character, so all off- + sets are valid). Unlike the pattern string, the subject may contain + binary zeroes. A non-zero starting offset is useful when searching for another match in the same subject by calling pcre_exec() again after a previous suc- @@ -3366,10 +3518,12 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION 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. + element of each pair is set to the offset of the first character in a + substring, and the second is set to the offset of the first character + after the end of a substring. These values are always data unit off- + sets, even in UTF mode. They are byte offsets in the 8-bit library, + 16-bit data item offsets in the 16-bit library, and 32-bit data item + offsets in the 32-bit library. Note: they are not character counts. The first pair of integers, ovector[0] and ovector[1], identify the portion of the subject string matched by the entire pattern. The next @@ -3684,11 +3838,12 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION The first byte of a character has the value 0xfe or 0xff. These values can never occur in a valid UTF-8 string. - PCRE_UTF8_ERR2 + PCRE_UTF8_ERR22 - Non-character. These are the last two characters in each plane (0xfffe, - 0xffff, 0x1fffe, 0x1ffff .. 0x10fffe, 0x10ffff), and the characters - 0xfdd0..0xfdef. + This error code was formerly used when the presence of a so-called + "non-character" caused an error. Unicode corrigendum #9 makes it clear + that such characters should not cause a string to be rejected, and so + this code is no longer in use and is never returned. EXTRACTING CAPTURED SUBSTRINGS BY NUMBER @@ -3704,78 +3859,78 @@ EXTRACTING CAPTURED SUBSTRINGS BY NUMBER int pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr); - Captured substrings can be accessed directly by using the offsets - returned by pcre_exec() in ovector. For convenience, the functions + Captured substrings can be accessed directly by using the offsets + returned by pcre_exec() in ovector. For convenience, the functions pcre_copy_substring(), pcre_get_substring(), and pcre_get_sub- - string_list() are provided for extracting captured substrings as new, - separate, zero-terminated strings. These functions identify substrings - by number. The next section describes functions for extracting named + string_list() are provided for extracting captured substrings as new, + separate, zero-terminated strings. These functions identify substrings + by number. The next section describes functions for extracting named substrings. - A substring that contains a binary zero is correctly extracted and has - a further zero added on the end, but the result is not, of course, a C - string. However, you can process such a string by referring to the - length that is returned by pcre_copy_substring() and pcre_get_sub- + A substring that contains a binary zero is correctly extracted and has + a further zero added on the end, but the result is not, of course, a C + string. However, you can process such a string by referring to the + length that is returned by pcre_copy_substring() and pcre_get_sub- string(). Unfortunately, the interface to pcre_get_substring_list() is - not adequate for handling strings containing binary zeros, because the + not adequate for handling strings containing binary zeros, because the end of the final string is not independently indicated. - The first three arguments are the same for all three of these func- - tions: subject is the subject string that has just been successfully + The first three arguments are the same for all three of these func- + tions: subject is the subject string that has just been successfully matched, ovector is a pointer to the vector of integer offsets that was passed to pcre_exec(), and stringcount is the number of substrings that - were captured by the match, including the substring that matched the + were captured by the match, including the substring that matched the entire regular expression. This is the value returned by pcre_exec() if - it is greater than zero. If pcre_exec() returned zero, indicating that - it ran out of space in ovector, the value passed as stringcount should + it is greater than zero. If pcre_exec() returned zero, indicating that + it ran out of space in ovector, the value passed as stringcount should be the number of elements in the vector divided by three. - The functions pcre_copy_substring() and pcre_get_substring() extract a - single substring, whose number is given as stringnumber. A value of - zero extracts the substring that matched the entire pattern, whereas - higher values extract the captured substrings. For pcre_copy_sub- - string(), the string is placed in buffer, whose length is given by - buffersize, while for pcre_get_substring() a new block of memory is - obtained via pcre_malloc, and its address is returned via stringptr. - The yield of the function is the length of the string, not including + The functions pcre_copy_substring() and pcre_get_substring() extract a + single substring, whose number is given as stringnumber. A value of + zero extracts the substring that matched the entire pattern, whereas + higher values extract the captured substrings. For pcre_copy_sub- + string(), the string is placed in buffer, whose length is given by + buffersize, while for pcre_get_substring() a new block of memory is + obtained via pcre_malloc, and its address is returned via stringptr. + The yield of the function is the length of the string, not including the terminating zero, or one of these error codes: PCRE_ERROR_NOMEMORY (-6) - The buffer was too small for pcre_copy_substring(), or the attempt to + The buffer was too small for pcre_copy_substring(), or the attempt to get memory failed for pcre_get_substring(). PCRE_ERROR_NOSUBSTRING (-7) There is no substring whose number is stringnumber. - The pcre_get_substring_list() function extracts all available sub- - strings and builds a list of pointers to them. All this is done in a + The pcre_get_substring_list() function extracts all available sub- + strings and builds a list of pointers to them. All this is done in a single block of memory that is obtained via pcre_malloc. The address of - the memory block is returned via listptr, which is also the start of - the list of string pointers. The end of the list is marked by a NULL - pointer. The yield of the function is zero if all went well, or the + the memory block is returned via listptr, which is also the start of + the list of string pointers. The end of the list is marked by a NULL + pointer. The yield of the function is zero if all went well, or the error code PCRE_ERROR_NOMEMORY (-6) if the attempt to get the memory block failed. - When any of these functions encounter a substring that is unset, which - can happen when capturing subpattern number n+1 matches some part of - the subject, but subpattern n has not been used at all, they return an + When any of these functions encounter a substring that is unset, which + can happen when capturing subpattern number n+1 matches some part of + the subject, but subpattern n has not been used at all, they return an empty string. This can be distinguished from a genuine zero-length sub- - string by inspecting the appropriate offset in ovector, which is nega- + string by inspecting the appropriate offset in ovector, which is nega- tive for unset substrings. - The two convenience functions pcre_free_substring() and pcre_free_sub- - string_list() can be used to free the memory returned by a previous + The two convenience functions pcre_free_substring() and pcre_free_sub- + string_list() can be used to free the memory returned by a previous call of pcre_get_substring() or pcre_get_substring_list(), respec- - tively. They do nothing more than call the function pointed to by - pcre_free, which of course could be called directly from a C program. - However, PCRE is used in some situations where it is linked via a spe- - cial interface to another programming language that cannot use - pcre_free directly; it is for these cases that the functions are pro- + tively. They do nothing more than call the function pointed to by + pcre_free, which of course could be called directly from a C program. + However, PCRE is used in some situations where it is linked via a spe- + cial interface to another programming language that cannot use + pcre_free directly; it is for these cases that the functions are pro- vided. @@ -3794,7 +3949,7 @@ EXTRACTING CAPTURED SUBSTRINGS BY NAME int stringcount, const char *stringname, const char **stringptr); - To extract a substring by name, you first have to find associated num- + To extract a substring by name, you first have to find associated num- ber. For example, for this pattern (a+)b(?\d+)... @@ -3803,35 +3958,35 @@ EXTRACTING CAPTURED SUBSTRINGS BY NAME be unique (PCRE_DUPNAMES was not set), you can find the number from the name by calling pcre_get_stringnumber(). The first argument is the com- piled pattern, and the second is the name. The yield of the function is - the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no + the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no subpattern of that name. Given the number, you can extract the substring directly, or use one of the functions described in the previous section. For convenience, there are also two functions that do the whole job. - Most of the arguments of pcre_copy_named_substring() and - pcre_get_named_substring() are the same as those for the similarly - named functions that extract by number. As these are described in the - previous section, they are not re-described here. There are just two + Most of the arguments of pcre_copy_named_substring() and + pcre_get_named_substring() are the same as those for the similarly + named functions that extract by number. As these are described in the + previous section, they are not re-described here. There are just two differences: - First, instead of a substring number, a substring name is given. Sec- + First, instead of a substring number, a substring name is given. Sec- ond, there is an extra argument, given at the start, which is a pointer - to the compiled pattern. This is needed in order to gain access to the + to the compiled pattern. This is needed in order to gain access to the name-to-number translation table. - These functions call pcre_get_stringnumber(), and if it succeeds, they - then call pcre_copy_substring() or pcre_get_substring(), as appropri- - ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the + These functions call pcre_get_stringnumber(), and if it succeeds, they + then call pcre_copy_substring() or pcre_get_substring(), as appropri- + ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the behaviour may not be what you want (see the next section). Warning: If the pattern uses the (?| feature to set up multiple subpat- - terns with the same number, as described in the section on duplicate - subpattern numbers in the pcrepattern page, you cannot use names to - distinguish the different subpatterns, because names are not included - in the compiled code. The matching process uses only numbers. For this - reason, the use of different names for subpatterns of the same number + terns with the same number, as described in the section on duplicate + subpattern numbers in the pcrepattern page, you cannot use names to + distinguish the different subpatterns, because names are not included + in the compiled code. The matching process uses only numbers. For this + reason, the use of different names for subpatterns of the same number causes an error at compile time. @@ -3840,76 +3995,76 @@ DUPLICATE SUBPATTERN NAMES int pcre_get_stringtable_entries(const pcre *code, const char *name, char **first, char **last); - When a pattern is compiled with the PCRE_DUPNAMES option, names for - subpatterns are not required to be unique. (Duplicate names are always - allowed for subpatterns with the same number, created by using the (?| - feature. Indeed, if such subpatterns are named, they are required to + When a pattern is compiled with the PCRE_DUPNAMES option, names for + subpatterns are not required to be unique. (Duplicate names are always + allowed for subpatterns with the same number, created by using the (?| + feature. Indeed, if such subpatterns are named, they are required to use the same names.) Normally, patterns with duplicate names are such that in any one match, - only one of the named subpatterns participates. An example is shown in + only one of the named subpatterns participates. An example is shown in the pcrepattern documentation. - When duplicates are present, pcre_copy_named_substring() and - pcre_get_named_substring() return the first substring corresponding to - the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING - (-7) is returned; no data is returned. The pcre_get_stringnumber() - function returns one of the numbers that are associated with the name, + When duplicates are present, pcre_copy_named_substring() and + pcre_get_named_substring() return the first substring corresponding to + the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING + (-7) is returned; no data is returned. The pcre_get_stringnumber() + function returns one of the numbers that are associated with the name, but it is not defined which it is. - If you want to get full details of all captured substrings for a given - name, you must use the pcre_get_stringtable_entries() function. The + If you want to get full details of all captured substrings for a given + name, you must use the pcre_get_stringtable_entries() function. The first argument is the compiled pattern, and the second is the name. The - third and fourth are pointers to variables which are updated by the + third and fourth are pointers to variables which are updated by the function. After it has run, they point to the first and last entries in - the name-to-number table for the given name. The function itself - returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if - there are none. The format of the table is described above in the sec- - tion entitled Information about a pattern above. Given all the rele- - vant entries for the name, you can extract each of their numbers, and + 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 + 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 + 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 + 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 + 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. @@ -3920,26 +4075,26 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION int options, int *ovector, int ovecsize, int *workspace, int wscount); - The function pcre_dfa_exec() is called to match a subject string - against a compiled pattern, using a matching algorithm that scans the - subject string just once, and does not backtrack. This has different - characteristics to the normal algorithm, and is not compatible with - Perl. Some of the features of PCRE patterns are not supported. Never- - theless, there are times when this kind of matching can be useful. For - a discussion of the two matching algorithms, and a list of features - that pcre_dfa_exec() does not support, see the pcrematching documenta- + The function pcre_dfa_exec() is called to match a subject string + against a compiled pattern, using a matching algorithm that scans the + subject string just once, and does not backtrack. This has different + characteristics to the normal algorithm, and is not compatible with + Perl. Some of the features of PCRE patterns are not supported. Never- + theless, there are times when this kind of matching can be useful. For + a discussion of the two matching algorithms, and a list of features + that pcre_dfa_exec() does not support, see the pcrematching documenta- tion. - The arguments for the pcre_dfa_exec() function are the same as for + The arguments for the pcre_dfa_exec() function are the same as for pcre_exec(), plus two extras. The ovector argument is used in a differ- - ent way, and this is described below. The other common arguments are - used in the same way as for pcre_exec(), so their description is not + ent way, and this is described below. The other common arguments are + used in the same way as for pcre_exec(), so their description is not repeated here. - The two additional arguments provide workspace for the function. The - workspace vector should contain at least 20 elements. It is used for + The two additional arguments provide workspace for the function. The + workspace vector should contain at least 20 elements. It is used for keeping track of multiple paths through the pattern tree. More - workspace will be needed for patterns and subjects where there are a + workspace will be needed for patterns and subjects where there are a lot of potential matches. Here is an example of a simple call to pcre_dfa_exec(): @@ -3961,55 +4116,55 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION Option bits for pcre_dfa_exec() - The unused bits of the options argument for pcre_dfa_exec() must be - zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW- + The unused bits of the options argument for pcre_dfa_exec() must be + zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW- LINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, - PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, - PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR- - TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last - four of these are exactly the same as for pcre_exec(), so their + PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, + PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR- + TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last + four of these are exactly the same as for pcre_exec(), so their description is not repeated here. PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT - These have the same general effect as they do for pcre_exec(), but the - details are slightly different. When PCRE_PARTIAL_HARD is set for - pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub- - ject is reached and there is still at least one matching possibility + These have the same general effect as they do for pcre_exec(), but the + details are slightly different. When PCRE_PARTIAL_HARD is set for + pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub- + ject is reached and there is still at least one matching possibility that requires additional characters. This happens even if some complete matches have also been found. When PCRE_PARTIAL_SOFT is set, the return code PCRE_ERROR_NOMATCH is converted into PCRE_ERROR_PARTIAL if the end - of the subject is reached, there have been no complete matches, but - there is still at least one matching possibility. The portion of the - string that was inspected when the longest partial match was found is - set as the first matching string in both cases. There is a more - detailed discussion of partial and multi-segment matching, with exam- + of the subject is reached, there have been no complete matches, but + there is still at least one matching possibility. The portion of the + string that was inspected when the longest partial match was found is + set as the first matching string in both cases. There is a more + detailed discussion of partial and multi-segment matching, with exam- ples, in the pcrepartial documentation. PCRE_DFA_SHORTEST - Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to + Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to stop as soon as it has found one match. Because of the way the alterna- - tive algorithm works, this is necessarily the shortest possible match + tive algorithm works, this is necessarily the shortest possible match at the first possible matching point in the subject string. PCRE_DFA_RESTART When pcre_dfa_exec() returns a partial match, it is possible to call it - again, with additional subject characters, and have it continue with - the same match. The PCRE_DFA_RESTART option requests this action; when - it is set, the workspace and wscount options must reference the same - vector as before because data about the match so far is left in them + again, with additional subject characters, and have it continue with + the same match. The PCRE_DFA_RESTART option requests this action; when + it is set, the workspace and wscount options must reference the same + vector as before because data about the match so far is left in them after a partial match. There is more discussion of this facility in the pcrepartial documentation. Successful returns from pcre_dfa_exec() - When pcre_dfa_exec() succeeds, it may have matched more than one sub- + When pcre_dfa_exec() succeeds, it may have matched more than one sub- string in the subject. Note, however, that all the matches from one run - of the function start at the same point in the subject. The shorter - matches are all initial substrings of the longer matches. For example, + of the function start at the same point in the subject. The shorter + matches are all initial substrings of the longer matches. For example, if the pattern <.*> @@ -4024,21 +4179,30 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION - On success, the yield of the function is a number greater than zero, - which is the number of matched substrings. The substrings themselves - are returned in ovector. Each string uses two elements; the first is - the offset to the start, and the second is the offset to the end. In - fact, all the strings have the same start offset. (Space could have - been saved by giving this only once, but it was decided to retain some - compatibility with the way pcre_exec() returns data, even though the + On success, the yield of the function is a number greater than zero, + which is the number of matched substrings. The substrings themselves + are returned in ovector. Each string uses two elements; the first is + the offset to the start, and the second is the offset to the end. In + fact, all the strings have the same start offset. (Space could have + been saved by giving this only once, but it was decided to retain some + compatibility with the way pcre_exec() returns data, even though the meaning of the strings is different.) The strings are returned in reverse order of length; that is, the long- - est matching string is given first. If there were too many matches to - fit into ovector, the yield of the function is zero, and the vector is - filled with the longest matches. Unlike pcre_exec(), pcre_dfa_exec() + 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. + NOTE: PCRE's "auto-possessification" optimization usually applies to + character repeats at the end of a pattern (as well as internally). For + example, the pattern "a\d+" is compiled as if it were "a\d++" because + there is no point even considering the possibility of backtracking into + the repeated digits. For DFA matching, this means that only one possi- + ble match is found. If you really do want multiple matches in such + cases, either use an ungreedy repeat ("a\d+?") or set the + PCRE_NO_AUTO_POSSESS option when compiling. + Error returns from pcre_dfa_exec() The pcre_dfa_exec() function returns a negative number when it fails. @@ -4101,18 +4265,18 @@ AUTHOR REVISION - Last updated: 08 November 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 09 February 2014 + Copyright (c) 1997-2014 University of Cambridge. ------------------------------------------------------------------------------ -PCRECALLOUT(3) PCRECALLOUT(3) +PCRECALLOUT(3) Library Functions Manual PCRECALLOUT(3) + NAME PCRE - Perl-compatible regular expressions - SYNOPSIS #include @@ -4153,48 +4317,88 @@ DESCRIPTION (?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255) Notice that there is a callout before and after each parenthesis and - alternation bar. Automatic callouts can be used for tracking the - progress of pattern matching. The pcretest command has an option that - sets automatic callouts; when it is used, the output indicates how the - pattern is matched. This is useful information when you are trying to - optimize the performance of a particular pattern. + alternation bar. If the pattern contains a conditional group whose con- + dition is an assertion, an automatic callout is inserted immediately + before the condition. Such a callout may also be inserted explicitly, + for example: - 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. + (?(?C9)(?=a)ab|de) + + This applies only to assertion conditions (because they are themselves + independent groups). + + Automatic callouts can be used for tracking the progress of pattern + matching. The pcretest program has a pattern qualifier (/C) that sets + automatic callouts; when it is used, the output indicates how the pat- + tern is being matched. This is useful information when you are trying + to optimize the performance of a particular pattern. MISSING CALLOUTS - You should be aware that, because of optimizations in the way PCRE - matches patterns by default, callouts sometimes do not happen. For - example, if the pattern is + You should be aware that, because of optimizations in the way PCRE com- + piles and matches patterns, callouts sometimes do not happen exactly as + you might expect. + + At compile time, PCRE "auto-possessifies" repeated items when it knows + that what follows cannot be part of the repeat. For example, a+[bc] is + compiled as if it were a++[bc]. The pcretest output when this pattern + is anchored and then applied with automatic callouts to the string + "aaaa" is: + + --->aaaa + +0 ^ ^ + +1 ^ a+ + +3 ^ ^ [bc] + No match + + This indicates that when matching [bc] fails, there is no backtracking + into a+ and therefore the callouts that would be taken for the back- + tracks do not occur. You can disable the auto-possessify feature by + passing PCRE_NO_AUTO_POSSESS to pcre_compile(), or starting the pattern + with (*NO_AUTO_POSSESS). If this is done in pcretest (using the /O + qualifier), the output changes to this: + + --->aaaa + +0 ^ ^ + +1 ^ a+ + +3 ^ ^ [bc] + +3 ^ ^ [bc] + +3 ^ ^ [bc] + +3 ^^ [bc] + No match + + This time, when matching [bc] fails, the matcher backtracks into a+ and + tries again, repeatedly, until a+ itself fails. + + Other optimizations that provide fast "no match" results also affect + callouts. For example, if the pattern is ab(?C4)cd PCRE knows that any matching string must contain the letter "d". If the - subject string is "abyz", the lack of "d" means that matching doesn't - ever start, and the callout is never reached. However, with "abyd", + subject string is "abyz", the lack of "d" means that matching doesn't + ever start, and the callout is never reached. However, with "abyd", though the result is still no match, the callout is obeyed. - If the pattern is studied, PCRE knows the minimum length of a matching - string, and will immediately give a "no match" return without actually - running a match if the subject is not long enough, or, for unanchored + If the pattern is studied, PCRE knows the minimum length of a matching + string, and will immediately give a "no match" return without actually + running a match if the subject is not long enough, or, for unanchored patterns, if it has been scanned far enough. - You can disable these optimizations by passing the PCRE_NO_START_OPTI- - MIZE option to the matching function, or by starting the pattern with - (*NO_START_OPT). This slows down the matching process, but does ensure + You can disable these optimizations by passing the PCRE_NO_START_OPTI- + MIZE option to the matching function, or by starting the pattern with + (*NO_START_OPT). This slows down the matching process, but does ensure that callouts such as the example above are obeyed. THE CALLOUT INTERFACE - During matching, when PCRE reaches a callout point, the external func- + During matching, when PCRE reaches a callout point, the external func- tion defined by pcre_callout or pcre[16|32]_callout is called (if it is - set). This applies to both normal and DFA matching. The only argument - to the callout function is a pointer to a pcre_callout or - pcre[16|32]_callout block. These structures contains the following + set). This applies to both normal and DFA matching. The only argument + to the callout function is a pointer to a pcre_callout or + pcre[16|32]_callout block. These structures contains the following fields: int version; @@ -4215,44 +4419,47 @@ THE CALLOUT INTERFACE const PCRE_UCHAR16 *mark; (16-bit version) const PCRE_UCHAR32 *mark; (32-bit version) - The version field is an integer containing the version number of the - block format. The initial version was 0; the current version is 2. The - version number will change again in future if additional fields are + The version field is an integer containing the version number of the + block format. The initial version was 0; the current version is 2. The + version number will change again in future if additional fields are added, but the intention is never to remove any of the existing fields. - The callout_number field contains the number of the callout, as com- - piled into the pattern (that is, the number after ?C for manual call- + The callout_number field contains the number of the callout, as com- + piled into the pattern (that is, the number after ?C for manual call- outs, and 255 for automatically generated callouts). - The offset_vector field is a pointer to the vector of offsets that was - passed by the caller to the matching function. When pcre_exec() or - pcre[16|32]_exec() is used, the contents can be inspected, in order to - extract substrings that have been matched so far, in the same way as - for extracting substrings after a match has completed. For the DFA + The offset_vector field is a pointer to the vector of offsets that was + passed by the caller to the matching function. When pcre_exec() or + pcre[16|32]_exec() is used, the contents can be inspected, in order to + extract substrings that have been matched so far, in the same way as + for extracting substrings after a match has completed. For the DFA matching functions, this field is not useful. The subject and subject_length fields contain copies of the values that were passed to the matching function. - The start_match field normally contains the offset within the subject - at which the current match attempt started. However, if the escape - sequence \K has been encountered, this value is changed to reflect the - modified starting point. If the pattern is not anchored, the callout + The start_match field normally contains the offset within the subject + at which the current match attempt started. However, if the escape + sequence \K has been encountered, this value is changed to reflect the + modified starting point. If the pattern is not anchored, the callout function may be called several times from the same point in the pattern for different starting points in the subject. - The current_position field contains the offset within the subject of + The current_position field contains the offset within the subject of the current match pointer. - When the pcre_exec() or pcre[16|32]_exec() is used, the capture_top - field contains one more than the number of the highest numbered cap- - tured substring so far. If no substrings have been captured, the value - of capture_top is one. This is always the case when the DFA functions + When the pcre_exec() or pcre[16|32]_exec() is used, the capture_top + field contains one more than the number of the highest numbered cap- + tured substring so far. If no substrings have been captured, the value + of capture_top is one. This is always the case when the DFA functions are used, because they do not support captured substrings. - The capture_last field contains the number of the most recently cap- - tured substring. If no substrings have been captured, its value is -1. - This is always the case for the DFA matching functions. + The capture_last field contains the number of the most recently cap- + tured substring. However, when a recursion exits, the value reverts to + what it was outside the recursion, as do the values of all captured + substrings. If no substrings have been captured, the value of cap- + ture_last is -1. This is always the case for the DFA matching func- + tions. The callout_data field contains a value that is passed to a matching function specifically so that it can be passed back in callouts. It is @@ -4310,18 +4517,18 @@ AUTHOR REVISION - Last updated: 24 June 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 12 November 2013 + Copyright (c) 1997-2013 University of Cambridge. ------------------------------------------------------------------------------ -PCRECOMPAT(3) PCRECOMPAT(3) +PCRECOMPAT(3) Library Functions Manual PCRECOMPAT(3) + NAME PCRE - Perl-compatible regular expressions - DIFFERENCES BETWEEN PCRE AND PERL This document describes the differences in the ways that PCRE and Perl @@ -4340,10 +4547,8 @@ DIFFERENCES BETWEEN PCRE AND PERL 3. Capturing subpatterns that occur inside negative lookahead asser- tions are counted, but their entries in the offsets vector are never - set. Perl sets its numerical variables from any such patterns that are - matched before the assertion fails to match something (thereby succeed- - ing), but only if the negative lookahead assertion contains just one - branch. + set. Perl sometimes (but not always) sets its numerical variables from + inside negative assertions. 4. Though binary zero characters are supported in the subject string, they are not allowed in a pattern string because it is passed as a nor- @@ -4398,24 +4603,30 @@ DIFFERENCES BETWEEN PCRE AND PERL There is a discussion that explains these differences in more detail in the section on recursion differences from Perl in the pcrepattern page. - 10. If any of the backtracking control verbs are used in an assertion - or in a subpattern that is called as a subroutine (whether or not - recursively), their effect is confined to that subpattern; it does not - extend to the surrounding pattern. This is not always the case in Perl. - In particular, if (*THEN) is present in a group that is called as a - subroutine, its action is limited to that group, even if the group does - not contain any | characters. There is one exception to this: the name - from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a success- - ful positive assertion is passed back when a match succeeds (compare - capturing parentheses in assertions). Note that such subpatterns are - processed as anchored at the point where they are tested. + 10. If any of the backtracking control verbs are used in a subpattern + that is called as a subroutine (whether or not recursively), their + effect is confined to that subpattern; it does not extend to the sur- + rounding pattern. This is not always the case in Perl. In particular, + if (*THEN) is present in a group that is called as a subroutine, its + action is limited to that group, even if the group does not contain any + | characters. Note that such subpatterns are processed as anchored at + the point where they are tested. - 11. There are some differences that are concerned with the settings of + 11. If a pattern contains more than one backtracking control verb, the + first one that is backtracked onto acts. For example, in the pattern + A(*COMMIT)B(*PRUNE)C a failure in B triggers (*COMMIT), but a failure + in C triggers (*PRUNE). Perl's behaviour is more complex; in many cases + it is the same as PCRE, but there are examples where it differs. + + 12. Most backtracking verbs in assertions have their normal actions. + They are not confined to the assertion. + + 13. There are some differences that are concerned with the settings of captured strings when part of a pattern is repeated. For example, matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b". - 12. PCRE's handling of duplicate subpattern numbers and duplicate sub- + 14. PCRE's handling of duplicate subpattern numbers and duplicate sub- pattern names is not as general as Perl's. This is a consequence of the fact the PCRE works internally just with numbers, using an external ta- ble to translate between numbers and names. In particular, a pattern @@ -4426,29 +4637,42 @@ DIFFERENCES BETWEEN PCRE AND PERL turing subpattern number 1. To avoid this confusing situation, an error is given at compile time. - 13. Perl recognizes comments in some places that PCRE does not, for + 15. Perl recognizes comments in some places that PCRE does not, for example, between the ( and ? at the start of a subpattern. If the /x - modifier is set, Perl allows white space between ( and ? but PCRE never - does, even if the PCRE_EXTENDED option is set. + modifier is set, Perl allows white space between ( and ? (though cur- + rent Perls warn that this is deprecated) but PCRE never does, even if + the PCRE_EXTENDED option is set. - 14. PCRE provides some extensions to the Perl regular expression facil- - ities. Perl 5.10 includes new features that are not in earlier ver- - sions of Perl, some of which (such as named parentheses) have been in + 16. Perl, when in warning mode, gives warnings for character classes + such as [A-\d] or [a-[:digit:]]. It then treats the hyphens as liter- + als. PCRE has no warning features, so it gives an error in these cases + because they are almost certainly user mistakes. + + 17. In PCRE, the upper/lower case character properties Lu and Ll are + not affected when case-independent matching is specified. For example, + \p{Lu} always matches an upper case letter. I think Perl has changed in + this respect; in the release at the time of writing (5.16), \p{Lu} and + \p{Ll} match all letters, regardless of case, when case independence is + specified. + + 18. PCRE provides some extensions to the Perl regular expression facil- + ities. Perl 5.10 includes new features that are not in earlier ver- + sions of Perl, some of which (such as named parentheses) have been in PCRE for some time. This list is with respect to Perl 5.10: - (a) Although lookbehind assertions in PCRE must match fixed length - strings, each alternative branch of a lookbehind assertion can match a - different length of string. Perl requires them all to have the same + (a) Although lookbehind assertions in PCRE must match fixed length + strings, each alternative branch of a lookbehind assertion can match a + different length of string. Perl requires them all to have the same length. - (b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $ + (b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $ meta-character matches only at the very end of the string. (c) If PCRE_EXTRA is set, a backslash followed by a letter with no spe- cial meaning is faulted. Otherwise, like Perl, the backslash is quietly ignored. (Perl can be made to issue a warning.) - (d) If PCRE_UNGREEDY is set, the greediness of the repetition quanti- + (d) If PCRE_UNGREEDY is set, the greediness of the repetition quanti- fiers is inverted, that is, by default they are not greedy, but if fol- lowed by a question mark they are. @@ -4456,10 +4680,10 @@ DIFFERENCES BETWEEN PCRE AND PERL tried only at the first matching position in the subject string. (f) The PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, - and PCRE_NO_AUTO_CAPTURE options for pcre_exec() have no Perl equiva- + and PCRE_NO_AUTO_CAPTURE options for pcre_exec() have no Perl equiva- lents. - (g) The \R escape sequence can be restricted to match only CR, LF, or + (g) The \R escape sequence can be restricted to match only CR, LF, or CRLF by the PCRE_BSR_ANYCRLF option. (h) The callout facility is PCRE-specific. @@ -4467,14 +4691,14 @@ DIFFERENCES BETWEEN PCRE AND PERL (i) The partial matching facility is PCRE-specific. (j) Patterns compiled by PCRE can be saved and re-used at a later time, - even on different hosts that have the other endianness. However, this + even on different hosts that have the other endianness. However, this does not apply to optimized data created by the just-in-time compiler. (k) The alternative matching functions (pcre_dfa_exec(), - pcre16_dfa_exec() and pcre32_dfa_exec(),) match in a different way and + pcre16_dfa_exec() and pcre32_dfa_exec(),) match in a different way and are not Perl-compatible. - (l) PCRE recognizes some special sequences such as (*CR) at the start + (l) PCRE recognizes some special sequences such as (*CR) at the start of a pattern that set overall options that cannot be changed within the pattern. @@ -4488,18 +4712,18 @@ AUTHOR REVISION - Last updated: 25 August 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 10 November 2013 + Copyright (c) 1997-2013 University of Cambridge. ------------------------------------------------------------------------------ -PCREPATTERN(3) PCREPATTERN(3) +PCREPATTERN(3) Library Functions Manual PCREPATTERN(3) + NAME PCRE - Perl-compatible regular expressions - PCRE REGULAR EXPRESSION DETAILS The syntax and semantics of the regular expressions that are supported @@ -4517,6 +4741,29 @@ PCRE REGULAR EXPRESSION DETAILS great detail. This description of PCRE's regular expressions is intended as reference material. + This document discusses the patterns that are supported by PCRE when + one its main matching functions, pcre_exec() (8-bit) or + pcre[16|32]_exec() (16- or 32-bit), is used. PCRE also has alternative + matching functions, pcre_dfa_exec() and pcre[16|32_dfa_exec(), which + match using a different algorithm that is not Perl-compatible. Some of + the features discussed below are not available when DFA matching is + used. The advantages and disadvantages of the alternative functions, + and how they differ from the normal functions, are discussed in the + pcrematching page. + + +SPECIAL START-OF-PATTERN ITEMS + + A number of options that can be passed to pcre_compile() can also be + set by special items at the start of a pattern. These are not Perl-com- + patible, but are provided to make these options accessible to pattern + writers who are not able to change the program that processes the pat- + tern. Any number of these items may appear, but they must all be + together right at the start of the pattern string, and the letters must + be in upper case. + + UTF support + The original operation of PCRE was on strings of one-byte characters. However, there is now also support for UTF-8 strings in the original library, an extra library that supports 16-bit and UTF-16 character @@ -4533,47 +4780,39 @@ PCRE REGULAR EXPRESSION DETAILS (*UTF) is a generic sequence that can be used with any of the libraries. Starting a pattern with such a sequence is equivalent to - setting the relevant option. This feature is not Perl-compatible. How - setting a UTF mode affects pattern matching is mentioned in several - places below. There is also a summary of features in the pcreunicode - page. + setting the relevant option. How setting a UTF mode affects pattern + matching is mentioned in several places below. There is also a summary + of features in the pcreunicode page. - Another special sequence that may appear at the start of a pattern or - in combination with (*UTF8), (*UTF16), (*UTF32) or (*UTF) is: + Some applications that allow their users to supply patterns may wish to + restrict them to non-UTF data for security reasons. If the + PCRE_NEVER_UTF option is set at compile time, (*UTF) etc. are not + allowed, and their appearance causes an error. - (*UCP) + Unicode property support - This has the same effect as setting the PCRE_UCP option: it causes - sequences such as \d and \w to use Unicode properties to determine - character types, instead of recognizing only characters with codes less - than 128 via a lookup table. + Another special sequence that may appear at the start of a pattern is + (*UCP). This has the same effect as setting the PCRE_UCP option: it + causes sequences such as \d and \w to use Unicode properties to deter- + mine character types, instead of recognizing only characters with codes + less than 128 via a lookup table. + + Disabling auto-possessification + + If a pattern starts with (*NO_AUTO_POSSESS), it has the same effect as + setting the PCRE_NO_AUTO_POSSESS option at compile time. This stops + PCRE from making quantifiers possessive when what follows cannot match + the repeated item. For example, by default a+b is treated as a++b. For + more details, see the pcreapi documentation. + + Disabling start-up optimizations If a pattern starts with (*NO_START_OPT), it has the same effect as setting the PCRE_NO_START_OPTIMIZE option either at compile or matching - time. There are also some more of these special sequences that are con- - cerned with the handling of newlines; they are described below. + time. This disables several optimizations for quickly reaching "no + match" results. For more details, see the pcreapi documentation. - The remainder of this document discusses the patterns that are sup- - ported by PCRE when one its main matching functions, pcre_exec() - (8-bit) or pcre[16|32]_exec() (16- or 32-bit), is used. PCRE also has - alternative matching functions, pcre_dfa_exec() and - pcre[16|32_dfa_exec(), which match using a different algorithm that is - not Perl-compatible. Some of the features discussed below are not - available when DFA matching is used. The advantages and disadvantages - of the alternative functions, and how they differ from the normal func- - tions, are discussed in the pcrematching page. - - -EBCDIC CHARACTER CODES - - PCRE can be compiled to run in an environment that uses EBCDIC as its - character code rather than ASCII or Unicode (typically a mainframe sys- - tem). In the sections below, character code values are ASCII or Uni- - code; in an EBCDIC environment these characters may have different code - values, and there are no code points greater than 255. - - -NEWLINE CONVENTIONS + Newline conventions PCRE supports five different conventions for indicating line breaks in strings: a single CR (carriage return) character, a single LF (line- @@ -4598,10 +4837,8 @@ NEWLINE CONVENTIONS (*CR)a.b changes the convention to CR. That pattern matches "a\nb" because LF is - no longer a newline. Note that these special settings, which are not - Perl-compatible, are recognized only at the very start of a pattern, - and that they must be in upper case. If more than one of them is - present, the last one is used. + no longer a newline. If more than one of these settings is present, the + last one is used. The newline convention affects where the circumflex and dollar asser- tions are true. It also affects the interpretation of the dot metachar- @@ -4612,6 +4849,36 @@ NEWLINE CONVENTIONS line sequences" below. A change of \R setting can be combined with a change of newline convention. + Setting match and recursion limits + + The caller of pcre_exec() can set a limit on the number of times the + internal match() function is called and on the maximum depth of recur- + sive calls. These facilities are provided to catch runaway matches that + are provoked by patterns with huge matching trees (a typical example is + a pattern with nested unlimited repeats) and to avoid running out of + system stack by too much recursion. When one of these limits is + reached, pcre_exec() gives an error return. The limits can also be set + by items at the start of the pattern of the form + + (*LIMIT_MATCH=d) + (*LIMIT_RECURSION=d) + + where d is any number of decimal digits. However, the value of the set- + ting must be less than the value set (or defaulted) by the caller of + pcre_exec() for it to have any effect. In other words, the pattern + writer can lower the limits set by the programmer, but not raise them. + If there is more than one setting of one of these limits, the lower + value is used. + + +EBCDIC CHARACTER CODES + + PCRE can be compiled to run in an environment that uses EBCDIC as its + character code rather than ASCII or Unicode (typically a mainframe sys- + tem). In the sections below, character code values are ASCII or Uni- + code; in an EBCDIC environment these characters may have different code + values, and there are no code points greater than 255. + CHARACTERS AND METACHARACTERS @@ -4689,11 +4956,11 @@ BACKSLASH after a backslash. All other characters (in particular, those whose codepoints are greater than 127) are treated as literals. - If a pattern is compiled with the PCRE_EXTENDED option, white space in - the pattern (other than in a character class) and characters between a - # outside a character class and the next newline are ignored. An escap- - ing backslash can be used to include a white space or # character as - part of the pattern. + If a pattern is compiled with the PCRE_EXTENDED option, most white + space in the pattern (other than in a character class), and characters + between a # outside a character class and the next newline, inclusive, + are ignored. An escaping backslash can be used to include a white space + or # character as part of the pattern. If you want to remove the special meaning from a sequence of charac- ters, you can do so by putting them between \Q and \E. This is differ- @@ -4731,7 +4998,9 @@ BACKSLASH \n linefeed (hex 0A) \r carriage return (hex 0D) \t tab (hex 09) + \0dd character with octal code 0dd \ddd character with octal code ddd, or back reference + \o{ddd..} character with octal code ddd.. \xhh character with hex code hh \x{hhh..} character with hex code hhh.. (non-JavaScript mode) \uhhhh character with hex code hhhh (JavaScript mode only) @@ -4754,61 +5023,38 @@ BACKSLASH are disjoint, \cZ becomes hex 29 (Z is E9), and other characters also generate different values. - By default, after \x, from zero to two hexadecimal digits are read - (letters can be in upper or lower case). Any number of hexadecimal dig- - its may appear between \x{ and }, but the character code is constrained - as follows: - - 8-bit non-UTF mode less than 0x100 - 8-bit UTF-8 mode less than 0x10ffff and a valid codepoint - 16-bit non-UTF mode less than 0x10000 - 16-bit UTF-16 mode less than 0x10ffff and a valid codepoint - 32-bit non-UTF mode less than 0x80000000 - 32-bit UTF-32 mode less than 0x10ffff and a valid codepoint - - Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so- - called "surrogate" codepoints), and 0xffef. - - If characters other than hexadecimal digits appear between \x{ and }, - or if there is no terminating }, this form of escape is not recognized. - Instead, the initial \x will be interpreted as a basic hexadecimal - escape, with no following digits, giving a character whose value is - zero. - - If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \x - is as just described only when it is followed by two hexadecimal dig- - its. Otherwise, it matches a literal "x" character. In JavaScript - mode, support for code points greater than 256 is provided by \u, which - must be followed by four hexadecimal digits; otherwise it matches a - literal "u" character. Character codes specified by \u in JavaScript - mode are constrained in the same was as those specified by \x in non- - JavaScript mode. - - Characters whose value is less than 256 can be defined by either of the - two syntaxes for \x (or by \u in JavaScript mode). There is no differ- - ence in the way they are handled. For example, \xdc is exactly the same - as \x{dc} (or \u00dc in JavaScript mode). - After \0 up to two further octal digits are read. If there are fewer than two digits, just those that are present are used. Thus the sequence \0\x\07 specifies two binary zeros followed by a BEL character (code value 7). Make sure you supply two digits after the initial zero if the pattern character that follows is itself an octal digit. + The escape \o must be followed by a sequence of octal digits, enclosed + in braces. An error occurs if this is not the case. This escape is a + recent addition to Perl; it provides way of specifying character code + points as octal numbers greater than 0777, and it also allows octal + numbers and back references to be unambiguously specified. + + For greater clarity and unambiguity, it is best to avoid following \ by + a digit greater than zero. Instead, use \o{} or \x{} to specify charac- + ter numbers, and \g{} to specify back references. The following para- + graphs describe the old, ambiguous syntax. + The handling of a backslash followed by a digit other than 0 is compli- - cated. Outside a character class, PCRE reads it and any following dig- - its as a decimal number. If the number is less than 10, or if there - have been at least that many previous capturing left parentheses in the - expression, the entire sequence is taken as a back reference. A + cated, and Perl has changed in recent releases, causing PCRE also to + change. Outside a character class, PCRE reads the digit and any follow- + ing digits as a decimal number. If the number is less than 8, or if + there have been at least that many previous capturing left parentheses + in the expression, the entire sequence is taken as a back reference. A description of how this works is given later, following the discussion of parenthesized subpatterns. - Inside a character class, or if the decimal number is greater than 9 - and there have not been that many capturing subpatterns, PCRE re-reads - up to three octal digits following the backslash, and uses them to gen- - erate a data character. Any subsequent digits stand for themselves. The - value of the character is constrained in the same way as characters - specified in hexadecimal. For example: + Inside a character class, or if the decimal number following \ is + greater than 7 and there have not been that many capturing subpatterns, + PCRE handles \8 and \9 as the literal characters "8" and "9", and oth- + erwise re-reads up to three octal digits following the backslash, using + them to generate a data character. Any subsequent digits stand for + themselves. For example: \040 is another way of writing an ASCII space \40 is the same, provided there are fewer than 40 @@ -4822,45 +5068,81 @@ BACKSLASH character with octal code 113 \377 might be a back reference, otherwise the value 255 (decimal) - \81 is either a back reference, or a binary zero - followed by the two characters "8" and "1" + \81 is either a back reference, or the two + characters "8" and "1" - Note that octal values of 100 or greater must not be introduced by a - leading zero, because no more than three octal digits are ever read. + Note that octal values of 100 or greater that are specified using this + syntax must not be introduced by a leading zero, because no more than + three octal digits are ever read. + + By default, after \x that is not followed by {, from zero to two hexa- + decimal digits are read (letters can be in upper or lower case). Any + number of hexadecimal digits may appear between \x{ and }. If a charac- + ter other than a hexadecimal digit appears between \x{ and }, or if + there is no terminating }, an error occurs. + + If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \x + is as just described only when it is followed by two hexadecimal dig- + its. Otherwise, it matches a literal "x" character. In JavaScript + mode, support for code points greater than 256 is provided by \u, which + must be followed by four hexadecimal digits; otherwise it matches a + literal "u" character. + + Characters whose value is less than 256 can be defined by either of the + two syntaxes for \x (or by \u in JavaScript mode). There is no differ- + ence in the way they are handled. For example, \xdc is exactly the same + as \x{dc} (or \u00dc in JavaScript mode). + + Constraints on character values + + Characters that are specified using octal or hexadecimal numbers are + limited to certain values, as follows: + + 8-bit non-UTF mode less than 0x100 + 8-bit UTF-8 mode less than 0x10ffff and a valid codepoint + 16-bit non-UTF mode less than 0x10000 + 16-bit UTF-16 mode less than 0x10ffff and a valid codepoint + 32-bit non-UTF mode less than 0x100000000 + 32-bit UTF-32 mode less than 0x10ffff and a valid codepoint + + Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so- + called "surrogate" codepoints), and 0xffef. + + Escape sequences in character classes All the sequences that define a single character value can be used both - inside and outside character classes. In addition, inside a character + inside and outside character classes. In addition, inside a character class, \b is interpreted as the backspace character (hex 08). - \N is not allowed in a character class. \B, \R, and \X are not special - inside a character class. Like other unrecognized escape sequences, - they are treated as the literal characters "B", "R", and "X" by - default, but cause an error if the PCRE_EXTRA option is set. Outside a + \N is not allowed in a character class. \B, \R, and \X are not special + inside a character class. Like other unrecognized escape sequences, + they are treated as the literal characters "B", "R", and "X" by + default, but cause an error if the PCRE_EXTRA option is set. Outside a character class, these sequences have different meanings. Unsupported escape sequences - In Perl, the sequences \l, \L, \u, and \U are recognized by its string - handler and used to modify the case of following characters. By - default, PCRE does not support these escape sequences. However, if the - PCRE_JAVASCRIPT_COMPAT option is set, \U matches a "U" character, and + In Perl, the sequences \l, \L, \u, and \U are recognized by its string + handler and used to modify the case of following characters. By + default, PCRE does not support these escape sequences. However, if the + PCRE_JAVASCRIPT_COMPAT option is set, \U matches a "U" character, and \u can be used to define a character by code point, as described in the previous section. Absolute and relative back references - The sequence \g followed by an unsigned or a negative number, option- - ally enclosed in braces, is an absolute or relative back reference. A + The sequence \g followed by an unsigned or a negative number, option- + ally enclosed in braces, is an absolute or relative back reference. A named back reference can be coded as \g{name}. Back references are dis- cussed later, following the discussion of parenthesized subpatterns. Absolute and relative subroutine calls - For compatibility with Oniguruma, the non-Perl syntax \g followed by a + For compatibility with Oniguruma, the non-Perl syntax \g followed by a name or a number enclosed either in angle brackets or single quotes, is - an alternative syntax for referencing a subpattern as a "subroutine". - Details are discussed later. Note that \g{...} (Perl syntax) and - \g<...> (Oniguruma syntax) are not synonymous. The former is a back + an alternative syntax for referencing a subpattern as a "subroutine". + Details are discussed later. Note that \g{...} (Perl syntax) and + \g<...> (Oniguruma syntax) are not synonymous. The former is a back reference; the latter is a subroutine call. Generic character types @@ -4879,44 +5161,49 @@ BACKSLASH \W any "non-word" character There is also the single sequence \N, which matches a non-newline char- - acter. This is the same as the "." metacharacter when PCRE_DOTALL is - not set. Perl also uses \N to match characters by name; PCRE does not + acter. This is the same as the "." metacharacter when PCRE_DOTALL is + not set. Perl also uses \N to match characters by name; PCRE does not support this. - Each pair of lower and upper case escape sequences partitions the com- - plete set of characters into two disjoint sets. Any given character - matches one, and only one, of each pair. The sequences can appear both - inside and outside character classes. They each match one character of - the appropriate type. If the current matching point is at the end of - the subject string, all of them fail, because there is no character to + Each pair of lower and upper case escape sequences partitions the com- + plete set of characters into two disjoint sets. Any given character + matches one, and only one, of each pair. The sequences can appear both + inside and outside character classes. They each match one character of + the appropriate type. If the current matching point is at the end of + the subject string, all of them fail, because there is no character to match. - For compatibility with Perl, \s does not match the VT character (code - 11). This makes it different from the the POSIX "space" class. The \s - characters are HT (9), LF (10), FF (12), CR (13), and space (32). If - "use locale;" is included in a Perl script, \s may match the VT charac- - ter. In PCRE, it never does. + For compatibility with Perl, \s did not used to match the VT character + (code 11), which made it different from the the POSIX "space" class. + However, Perl added VT at release 5.18, and PCRE followed suit at + release 8.34. The default \s characters are now HT (9), LF (10), VT + (11), FF (12), CR (13), and space (32), which are defined as white + space in the "C" locale. This list may vary if locale-specific matching + is taking place. For example, in some locales the "non-breaking space" + character (\xA0) is recognized as white space, and in others the VT + character is not. - A "word" character is an underscore or any character that is a letter - or digit. By default, the definition of letters and digits is con- - trolled by PCRE's low-valued character tables, and may vary if locale- - specific matching is taking place (see "Locale support" in the pcreapi - page). For example, in a French locale such as "fr_FR" in Unix-like - systems, or "french" in Windows, some character codes greater than 128 - are used for accented letters, and these are then matched by \w. The + A "word" character is an underscore or any character that is a letter + or digit. By default, the definition of letters and digits is con- + trolled by PCRE's low-valued character tables, and may vary if locale- + specific matching is taking place (see "Locale support" in the pcreapi + page). For example, in a French locale such as "fr_FR" in Unix-like + systems, or "french" in Windows, some character codes greater than 127 + are used for accented letters, and these are then matched by \w. The use of locales with Unicode is discouraged. - By default, in a UTF mode, characters with values greater than 128 - never match \d, \s, or \w, and always match \D, \S, and \W. These - sequences retain their original meanings from before UTF support was - available, mainly for efficiency reasons. However, if PCRE is compiled - with Unicode property support, and the PCRE_UCP option is set, the be- - haviour is changed so that Unicode properties are used to determine - character types, as follows: + By default, characters whose code points are greater than 127 never + match \d, \s, or \w, and always match \D, \S, and \W, although this may + vary for characters in the range 128-255 when locale-specific matching + is happening. These escape sequences retain their original meanings + from before Unicode support was available, mainly for efficiency rea- + sons. If PCRE is compiled with Unicode property support, and the + PCRE_UCP option is set, the behaviour is changed so that Unicode prop- + erties are used to determine character types, as follows: - \d any character that \p{Nd} matches (decimal digit) - \s any character that \p{Z} matches, plus HT, LF, FF, CR - \w any character that \p{L} or \p{N} matches, plus underscore + \d any character that matches \p{Nd} (decimal digit) + \s any character that matches \p{Z} or \h or \v + \w any character that matches \p{L} or \p{N}, plus underscore The upper case escapes match the inverse sets of characters. Note that \d matches only decimal digits, whereas \w matches any Unicode digit, @@ -4927,7 +5214,7 @@ BACKSLASH The sequences \h, \H, \v, and \V are features that were added to Perl at release 5.10. In contrast to the other sequences, which match only ASCII characters by default, these always match certain high-valued - codepoints, whether or not PCRE_UCP is set. The horizontal space char- + code points, whether or not PCRE_UCP is set. The horizontal space char- acters are: U+0009 Horizontal tab (HT) @@ -5136,52 +5423,53 @@ BACKSLASH in the Unicode table. Specifying caseless matching does not affect these escape sequences. - For example, \p{Lu} always matches only upper case letters. + For example, \p{Lu} always matches only upper case letters. This is + different from the behaviour of current versions of Perl. - Matching characters by Unicode property is not fast, because PCRE has - to do a multistage table lookup in order to find a character's prop- + Matching characters by Unicode property is not fast, because PCRE has + to do a multistage table lookup in order to find a character's prop- erty. That is why the traditional escape sequences such as \d and \w do not use Unicode properties in PCRE by default, though you can make them - do so by setting the PCRE_UCP option or by starting the pattern with + do so by setting the PCRE_UCP option or by starting the pattern with (*UCP). Extended grapheme clusters - The \X escape matches any number of Unicode characters that form an + The \X escape matches any number of Unicode characters that form an "extended grapheme cluster", and treats the sequence as an atomic group - (see below). Up to and including release 8.31, PCRE matched an ear- + (see below). Up to and including release 8.31, PCRE matched an ear- lier, simpler definition that was equivalent to (?>\PM\pM*) - That is, it matched a character without the "mark" property, followed - by zero or more characters with the "mark" property. Characters with - the "mark" property are typically non-spacing accents that affect the + That is, it matched a character without the "mark" property, followed + by zero or more characters with the "mark" property. Characters with + the "mark" property are typically non-spacing accents that affect the preceding character. - This simple definition was extended in Unicode to include more compli- - cated kinds of composite character by giving each character a grapheme - breaking property, and creating rules that use these properties to - define the boundaries of extended grapheme clusters. In releases of + This simple definition was extended in Unicode to include more compli- + cated kinds of composite character by giving each character a grapheme + breaking property, and creating rules that use these properties to + define the boundaries of extended grapheme clusters. In releases of PCRE later than 8.31, \X matches one of these clusters. - \X always matches at least one character. Then it decides whether to + \X always matches at least one character. Then it decides whether to add additional characters according to the following rules for ending a cluster: 1. End at the end of the subject string. - 2. Do not end between CR and LF; otherwise end after any control char- + 2. Do not end between CR and LF; otherwise end after any control char- acter. - 3. Do not break Hangul (a Korean script) syllable sequences. Hangul - characters are of five types: L, V, T, LV, and LVT. An L character may - be followed by an L, V, LV, or LVT character; an LV or V character may + 3. Do not break Hangul (a Korean script) syllable sequences. Hangul + characters are of five types: L, V, T, LV, and LVT. An L character may + be followed by an L, V, LV, or LVT character; an LV or V character may be followed by a V or T character; an LVT or T character may be follwed only by a T character. - 4. Do not end before extending characters or spacing marks. Characters - with the "mark" property always have the "extend" grapheme breaking + 4. Do not end before extending characters or spacing marks. Characters + with the "mark" property always have the "extend" grapheme breaking property. 5. Do not end after prepend characters. @@ -5190,51 +5478,65 @@ BACKSLASH PCRE's additional properties - As well as the standard Unicode properties described above, PCRE sup- - ports four more that make it possible to convert traditional escape - sequences such as \w and \s and POSIX character classes to use Unicode - properties. PCRE uses these non-standard, non-Perl properties inter- - nally when PCRE_UCP is set. They are: + As well as the standard Unicode properties described above, PCRE sup- + ports four more that make it possible to convert traditional escape + sequences such as \w and \s to use Unicode properties. PCRE uses these + non-standard, non-Perl properties internally when PCRE_UCP is set. How- + ever, they may also be used explicitly. These properties are: Xan Any alphanumeric character Xps Any POSIX space character Xsp Any Perl space character Xwd Any Perl "word" character - Xan matches characters that have either the L (letter) or the N (num- - ber) property. Xps matches the characters tab, linefeed, vertical tab, - form feed, or carriage return, and any other character that has the Z - (separator) property. Xsp is the same as Xps, except that vertical tab - is excluded. Xwd matches the same characters as Xan, plus underscore. + Xan matches characters that have either the L (letter) or the N (num- + ber) property. Xps matches the characters tab, linefeed, vertical tab, + form feed, or carriage return, and any other character that has the Z + (separator) property. Xsp is the same as Xps; it used to exclude ver- + tical tab, for Perl compatibility, but Perl changed, and so PCRE fol- + lowed at release 8.34. Xwd matches the same characters as Xan, plus + underscore. + + There is another non-standard property, Xuc, which matches any charac- + ter that can be represented by a Universal Character Name in C++ and + other programming languages. These are the characters $, @, ` (grave + accent), and all characters with Unicode code points greater than or + equal to U+00A0, except for the surrogates U+D800 to U+DFFF. Note that + most base (ASCII) characters are excluded. (Universal Character Names + are of the form \uHHHH or \UHHHHHHHH where H is a hexadecimal digit. + Note that the Xuc property does not match these sequences but the char- + acters that they represent.) Resetting the match start - The escape sequence \K causes any previously matched characters not to + The escape sequence \K causes any previously matched characters not to be included in the final matched sequence. For example, the pattern: foo\Kbar - matches "foobar", but reports that it has matched "bar". This feature - is similar to a lookbehind assertion (described below). However, in - this case, the part of the subject before the real match does not have - to be of fixed length, as lookbehind assertions do. The use of \K does - not interfere with the setting of captured substrings. For example, + matches "foobar", but reports that it has matched "bar". This feature + is similar to a lookbehind assertion (described below). However, in + this case, the part of the subject before the real match does not have + to be of fixed length, as lookbehind assertions do. The use of \K does + not interfere with the setting of captured substrings. For example, when the pattern (foo)\Kbar matches "foobar", the first substring is still set to "foo". - Perl documents that the use of \K within assertions is "not well - defined". In PCRE, \K is acted upon when it occurs inside positive - assertions, but is ignored in negative assertions. + 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. Note that when a + pattern such as (?=ab\K) matches, the reported start of the match can + be greater than the end of the match. Simple assertions - The final use of backslash is for certain simple assertions. An asser- - tion specifies a condition that has to be met at a particular point in - a match, without consuming any characters from the subject string. The - use of subpatterns for more complicated assertions is described below. + The final use of backslash is for certain simple assertions. An asser- + tion specifies a condition that has to be met at a particular point in + a match, without consuming any characters from the subject string. The + use of subpatterns for more complicated assertions is described below. The backslashed assertions are: \b matches at a word boundary @@ -5245,161 +5547,161 @@ BACKSLASH \z matches only at the end of the subject \G matches at the first matching position in the subject - Inside a character class, \b has a different meaning; it matches the - backspace character. If any other of these assertions appears in a - character class, by default it matches the corresponding literal char- + Inside a character class, \b has a different meaning; it matches the + backspace character. If any other of these assertions appears in a + character class, by default it matches the corresponding literal char- acter (for example, \B matches the letter B). However, if the - PCRE_EXTRA option is set, an "invalid escape sequence" error is gener- + PCRE_EXTRA option is set, an "invalid escape sequence" error is gener- ated instead. - A word boundary is a position in the subject string where the current - character and the previous character do not both match \w or \W (i.e. - one matches \w and the other matches \W), or the start or end of the - string if the first or last character matches \w, respectively. In a - UTF mode, the meanings of \w and \W can be changed by setting the - PCRE_UCP option. When this is done, it also affects \b and \B. Neither - PCRE nor Perl has a separate "start of word" or "end of word" metase- - quence. However, whatever follows \b normally determines which it is. + A word boundary is a position in the subject string where the current + character and the previous character do not both match \w or \W (i.e. + one matches \w and the other matches \W), or the start or end of the + string if the first or last character matches \w, respectively. In a + UTF mode, the meanings of \w and \W can be changed by setting the + PCRE_UCP option. When this is done, it also affects \b and \B. Neither + PCRE nor Perl has a separate "start of word" or "end of word" metase- + quence. However, whatever follows \b normally determines which it is. For example, the fragment \ba matches "a" at the start of a word. - The \A, \Z, and \z assertions differ from the traditional circumflex + The \A, \Z, and \z assertions differ from the traditional circumflex and dollar (described in the next section) in that they only ever match - at the very start and end of the subject string, whatever options are - set. Thus, they are independent of multiline mode. These three asser- + at the very start and end of the subject string, whatever options are + set. Thus, they are independent of multiline mode. These three asser- tions are not affected by the PCRE_NOTBOL or PCRE_NOTEOL options, which - affect only the behaviour of the circumflex and dollar metacharacters. - However, if the startoffset argument of pcre_exec() is non-zero, indi- + affect only the behaviour of the circumflex and dollar metacharacters. + However, if the startoffset argument of pcre_exec() is non-zero, indi- cating that matching is to start at a point other than the beginning of - the subject, \A can never match. The difference between \Z and \z is + the subject, \A can never match. The difference between \Z and \z is that \Z matches before a newline at the end of the string as well as at the very end, whereas \z matches only at the end. - The \G assertion is true only when the current matching position is at - the start point of the match, as specified by the startoffset argument - of pcre_exec(). It differs from \A when the value of startoffset is - non-zero. By calling pcre_exec() multiple times with appropriate argu- + The \G assertion is true only when the current matching position is at + the start point of the match, as specified by the startoffset argument + of pcre_exec(). It differs from \A when the value of startoffset is + non-zero. By calling pcre_exec() multiple times with appropriate argu- ments, you can mimic Perl's /g option, and it is in this kind of imple- mentation where \G can be useful. - Note, however, that PCRE's interpretation of \G, as the start of the + Note, however, that PCRE's interpretation of \G, as the start of the current match, is subtly different from Perl's, which defines it as the - end of the previous match. In Perl, these can be different when the - previously matched string was empty. Because PCRE does just one match + end of the previous match. In Perl, these can be different when the + previously matched string was empty. Because PCRE does just one match at a time, it cannot reproduce this behaviour. - If all the alternatives of a pattern begin with \G, the expression is + If all the alternatives of a pattern begin with \G, the expression is anchored to the starting match position, and the "anchored" flag is set in the compiled regular expression. CIRCUMFLEX AND DOLLAR - The circumflex and dollar metacharacters are zero-width assertions. - That is, they test for a particular condition being true without con- + The circumflex and dollar metacharacters are zero-width assertions. + That is, they test for a particular condition being true without con- suming any characters from the subject string. Outside a character class, in the default matching mode, the circumflex - character is an assertion that is true only if the current matching - point is at the start of the subject string. If the startoffset argu- - ment of pcre_exec() is non-zero, circumflex can never match if the - PCRE_MULTILINE option is unset. Inside a character class, circumflex + character is an assertion that is true only if the current matching + point is at the start of the subject string. If the startoffset argu- + ment of pcre_exec() is non-zero, circumflex can never match if the + PCRE_MULTILINE option is unset. Inside a character class, circumflex has an entirely different meaning (see below). - Circumflex need not be the first character of the pattern if a number - of alternatives are involved, but it should be the first thing in each - alternative in which it appears if the pattern is ever to match that - branch. If all possible alternatives start with a circumflex, that is, - if the pattern is constrained to match only at the start of the sub- - ject, it is said to be an "anchored" pattern. (There are also other + Circumflex need not be the first character of the pattern if a number + of alternatives are involved, but it should be the first thing in each + alternative in which it appears if the pattern is ever to match that + branch. If all possible alternatives start with a circumflex, that is, + if the pattern is constrained to match only at the start of the sub- + ject, it is said to be an "anchored" pattern. (There are also other constructs that can cause a pattern to be anchored.) - The dollar character is an assertion that is true only if the current - matching point is at the end of the subject string, or immediately - before a newline at the end of the string (by default). Note, however, - that it does not actually match the newline. Dollar need not be the + The dollar character is an assertion that is true only if the current + matching point is at the end of the subject string, or immediately + before a newline at the end of the string (by default). Note, however, + that it does not actually match the newline. Dollar need not be the last character of the pattern if a number of alternatives are involved, - but it should be the last item in any branch in which it appears. Dol- + but it should be the last item in any branch in which it appears. Dol- lar has no special meaning in a character class. - The meaning of dollar can be changed so that it matches only at the - very end of the string, by setting the PCRE_DOLLAR_ENDONLY option at + The meaning of dollar can be changed so that it matches only at the + very end of the string, by setting the PCRE_DOLLAR_ENDONLY option at compile time. This does not affect the \Z assertion. The meanings of the circumflex and dollar characters are changed if the - PCRE_MULTILINE option is set. When this is the case, a circumflex - matches immediately after internal newlines as well as at the start of - the subject string. It does not match after a newline that ends the - string. A dollar matches before any newlines in the string, as well as - at the very end, when PCRE_MULTILINE is set. When newline is specified - as the two-character sequence CRLF, isolated CR and LF characters do + PCRE_MULTILINE option is set. When this is the case, a circumflex + matches immediately after internal newlines as well as at the start of + the subject string. It does not match after a newline that ends the + string. A dollar matches before any newlines in the string, as well as + at the very end, when PCRE_MULTILINE is set. When newline is specified + as the two-character sequence CRLF, isolated CR and LF characters do not indicate newlines. - For example, the pattern /^abc$/ matches the subject string "def\nabc" - (where \n represents a newline) in multiline mode, but not otherwise. - Consequently, patterns that are anchored in single line mode because - all branches start with ^ are not anchored in multiline mode, and a - match for circumflex is possible when the startoffset argument of - pcre_exec() is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if + For example, the pattern /^abc$/ matches the subject string "def\nabc" + (where \n represents a newline) in multiline mode, but not otherwise. + Consequently, patterns that are anchored in single line mode because + all branches start with ^ are not anchored in multiline mode, and a + match for circumflex is possible when the startoffset argument of + pcre_exec() is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if PCRE_MULTILINE is set. - Note that the sequences \A, \Z, and \z can be used to match the start - and end of the subject in both modes, and if all branches of a pattern - start with \A it is always anchored, whether or not PCRE_MULTILINE is + Note that the sequences \A, \Z, and \z can be used to match the start + and end of the subject in both modes, and if all branches of a pattern + start with \A it is always anchored, whether or not PCRE_MULTILINE is set. FULL STOP (PERIOD, DOT) AND \N Outside a character class, a dot in the pattern matches any one charac- - ter in the subject string except (by default) a character that signi- + ter in the subject string except (by default) a character that signi- fies the end of a line. - When a line ending is defined as a single character, dot never matches - that character; when the two-character sequence CRLF is used, dot does - not match CR if it is immediately followed by LF, but otherwise it - matches all characters (including isolated CRs and LFs). When any Uni- - code line endings are being recognized, dot does not match CR or LF or + When a line ending is defined as a single character, dot never matches + that character; when the two-character sequence CRLF is used, dot does + not match CR if it is immediately followed by LF, but otherwise it + matches all characters (including isolated CRs and LFs). When any Uni- + code line endings are being recognized, dot does not match CR or LF or any of the other line ending characters. - The behaviour of dot with regard to newlines can be changed. If the - PCRE_DOTALL option is set, a dot matches any one character, without + The behaviour of dot with regard to newlines can be changed. If the + PCRE_DOTALL option is set, a dot matches any one character, without exception. If the two-character sequence CRLF is present in the subject string, it takes two dots to match it. - The handling of dot is entirely independent of the handling of circum- - flex and dollar, the only relationship being that they both involve + The handling of dot is entirely independent of the handling of circum- + flex and dollar, the only relationship being that they both involve newlines. Dot has no special meaning in a character class. - The escape sequence \N behaves like a dot, except that it is not - affected by the PCRE_DOTALL option. In other words, it matches any - character except one that signifies the end of a line. Perl also uses + The escape sequence \N behaves like a dot, except that it is not + affected by the PCRE_DOTALL option. In other words, it matches any + character except one that signifies the end of a line. Perl also uses \N to match characters by name; PCRE does not support this. MATCHING A SINGLE DATA UNIT - Outside a character class, the escape sequence \C matches any one data - unit, whether or not a UTF mode is set. In the 8-bit library, one data - unit is one byte; in the 16-bit library it is a 16-bit unit; in the - 32-bit library it is a 32-bit unit. Unlike a dot, \C always matches - line-ending characters. The feature is provided in Perl in order to + Outside a character class, the escape sequence \C matches any one data + unit, whether or not a UTF mode is set. In the 8-bit library, one data + unit is one byte; in the 16-bit library it is a 16-bit unit; in the + 32-bit library it is a 32-bit unit. Unlike a dot, \C always matches + line-ending characters. The feature is provided in Perl in order to match individual bytes in UTF-8 mode, but it is unclear how it can use- - fully be used. Because \C breaks up characters into individual data - units, matching one unit with \C in a UTF mode means that the rest of + fully be used. Because \C breaks up characters into individual data + units, matching one unit with \C in a UTF mode means that the rest of the string may start with a malformed UTF character. This has undefined results, because PCRE assumes that it is dealing with valid UTF strings - (and by default it checks this at the start of processing unless the - PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK or PCRE_NO_UTF32_CHECK option + (and by default it checks this at the start of processing unless the + PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK or PCRE_NO_UTF32_CHECK option is used). - PCRE does not allow \C to appear in lookbehind assertions (described - below) in a UTF mode, because this would make it impossible to calcu- + PCRE does not allow \C to appear in lookbehind assertions (described + below) in a UTF mode, because this would make it impossible to calcu- late the length of the lookbehind. In general, the \C escape sequence is best avoided. However, one way of - using it that avoids the problem of malformed UTF characters is to use - a lookahead to check the length of the next character, as in this pat- - tern, which could be used with a UTF-8 string (ignore white space and + using it that avoids the problem of malformed UTF characters is to use + a lookahead to check the length of the next character, as in this pat- + tern, which could be used with a UTF-8 string (ignore white space and line breaks): (?| (?=[\x00-\x7f])(\C) | @@ -5407,11 +5709,11 @@ MATCHING A SINGLE DATA UNIT (?=[\x{800}-\x{ffff}])(\C)(\C)(\C) | (?=[\x{10000}-\x{1fffff}])(\C)(\C)(\C)(\C)) - A group that starts with (?| resets the capturing parentheses numbers - in each alternative (see "Duplicate Subpattern Numbers" below). The - assertions at the start of each branch check the next UTF-8 character - for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The - character's individual bytes are then captured by the appropriate num- + A group that starts with (?| resets the capturing parentheses numbers + in each alternative (see "Duplicate Subpattern Numbers" below). The + assertions at the start of each branch check the next UTF-8 character + for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The + character's individual bytes are then captured by the appropriate num- ber of groups. @@ -5421,64 +5723,71 @@ SQUARE BRACKETS AND CHARACTER CLASSES closing square bracket. A closing square bracket on its own is not spe- cial by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set, a lone closing square bracket causes a compile-time error. If a closing - square bracket is required as a member of the class, it should be the - first data character in the class (after an initial circumflex, if + square bracket is required as a member of the class, it should be the + first data character in the class (after an initial circumflex, if present) or escaped with a backslash. - A character class matches a single character in the subject. In a UTF - mode, the character may be more than one data unit long. A matched + A character class matches a single character in the subject. In a UTF + mode, the character may be more than one data unit long. A matched character must be in the set of characters defined by the class, unless - the first character in the class definition is a circumflex, in which + the first character in the class definition is a circumflex, in which case the subject character must not be in the set defined by the class. - If a circumflex is actually required as a member of the class, ensure + If a circumflex is actually required as a member of the class, ensure it is not the first character, or escape it with a backslash. - For example, the character class [aeiou] matches any lower case vowel, - while [^aeiou] matches any character that is not a lower case vowel. + For example, the character class [aeiou] matches any lower case vowel, + while [^aeiou] matches any character that is not a lower case vowel. Note that a circumflex is just a convenient notation for specifying the - characters that are in the class by enumerating those that are not. A - class that starts with a circumflex is not an assertion; it still con- - sumes a character from the subject string, and therefore it fails if + characters that are in the class by enumerating those that are not. A + class that starts with a circumflex is not an assertion; it still con- + sumes a character from the subject string, and therefore it fails if the current pointer is at the end of the string. In UTF-8 (UTF-16, UTF-32) mode, characters with values greater than 255 - (0xffff) can be included in a class as a literal string of data units, + (0xffff) can be included in a class as a literal string of data units, or by using the \x{ escaping mechanism. - When caseless matching is set, any letters in a class represent both - their upper case and lower case versions, so for example, a caseless - [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not - match "A", whereas a caseful version would. In a UTF mode, PCRE always - understands the concept of case for characters whose values are less - than 128, so caseless matching is always possible. For characters with - higher values, the concept of case is supported if PCRE is compiled - with Unicode property support, but not otherwise. If you want to use - caseless matching in a UTF mode for characters 128 and above, you must - ensure that PCRE is compiled with Unicode property support as well as + When caseless matching is set, any letters in a class represent both + their upper case and lower case versions, so for example, a caseless + [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not + match "A", whereas a caseful version would. In a UTF mode, PCRE always + understands the concept of case for characters whose values are less + than 128, so caseless matching is always possible. For characters with + higher values, the concept of case is supported if PCRE is compiled + with Unicode property support, but not otherwise. If you want to use + caseless matching in a UTF mode for characters 128 and above, you must + ensure that PCRE is compiled with Unicode property support as well as with UTF support. - Characters that might indicate line breaks are never treated in any - special way when matching character classes, whatever line-ending - sequence is in use, and whatever setting of the PCRE_DOTALL and + Characters that might indicate line breaks are never treated in any + special way when matching character classes, whatever line-ending + sequence is in use, and whatever setting of the PCRE_DOTALL and PCRE_MULTILINE options is used. A class such as [^a] always matches one of these characters. - The minus (hyphen) character can be used to specify a range of charac- - ters in a character class. For example, [d-m] matches any letter - between d and m, inclusive. If a minus character is required in a - class, it must be escaped with a backslash or appear in a position - where it cannot be interpreted as indicating a range, typically as the - first or last character in the class. + The minus (hyphen) character can be used to specify a range of charac- + ters in a character class. For example, [d-m] matches any letter + between d and m, inclusive. If a minus character is required in a + class, it must be escaped with a backslash or appear in a position + where it cannot be interpreted as indicating a range, typically as the + first or last character in the class, or immediately after a range. For + example, [b-d-z] matches letters in the range b to d, a hyphen charac- + ter, or z. It is not possible to have the literal character "]" as the end charac- - ter of a range. A pattern such as [W-]46] is interpreted as a class of - two characters ("W" and "-") followed by a literal string "46]", so it - would match "W46]" or "-46]". However, if the "]" is escaped with a - backslash it is interpreted as the end of range, so [W-\]46] is inter- - preted as a class containing a range followed by two other characters. - The octal or hexadecimal representation of "]" can also be used to end + ter of a range. A pattern such as [W-]46] is interpreted as a class of + two characters ("W" and "-") followed by a literal string "46]", so it + would match "W46]" or "-46]". However, if the "]" is escaped with a + backslash it is interpreted as the end of range, so [W-\]46] is inter- + preted as a class containing a range followed by two other characters. + The octal or hexadecimal representation of "]" can also be used to end a range. + An error is generated if a POSIX character class (see below) or an + escape sequence other than one that defines a single character appears + at a point where a range ending character is expected. For example, + [z-\xff] is valid, but [A-\d] and [A-[:digit:]] are not. + Ranges operate in the collating sequence of character values. They can also be used for characters specified numerically, for example [\000-\037]. Ranges can include any characters that are valid for the @@ -5515,15 +5824,16 @@ SQUARE BRACKETS AND CHARACTER CLASSES The only metacharacters that are recognized in character classes are backslash, hyphen (only where it can be interpreted as specifying a range), circumflex (only at the start), opening square bracket (only - when it can be interpreted as introducing a POSIX class name - see the - next section), and the terminating closing square bracket. However, - escaping other non-alphanumeric characters does no harm. + when it can be interpreted as introducing a POSIX class name, or for a + special compatibility feature - see the next two sections), and the + terminating closing square bracket. However, escaping other non- + alphanumeric characters does no harm. POSIX CHARACTER CLASSES Perl supports the POSIX notation for character classes. This uses names - enclosed by [: and :] within the enclosing square brackets. PCRE also + enclosed by [: and :] within the enclosing square brackets. PCRE also supports this notation. For example, [01[:alpha:]%] @@ -5541,15 +5851,18 @@ POSIX CHARACTER CLASSES lower lower case letters print printing characters, including space punct printing characters, excluding letters and digits and space - space white space (not quite the same as \s) + space white space (the same as \s from PCRE 8.34) upper upper case letters word "word" characters (same as \w) xdigit hexadecimal digits - The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), - and space (32). Notice that this list includes the VT character (code - 11). This makes "space" different to \s, which does not include VT (for - Perl compatibility). + The default "space" characters are HT (9), LF (10), VT (11), FF (12), + CR (13), and space (32). If locale-specific matching is taking place, + the list of space characters may be different; there may be fewer or + more of them. "Space" used to be different to \s, which did not include + VT, for Perl compatibility. However, Perl changed at release 5.18, and + PCRE followed at release 8.34. "Space" and \s now match the same set + of characters. The name "word" is a Perl extension, and "blank" is a GNU extension from Perl 5.8. Another Perl extension is negation, which is indicated @@ -5561,11 +5874,11 @@ POSIX CHARACTER CLASSES POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not supported, and an error is given if they are encountered. - By default, in UTF modes, characters with values greater than 128 do - not match any of the POSIX character classes. However, if the PCRE_UCP - option is passed to pcre_compile(), some of the classes are changed so - that Unicode character properties are used. This is achieved by replac- - ing the POSIX classes by other sequences, as follows: + By default, characters with values greater than 128 do not match any of + the POSIX character classes. However, if the PCRE_UCP option is passed + to pcre_compile(), some of the classes are changed so that Unicode + character properties are used. This is achieved by replacing certain + POSIX classes by other sequences, as follows: [:alnum:] becomes \p{Xan} [:alpha:] becomes \p{L} @@ -5576,9 +5889,48 @@ POSIX CHARACTER CLASSES [:upper:] becomes \p{Lu} [:word:] becomes \p{Xwd} - Negated versions, such as [:^alpha:] use \P instead of \p. The other - POSIX classes are unchanged, and match only characters with code points - less than 128. + Negated versions, such as [:^alpha:] use \P instead of \p. Three other + POSIX classes are handled specially in UCP mode: + + [:graph:] This matches characters that have glyphs that mark the page + when printed. In Unicode property terms, it matches all char- + acters with the L, M, N, P, S, or Cf properties, except for: + + U+061C Arabic Letter Mark + U+180E Mongolian Vowel Separator + U+2066 - U+2069 Various "isolate"s + + + [:print:] This matches the same characters as [:graph:] plus space + characters that are not controls, that is, characters with + the Zs property. + + [:punct:] This matches all characters that have the Unicode P (punctua- + tion) property, plus those characters whose code points are + less than 128 that have the S (Symbol) property. + + The other POSIX classes are unchanged, and match only characters with + code points less than 128. + + +COMPATIBILITY FEATURE FOR WORD BOUNDARIES + + In the POSIX.2 compliant library that was included in 4.4BSD Unix, the + ugly syntax [[:<:]] and [[:>:]] is used for matching "start of word" + and "end of word". PCRE treats these items as follows: + + [[:<:]] is converted to \b(?=\w) + [[:>:]] is converted to \b(?<=\w) + + Only these exact character sequences are recognized. A sequence such as + [a[:<:]b] provokes error for an unrecognized POSIX class name. This + support is not compatible with Perl. It is provided to help migrations + from other environments, and is best not used in any new patterns. Note + that \b matches at the start and the end of a word (see "Simple asser- + tions" above), and in a Perl-style pattern the preceding or following + character normally shows which is wanted, without the need for the + assertions that are used above in order to give exactly the POSIX be- + haviour. VERTICAL BAR @@ -5653,7 +6005,9 @@ INTERNAL OPTION SETTING (*UCP) leading sequences that can be used to set UTF and Unicode prop- erty modes; they are equivalent to setting the PCRE_UTF8, PCRE_UTF16, PCRE_UTF32 and the PCRE_UCP options, respectively. The (*UTF) sequence - is a generic version that can be used with any of the libraries. + is a generic version that can be used with any of the libraries. How- + ever, the application can set the PCRE_NEVER_UTF option, which locks + out the use of the (*UTF) sequences. SUBPATTERNS @@ -5773,12 +6127,12 @@ NAMED SUBPATTERNS references, recursion, and conditions, can be made by name as well as by number. - Names consist of up to 32 alphanumeric characters and underscores. - Named capturing parentheses are still allocated numbers as well as - names, exactly as if the names were not present. The PCRE API provides - function calls for extracting the name-to-number translation table from - a compiled pattern. There is also a convenience function for extracting - a captured substring by name. + Names consist of up to 32 alphanumeric characters and underscores, but + must start with a non-digit. Named capturing parentheses are still + allocated numbers as well as names, exactly as if the names were not + present. The PCRE API provides function calls for extracting the name- + to-number translation table from a compiled pattern. There is also a + convenience function for extracting a captured substring by name. By default, a name must be unique within a pattern, but it is possible to relax this constraint by setting the PCRE_DUPNAMES option at compile @@ -5806,28 +6160,38 @@ NAMED SUBPATTERNS subpattern it was. If you make a back reference to a non-unique named subpattern from - elsewhere in the pattern, the one that corresponds to the first occur- - rence of the name is used. In the absence of duplicate numbers (see the - previous section) this is the one with the lowest number. If you use a - named reference in a condition test (see the section about conditions - below), either to check whether a subpattern has matched, or to check - for recursion, all subpatterns with the same name are tested. If the - condition is true for any one of them, the overall condition is true. - This is the same behaviour as testing by number. For further details of - the interfaces for handling named subpatterns, see the pcreapi documen- - tation. + elsewhere in the pattern, the subpatterns to which the name refers are + checked in the order in which they appear in the overall pattern. The + first one that is set is used for the reference. For example, this pat- + tern matches both "foofoo" and "barbar" but not "foobar" or "barfoo": + + (?:(?foo)|(?bar))\k + + + If you make a subroutine call to a non-unique named subpattern, the one + that corresponds to the first occurrence of the name is used. In the + absence of duplicate numbers (see the previous section) this is the one + with the lowest number. + + If you use a named reference in a condition test (see the section about + conditions below), either to check whether a subpattern has matched, or + to check for recursion, all subpatterns with the same name are tested. + If the condition is true for any one of them, the overall condition is + true. This is the same behaviour as testing by number. For further + details of the interfaces for handling named subpatterns, see the + pcreapi documentation. Warning: You cannot use different names to distinguish between two sub- - patterns with the same number because PCRE uses only the numbers when + patterns with the same number because PCRE uses only the numbers when matching. For this reason, an error is given at compile time if differ- - ent names are given to subpatterns with the same number. However, you - can give the same name to subpatterns with the same number, even when - PCRE_DUPNAMES is not set. + ent names are given to subpatterns with the same number. However, you + can always give the same name to subpatterns with the same number, even + when PCRE_DUPNAMES is not set. REPETITION - Repetition is specified by quantifiers, which can follow any of the + Repetition is specified by quantifiers, which can follow any of the following items: a literal data character @@ -5841,17 +6205,17 @@ REPETITION a parenthesized subpattern (including assertions) a subroutine call to a subpattern (recursive or otherwise) - The general repetition quantifier specifies a minimum and maximum num- - ber of permitted matches, by giving the two numbers in curly brackets - (braces), separated by a comma. The numbers must be less than 65536, + The general repetition quantifier specifies a minimum and maximum num- + ber of permitted matches, by giving the two numbers in curly brackets + (braces), separated by a comma. The numbers must be less than 65536, and the first must be less than or equal to the second. For example: z{2,4} - matches "zz", "zzz", or "zzzz". A closing brace on its own is not a - special character. If the second number is omitted, but the comma is - present, there is no upper limit; if the second number and the comma - are both omitted, the quantifier specifies an exact number of required + matches "zz", "zzz", or "zzzz". A closing brace on its own is not a + special character. If the second number is omitted, but the comma is + present, there is no upper limit; if the second number and the comma + are both omitted, the quantifier specifies an exact number of required matches. Thus [aeiou]{3,} @@ -5860,50 +6224,50 @@ REPETITION \d{8} - matches exactly 8 digits. An opening curly bracket that appears in a - position where a quantifier is not allowed, or one that does not match - the syntax of a quantifier, is taken as a literal character. For exam- + matches exactly 8 digits. An opening curly bracket that appears in a + position where a quantifier is not allowed, or one that does not match + the syntax of a quantifier, is taken as a literal character. For exam- ple, {,6} is not a quantifier, but a literal string of four characters. In UTF modes, quantifiers apply to characters rather than to individual - data units. Thus, for example, \x{100}{2} matches two characters, each + data units. Thus, for example, \x{100}{2} matches two characters, each of which is represented by a two-byte sequence in a UTF-8 string. Simi- - larly, \X{3} matches three Unicode extended grapheme clusters, each of - which may be several data units long (and they may be of different + larly, \X{3} matches three Unicode extended grapheme clusters, each of + which may be several data units long (and they may be of different lengths). The quantifier {0} is permitted, causing the expression to behave as if the previous item and the quantifier were not present. This may be use- - ful for subpatterns that are referenced as subroutines from elsewhere + ful for subpatterns that are referenced as subroutines from elsewhere in the pattern (but see also the section entitled "Defining subpatterns - for use by reference only" below). Items other than subpatterns that + for use by reference only" below). Items other than subpatterns that have a {0} quantifier are omitted from the compiled pattern. - For convenience, the three most common quantifiers have single-charac- + For convenience, the three most common quantifiers have single-charac- ter abbreviations: * is equivalent to {0,} + is equivalent to {1,} ? is equivalent to {0,1} - It is possible to construct infinite loops by following a subpattern + It is possible to construct infinite loops by following a subpattern that can match no characters with a quantifier that has no upper limit, for example: (a?)* Earlier versions of Perl and PCRE used to give an error at compile time - for such patterns. However, because there are cases where this can be - useful, such patterns are now accepted, but if any repetition of the - subpattern does in fact match no characters, the loop is forcibly bro- + for such patterns. However, because there are cases where this can be + useful, such patterns are now accepted, but if any repetition of the + subpattern does in fact match no characters, the loop is forcibly bro- ken. - By default, the quantifiers are "greedy", that is, they match as much - as possible (up to the maximum number of permitted times), without - causing the rest of the pattern to fail. The classic example of where + By default, the quantifiers are "greedy", that is, they match as much + as possible (up to the maximum number of permitted times), without + causing the rest of the pattern to fail. The classic example of where this gives problems is in trying to match comments in C programs. These - appear between /* and */ and within the comment, individual * and / - characters may appear. An attempt to match C comments by applying the + appear between /* and */ and within the comment, individual * and / + characters may appear. An attempt to match C comments by applying the pattern /\*.*\*/ @@ -5912,19 +6276,19 @@ REPETITION /* first comment */ not comment /* second comment */ - fails, because it matches the entire string owing to the greediness of + fails, because it matches the entire string owing to the greediness of the .* item. - However, if a quantifier is followed by a question mark, it ceases to + However, if a quantifier is followed by a question mark, it ceases to be greedy, and instead matches the minimum number of times possible, so the pattern /\*.*?\*/ - does the right thing with the C comments. The meaning of the various - quantifiers is not otherwise changed, just the preferred number of - matches. Do not confuse this use of question mark with its use as a - quantifier in its own right. Because it has two uses, it can sometimes + does the right thing with the C comments. The meaning of the various + quantifiers is not otherwise changed, just the preferred number of + matches. Do not confuse this use of question mark with its use as a + quantifier in its own right. Because it has two uses, it can sometimes appear doubled, as in \d??\d @@ -5932,45 +6296,45 @@ REPETITION which matches one digit by preference, but can match two if that is the only way the rest of the pattern matches. - If the PCRE_UNGREEDY option is set (an option that is not available in - Perl), the quantifiers are not greedy by default, but individual ones - can be made greedy by following them with a question mark. In other + If the PCRE_UNGREEDY option is set (an option that is not available in + Perl), the quantifiers are not greedy by default, but individual ones + can be made greedy by following them with a question mark. In other words, it inverts the default behaviour. - When a parenthesized subpattern is quantified with a minimum repeat - count that is greater than 1 or with a limited maximum, more memory is - required for the compiled pattern, in proportion to the size of the + When a parenthesized subpattern is quantified with a minimum repeat + count that is greater than 1 or with a limited maximum, more memory is + required for the compiled pattern, in proportion to the size of the minimum or maximum. If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equiv- - alent to Perl's /s) is set, thus allowing the dot to match newlines, - the pattern is implicitly anchored, because whatever follows will be - tried against every character position in the subject string, so there - is no point in retrying the overall match at any position after the - first. PCRE normally treats such a pattern as though it were preceded + alent to Perl's /s) is set, thus allowing the dot to match newlines, + the pattern is implicitly anchored, because whatever follows will be + tried against every character position in the subject string, so there + is no point in retrying the overall match at any position after the + first. PCRE normally treats such a pattern as though it were preceded by \A. - In cases where it is known that the subject string contains no new- - lines, it is worth setting PCRE_DOTALL in order to obtain this opti- + In cases where it is known that the subject string contains no new- + lines, it is worth setting PCRE_DOTALL in order to obtain this opti- mization, or alternatively using ^ to indicate anchoring explicitly. - However, there are some cases where the optimization cannot be used. + However, there are some cases where the optimization cannot be used. When .* is inside capturing parentheses that are the subject of a back reference elsewhere in the pattern, a match at the start may fail where a later one succeeds. Consider, for example: (.*)abc\1 - If the subject is "xyz123abc123" the match point is the fourth charac- + If the subject is "xyz123abc123" the match point is the fourth charac- ter. For this reason, such a pattern is not implicitly anchored. - Another case where implicit anchoring is not applied is when the lead- - ing .* is inside an atomic group. Once again, a match at the start may + Another case where implicit anchoring is not applied is when the lead- + ing .* is inside an atomic group. Once again, a match at the start may fail where a later one succeeds. Consider this pattern: (?>.*?a)b - It matches "ab" in the subject "aab". The use of the backtracking con- + It matches "ab" in the subject "aab". The use of the backtracking con- trol verbs (*PRUNE) and (*SKIP) also disable this optimization. When a capturing subpattern is repeated, the value captured is the sub- @@ -5979,8 +6343,8 @@ REPETITION (tweedle[dume]{3}\s*)+ has matched "tweedledum tweedledee" the value of the captured substring - is "tweedledee". However, if there are nested capturing subpatterns, - the corresponding captured values may have been set in previous itera- + is "tweedledee". However, if there are nested capturing subpatterns, + the corresponding captured values may have been set in previous itera- tions. For example, after /(a|(b))+/ @@ -5990,53 +6354,53 @@ REPETITION ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS - With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy") - repetition, failure of what follows normally causes the repeated item - to be re-evaluated to see if a different number of repeats allows the - rest of the pattern to match. Sometimes it is useful to prevent this, - either to change the nature of the match, or to cause it fail earlier - than it otherwise might, when the author of the pattern knows there is + With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy") + repetition, failure of what follows normally causes the repeated item + to be re-evaluated to see if a different number of repeats allows the + rest of the pattern to match. Sometimes it is useful to prevent this, + either to change the nature of the match, or to cause it fail earlier + than it otherwise might, when the author of the pattern knows there is no point in carrying on. - Consider, for example, the pattern \d+foo when applied to the subject + Consider, for example, the pattern \d+foo when applied to the subject line 123456bar After matching all 6 digits and then failing to match "foo", the normal - action of the matcher is to try again with only 5 digits matching the - \d+ item, and then with 4, and so on, before ultimately failing. - "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides - the means for specifying that once a subpattern has matched, it is not + action of the matcher is to try again with only 5 digits matching the + \d+ item, and then with 4, and so on, before ultimately failing. + "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides + the means for specifying that once a subpattern has matched, it is not to be re-evaluated in this way. - If we use atomic grouping for the previous example, the matcher gives - up immediately on failing to match "foo" the first time. The notation + If we use atomic grouping for the previous example, the matcher gives + up immediately on failing to match "foo" the first time. The notation is a kind of special parenthesis, starting with (?> as in this example: (?>\d+)foo - This kind of parenthesis "locks up" the part of the pattern it con- - tains once it has matched, and a failure further into the pattern is - prevented from backtracking into it. Backtracking past it to previous + This kind of parenthesis "locks up" the part of the pattern it con- + tains once it has matched, and a failure further into the pattern is + prevented from backtracking into it. Backtracking past it to previous items, however, works as normal. - An alternative description is that a subpattern of this type matches - the string of characters that an identical standalone pattern would + An alternative description is that a subpattern of this type matches + the string of characters that an identical standalone pattern would match, if anchored at the current point in the subject string. Atomic grouping subpatterns are not capturing subpatterns. Simple cases such as the above example can be thought of as a maximizing repeat that - must swallow everything it can. So, while both \d+ and \d+? are pre- - pared to adjust the number of digits they match in order to make the + must swallow everything it can. So, while both \d+ and \d+? are pre- + pared to adjust the number of digits they match in order to make the rest of the pattern match, (?>\d+) can only match an entire sequence of digits. - Atomic groups in general can of course contain arbitrarily complicated - subpatterns, and can be nested. However, when the subpattern for an + Atomic groups in general can of course contain arbitrarily complicated + subpatterns, and can be nested. However, when the subpattern for an atomic group is just a single repeated item, as in the example above, a - simpler notation, called a "possessive quantifier" can be used. This - consists of an additional + character following a quantifier. Using + simpler notation, called a "possessive quantifier" can be used. This + consists of an additional + character following a quantifier. Using this notation, the previous example can be rewritten as \d++foo @@ -6046,45 +6410,45 @@ ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS (abc|xyz){2,3}+ - Possessive quantifiers are always greedy; the setting of the + Possessive quantifiers are always greedy; the setting of the PCRE_UNGREEDY option is ignored. They are a convenient notation for the - simpler forms of atomic group. However, there is no difference in the - meaning of a possessive quantifier and the equivalent atomic group, - though there may be a performance difference; possessive quantifiers + simpler forms of atomic group. However, there is no difference in the + meaning of a possessive quantifier and the equivalent atomic group, + though there may be a performance difference; possessive quantifiers should be slightly faster. - The possessive quantifier syntax is an extension to the Perl 5.8 syn- - tax. Jeffrey Friedl originated the idea (and the name) in the first + The possessive quantifier syntax is an extension to the Perl 5.8 syn- + tax. Jeffrey Friedl originated the idea (and the name) in the first edition of his book. Mike McCloskey liked it, so implemented it when he - built Sun's Java package, and PCRE copied it from there. It ultimately + built Sun's Java package, and PCRE copied it from there. It ultimately found its way into Perl at release 5.10. PCRE has an optimization that automatically "possessifies" certain sim- - ple pattern constructs. For example, the sequence A+B is treated as - A++B because there is no point in backtracking into a sequence of A's + ple pattern constructs. For example, the sequence A+B is treated as + A++B because there is no point in backtracking into a sequence of A's when B must follow. - When a pattern contains an unlimited repeat inside a subpattern that - can itself be repeated an unlimited number of times, the use of an - atomic group is the only way to avoid some failing matches taking a + When a pattern contains an unlimited repeat inside a subpattern that + can itself be repeated an unlimited number of times, the use of an + atomic group is the only way to avoid some failing matches taking a very long time indeed. The pattern (\D+|<\d+>)*[!?] - matches an unlimited number of substrings that either consist of non- - digits, or digits enclosed in <>, followed by either ! or ?. When it + matches an unlimited number of substrings that either consist of non- + digits, or digits enclosed in <>, followed by either ! or ?. When it matches, it runs quickly. However, if it is applied to aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - it takes a long time before reporting failure. This is because the - string can be divided between the internal \D+ repeat and the external - * repeat in a large number of ways, and all have to be tried. (The - example uses [!?] rather than a single character at the end, because - both PCRE and Perl have an optimization that allows for fast failure - when a single character is used. They remember the last single charac- - ter that is required for a match, and fail early if it is not present - in the string.) If the pattern is changed so that it uses an atomic + it takes a long time before reporting failure. This is because the + string can be divided between the internal \D+ repeat and the external + * repeat in a large number of ways, and all have to be tried. (The + example uses [!?] rather than a single character at the end, because + both PCRE and Perl have an optimization that allows for fast failure + when a single character is used. They remember the last single charac- + ter that is required for a match, and fail early if it is not present + in the string.) If the pattern is changed so that it uses an atomic group, like this: ((?>\D+)|<\d+>)*[!?] @@ -6096,28 +6460,28 @@ BACK REFERENCES Outside a character class, a backslash followed by a digit greater than 0 (and possibly further digits) is a back reference to a capturing sub- - pattern earlier (that is, to its left) in the pattern, provided there + pattern earlier (that is, to its left) in the pattern, provided there have been that many previous capturing left parentheses. However, if the decimal number following the backslash is less than 10, - it is always taken as a back reference, and causes an error only if - there are not that many capturing left parentheses in the entire pat- - tern. In other words, the parentheses that are referenced need not be - to the left of the reference for numbers less than 10. A "forward back - reference" of this type can make sense when a repetition is involved - and the subpattern to the right has participated in an earlier itera- + it is always taken as a back reference, and causes an error only if + there are not that many capturing left parentheses in the entire pat- + tern. In other words, the parentheses that are referenced need not be + to the left of the reference for numbers less than 10. A "forward back + reference" of this type can make sense when a repetition is involved + and the subpattern to the right has participated in an earlier itera- tion. - It is not possible to have a numerical "forward back reference" to a - subpattern whose number is 10 or more using this syntax because a - sequence such as \50 is interpreted as a character defined in octal. + It is not possible to have a numerical "forward back reference" to a + subpattern whose number is 10 or more using this syntax because a + sequence such as \50 is interpreted as a character defined in octal. See the subsection entitled "Non-printing characters" above for further - details of the handling of digits following a backslash. There is no - such problem when named parentheses are used. A back reference to any + details of the handling of digits following a backslash. There is no + such problem when named parentheses are used. A back reference to any subpattern is possible using named parentheses (see below). - Another way of avoiding the ambiguity inherent in the use of digits - following a backslash is to use the \g escape sequence. This escape + Another way of avoiding the ambiguity inherent in the use of digits + following a backslash is to use the \g escape sequence. This escape must be followed by an unsigned number or a negative number, optionally enclosed in braces. These examples are all identical: @@ -6125,7 +6489,7 @@ BACK REFERENCES (ring), \g1 (ring), \g{1} - An unsigned number specifies an absolute reference without the ambigu- + An unsigned number specifies an absolute reference without the ambigu- ity that is present in the older syntax. It is also useful when literal digits follow the reference. A negative number is a relative reference. Consider this example: @@ -6134,33 +6498,33 @@ BACK REFERENCES The sequence \g{-1} is a reference to the most recently started captur- ing subpattern before \g, that is, is it equivalent to \2 in this exam- - ple. Similarly, \g{-2} would be equivalent to \1. The use of relative - references can be helpful in long patterns, and also in patterns that - are created by joining together fragments that contain references + ple. Similarly, \g{-2} would be equivalent to \1. The use of relative + references can be helpful in long patterns, and also in patterns that + are created by joining together fragments that contain references within themselves. - A back reference matches whatever actually matched the capturing sub- - pattern in the current subject string, rather than anything matching + A back reference matches whatever actually matched the capturing sub- + pattern in the current subject string, rather than anything matching the subpattern itself (see "Subpatterns as subroutines" below for a way of doing that). So the pattern (sens|respons)e and \1ibility - matches "sense and sensibility" and "response and responsibility", but - not "sense and responsibility". If caseful matching is in force at the - time of the back reference, the case of letters is relevant. For exam- + matches "sense and sensibility" and "response and responsibility", but + not "sense and responsibility". If caseful matching is in force at the + time of the back reference, the case of letters is relevant. For exam- ple, ((?i)rah)\s+\1 - matches "rah rah" and "RAH RAH", but not "RAH rah", even though the + matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original capturing subpattern is matched caselessly. - There are several different ways of writing back references to named - subpatterns. The .NET syntax \k{name} and the Perl syntax \k or - \k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's + There are several different ways of writing back references to named + subpatterns. The .NET syntax \k{name} and the Perl syntax \k or + \k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's unified back reference syntax, in which \g can be used for both numeric - and named references, is also supported. We could rewrite the above + and named references, is also supported. We could rewrite the above example in any of the following ways: (?(?i)rah)\s+\k @@ -6168,66 +6532,67 @@ BACK REFERENCES (?P(?i)rah)\s+(?P=p1) (?(?i)rah)\s+\g{p1} - A subpattern that is referenced by name may appear in the pattern + A subpattern that is referenced by name may appear in the pattern before or after the reference. - There may be more than one back reference to the same subpattern. If a - subpattern has not actually been used in a particular match, any back + There may be more than one back reference to the same subpattern. If a + subpattern has not actually been used in a particular match, any back references to it always fail by default. For example, the pattern (a|(bc))\2 - always fails if it starts to match "a" rather than "bc". However, if + always fails if it starts to match "a" rather than "bc". However, if the PCRE_JAVASCRIPT_COMPAT option is set at compile time, a back refer- ence to an unset value matches an empty string. - Because there may be many capturing parentheses in a pattern, all dig- - its following a backslash are taken as part of a potential back refer- - ence number. If the pattern continues with a digit character, some - delimiter must be used to terminate the back reference. If the - PCRE_EXTENDED option is set, this can be white space. Otherwise, the + Because there may be many capturing parentheses in a pattern, all dig- + its following a backslash are taken as part of a potential back refer- + ence number. If the pattern continues with a digit character, some + delimiter must be used to terminate the back reference. If the + PCRE_EXTENDED option is set, this can be white space. Otherwise, the \g{ syntax or an empty comment (see "Comments" below) can be used. Recursive back references - A back reference that occurs inside the parentheses to which it refers - fails when the subpattern is first used, so, for example, (a\1) never - matches. However, such references can be useful inside repeated sub- + A back reference that occurs inside the parentheses to which it refers + fails when the subpattern is first used, so, for example, (a\1) never + matches. However, such references can be useful inside repeated sub- patterns. For example, the pattern (a|b\1)+ matches any number of "a"s and also "aba", "ababbaa" etc. At each iter- - ation of the subpattern, the back reference matches the character - string corresponding to the previous iteration. In order for this to - work, the pattern must be such that the first iteration does not need - to match the back reference. This can be done using alternation, as in + ation of the subpattern, the back reference matches the character + string corresponding to the previous iteration. In order for this to + work, the pattern must be such that the first iteration does not need + to match the back reference. This can be done using alternation, as in the example above, or by a quantifier with a minimum of zero. - Back references of this type cause the group that they reference to be - treated as an atomic group. Once the whole group has been matched, a - subsequent matching failure cannot cause backtracking into the middle + Back references of this type cause the group that they reference to be + treated as an atomic group. Once the whole group has been matched, a + subsequent matching failure cannot cause backtracking into the middle of the group. ASSERTIONS - An assertion is a test on the characters following or preceding the - current matching point that does not actually consume any characters. - The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are + An assertion is a test on the characters following or preceding the + current matching point that does not actually consume any characters. + The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are described above. - More complicated assertions are coded as subpatterns. There are two - kinds: those that look ahead of the current position in the subject - string, and those that look behind it. An assertion subpattern is - matched in the normal way, except that it does not cause the current + More complicated assertions are coded as subpatterns. There are two + kinds: those that look ahead of the current position in the subject + string, and those that look behind it. An assertion subpattern is + matched in the normal way, except that it does not cause the current matching position to be changed. - Assertion subpatterns are not capturing subpatterns. If such an asser- - tion contains capturing subpatterns within it, these are counted for - the purposes of numbering the capturing subpatterns in the whole pat- - tern. However, substring capturing is carried out only for positive - assertions, because it does not make sense for negative assertions. + Assertion subpatterns are not capturing subpatterns. If such an asser- + tion contains capturing subpatterns within it, these are counted for + the purposes of numbering the capturing subpatterns in the whole pat- + tern. However, substring capturing is carried out only for positive + assertions. (Perl sometimes, but not always, does do capturing in nega- + tive assertions.) For compatibility with Perl, assertion subpatterns may be repeated; though it makes no sense to assert the same thing several times, the @@ -6456,25 +6821,20 @@ CONDITIONAL SUBPATTERNS 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. + also recognized. 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: @@ -6482,51 +6842,51 @@ CONDITIONAL SUBPATTERNS the condition is true if the most recent recursion is into a subpattern whose number or name is given. This condition does not check the entire - recursion stack. If the name used in a condition of this kind is a + recursion stack. If the name used in a condition of this kind is a duplicate, the test is applied to all subpatterns of the same name, and is true if any one of them is the most recent recursion. - At "top level", all these recursion test conditions are false. The + At "top level", all these recursion test conditions are false. The syntax for recursive patterns is described below. Defining subpatterns for use by reference only - If the condition is the string (DEFINE), and there is no subpattern - with the name DEFINE, the condition is always false. In this case, - there may be only one alternative in the subpattern. It is always - skipped if control reaches this point in the pattern; the idea of - DEFINE is that it can be used to define subroutines that can be refer- - enced from elsewhere. (The use of subroutines is described below.) For - example, a pattern to match an IPv4 address such as "192.168.23.245" + If the condition is the string (DEFINE), and there is no subpattern + with the name DEFINE, the condition is always false. In this case, + there may be only one alternative in the subpattern. It is always + skipped if control reaches this point in the pattern; the idea of + DEFINE is that it can be used to define subroutines that can be refer- + enced from elsewhere. (The use of subroutines is described below.) For + example, a pattern to match an IPv4 address such as "192.168.23.245" could be written like this (ignore white space and line breaks): (?(DEFINE) (? 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) ) \b (?&byte) (\.(?&byte)){3} \b - The first part of the pattern is a DEFINE group inside which a another - group named "byte" is defined. This matches an individual component of - an IPv4 address (a number less than 256). When matching takes place, - this part of the pattern is skipped because DEFINE acts like a false - condition. The rest of the pattern uses references to the named group - to match the four dot-separated components of an IPv4 address, insist- + The first part of the pattern is a DEFINE group inside which a another + group named "byte" is defined. This matches an individual component of + an IPv4 address (a number less than 256). When matching takes place, + this part of the pattern is skipped because DEFINE acts like a false + condition. The rest of the pattern uses references to the named group + to match the four dot-separated components of an IPv4 address, insist- ing on a word boundary at each end. Assertion conditions - If the condition is not in any of the above formats, it must be an - assertion. This may be a positive or negative lookahead or lookbehind - assertion. Consider this pattern, again containing non-significant + If the condition is not in any of the above formats, it must be an + assertion. This may be a positive or negative lookahead or lookbehind + assertion. Consider this pattern, again containing non-significant white space, and with the two alternatives on the second line: (?(?=[^a-z]*[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) - The condition is a positive lookahead assertion that matches an - optional sequence of non-letters followed by a letter. In other words, - it tests for the presence of at least one letter in the subject. If a - letter is found, the subject is matched against the first alternative; - otherwise it is matched against the second. This pattern matches - strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are + The condition is a positive lookahead assertion that matches an + optional sequence of non-letters followed by a letter. In other words, + it tests for the presence of at least one letter in the subject. If a + letter is found, the subject is matched against the first alternative; + otherwise it is matched against the second. This pattern matches + strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits. @@ -6535,41 +6895,41 @@ COMMENTS There are two ways of including comments in patterns that are processed by PCRE. In both cases, the start of the comment must not be in a char- acter class, nor in the middle of any other sequence of related charac- - ters such as (?: or a subpattern name or number. The characters that + ters such as (?: or a subpattern name or number. The characters that make up a comment play no part in the pattern matching. - The sequence (?# marks the start of a comment that continues up to the - next closing parenthesis. Nested parentheses are not permitted. If the + The sequence (?# marks the start of a comment that continues up to the + next closing parenthesis. Nested parentheses are not permitted. If the PCRE_EXTENDED option is set, an unescaped # character also introduces a - comment, which in this case continues to immediately after the next - newline character or character sequence in the pattern. Which charac- + comment, which in this case continues to immediately after the next + newline character or character sequence in the pattern. Which charac- ters are interpreted as newlines is controlled by the options passed to - a compiling function or by a special sequence at the start of the pat- + a compiling function or by a special sequence at the start of the pat- tern, as described in the section entitled "Newline conventions" above. Note that the end of this type of comment is a literal newline sequence - in the pattern; escape sequences that happen to represent a newline do - not count. For example, consider this pattern when PCRE_EXTENDED is + in the pattern; escape sequences that happen to represent a newline do + not count. For example, consider this pattern when PCRE_EXTENDED is set, and the default newline convention is in force: abc #comment \n still comment - On encountering the # character, pcre_compile() skips along, looking - for a newline in the pattern. The sequence \n is still literal at this - stage, so it does not terminate the comment. Only an actual character + On encountering the # character, pcre_compile() skips along, looking + for a newline in the pattern. The sequence \n is still literal at this + stage, so it does not terminate the comment. Only an actual character with the code value 0x0a (the default newline) does so. RECURSIVE PATTERNS - Consider the problem of matching a string in parentheses, allowing for - unlimited nested parentheses. Without the use of recursion, the best - that can be done is to use a pattern that matches up to some fixed - depth of nesting. It is not possible to handle an arbitrary nesting + Consider the problem of matching a string in parentheses, allowing for + unlimited nested parentheses. Without the use of recursion, the best + that can be done is to use a pattern that matches up to some fixed + depth of nesting. It is not possible to handle an arbitrary nesting depth. For some time, Perl has provided a facility that allows regular expres- - sions to recurse (amongst other things). It does this by interpolating - Perl code in the expression at run time, and the code can refer to the + sions to recurse (amongst other things). It does this by interpolating + Perl code in the expression at run time, and the code can refer to the expression itself. A Perl pattern using code interpolation to solve the parentheses problem can be created like this: @@ -6579,201 +6939,201 @@ RECURSIVE PATTERNS refers recursively to the pattern in which it appears. Obviously, PCRE cannot support the interpolation of Perl code. Instead, - it supports special syntax for recursion of the entire pattern, and - also for individual subpattern recursion. After its introduction in - PCRE and Python, this kind of recursion was subsequently introduced + it supports special syntax for recursion of the entire pattern, and + also for individual subpattern recursion. After its introduction in + PCRE and Python, this kind of recursion was subsequently introduced into Perl at release 5.10. - A special item that consists of (? followed by a number greater than - zero and a closing parenthesis is a recursive subroutine call of the - subpattern of the given number, provided that it occurs inside that - subpattern. (If not, it is a non-recursive subroutine call, which is - described in the next section.) The special item (?R) or (?0) is a + A special item that consists of (? followed by a number greater than + zero and a closing parenthesis is a recursive subroutine call of the + subpattern of the given number, provided that it occurs inside that + subpattern. (If not, it is a non-recursive subroutine call, which is + described in the next section.) The special item (?R) or (?0) is a recursive call of the entire regular expression. - This PCRE pattern solves the nested parentheses problem (assume the + This PCRE pattern solves the nested parentheses problem (assume the PCRE_EXTENDED option is set so that white space is ignored): \( ( [^()]++ | (?R) )* \) - First it matches an opening parenthesis. Then it matches any number of - substrings which can either be a sequence of non-parentheses, or a - recursive match of the pattern itself (that is, a correctly parenthe- + First it matches an opening parenthesis. Then it matches any number of + substrings which can either be a sequence of non-parentheses, or a + recursive match of the pattern itself (that is, a correctly parenthe- sized substring). Finally there is a closing parenthesis. Note the use of a possessive quantifier to avoid backtracking into sequences of non- parentheses. - If this were part of a larger pattern, you would not want to recurse + If this were part of a larger pattern, you would not want to recurse the entire pattern, so instead you could use this: ( \( ( [^()]++ | (?1) )* \) ) - We have put the pattern into parentheses, and caused the recursion to + We have put the pattern into parentheses, and caused the recursion to refer to them instead of the whole pattern. - In a larger pattern, keeping track of parenthesis numbers can be - tricky. This is made easier by the use of relative references. Instead + In a larger pattern, keeping track of parenthesis numbers can be + tricky. This is made easier by the use of relative references. Instead of (?1) in the pattern above you can write (?-2) to refer to the second - most recently opened parentheses preceding the recursion. In other - words, a negative number counts capturing parentheses leftwards from + most recently opened parentheses preceding the recursion. In other + words, a negative number counts capturing parentheses leftwards from the point at which it is encountered. - It is also possible to refer to subsequently opened parentheses, by - writing references such as (?+2). However, these cannot be recursive - because the reference is not inside the parentheses that are refer- - enced. They are always non-recursive subroutine calls, as described in + It is also possible to refer to subsequently opened parentheses, by + writing references such as (?+2). However, these cannot be recursive + because the reference is not inside the parentheses that are refer- + enced. They are always non-recursive subroutine calls, as described in the next section. - An alternative approach is to use named parentheses instead. The Perl - syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also + An alternative approach is to use named parentheses instead. The Perl + syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also supported. We could rewrite the above example as follows: (? \( ( [^()]++ | (?&pn) )* \) ) - If there is more than one subpattern with the same name, the earliest + If there is more than one subpattern with the same name, the earliest one is used. - This particular example pattern that we have been looking at contains + This particular example pattern that we have been looking at contains nested unlimited repeats, and so the use of a possessive quantifier for matching strings of non-parentheses is important when applying the pat- - tern to strings that do not match. For example, when this pattern is + tern to strings that do not match. For example, when this pattern is applied to (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa() - it yields "no match" quickly. However, if a possessive quantifier is - not used, the match runs for a very long time indeed because there are - so many different ways the + and * repeats can carve up the subject, + it yields "no match" quickly. However, if a possessive quantifier is + not used, the match runs for a very long time indeed because there are + so many different ways the + and * repeats can carve up the subject, and all have to be tested before failure can be reported. - At the end of a match, the values of capturing parentheses are those - from the outermost level. If you want to obtain intermediate values, a - callout function can be used (see below and the pcrecallout documenta- + At the end of a match, the values of capturing parentheses are those + from the outermost level. If you want to obtain intermediate values, a + callout function can be used (see below and the pcrecallout documenta- tion). If the pattern above is matched against (ab(cd)ef) - the value for the inner capturing parentheses (numbered 2) is "ef", - which is the last value taken on at the top level. If a capturing sub- - pattern is not matched at the top level, its final captured value is - unset, even if it was (temporarily) set at a deeper level during the + the value for the inner capturing parentheses (numbered 2) is "ef", + which is the last value taken on at the top level. If a capturing sub- + pattern is not matched at the top level, its final captured value is + unset, even if it was (temporarily) set at a deeper level during the matching process. - If there are more than 15 capturing parentheses in a pattern, PCRE has - to obtain extra memory to store data during a recursion, which it does + If there are more than 15 capturing parentheses in a pattern, PCRE has + to obtain extra memory to store data during a recursion, which it does by using pcre_malloc, freeing it via pcre_free afterwards. If no memory can be obtained, the match fails with the PCRE_ERROR_NOMEMORY error. - Do not confuse the (?R) item with the condition (R), which tests for - recursion. Consider this pattern, which matches text in angle brack- - ets, allowing for arbitrary nesting. Only digits are allowed in nested - brackets (that is, when recursing), whereas any characters are permit- + Do not confuse the (?R) item with the condition (R), which tests for + recursion. Consider this pattern, which matches text in angle brack- + ets, allowing for arbitrary nesting. Only digits are allowed in nested + brackets (that is, when recursing), whereas any characters are permit- ted at the outer level. < (?: (?(R) \d++ | [^<>]*+) | (?R)) * > - In this pattern, (?(R) is the start of a conditional subpattern, with - two different alternatives for the recursive and non-recursive cases. + In this pattern, (?(R) is the start of a conditional subpattern, with + two different alternatives for the recursive and non-recursive cases. The (?R) item is the actual recursive call. Differences in recursion processing between PCRE and Perl - Recursion processing in PCRE differs from Perl in two important ways. - In PCRE (like Python, but unlike Perl), a recursive subpattern call is + Recursion processing in PCRE differs from Perl in two important ways. + In PCRE (like Python, but unlike Perl), a recursive subpattern call is always treated as an atomic group. That is, once it has matched some of the subject string, it is never re-entered, even if it contains untried - alternatives and there is a subsequent matching failure. This can be - illustrated by the following pattern, which purports to match a palin- - dromic string that contains an odd number of characters (for example, + alternatives and there is a subsequent matching failure. This can be + illustrated by the following pattern, which purports to match a palin- + dromic string that contains an odd number of characters (for example, "a", "aba", "abcba", "abcdcba"): ^(.|(.)(?1)\2)$ The idea is that it either matches a single character, or two identical - characters surrounding a sub-palindrome. In Perl, this pattern works; - in PCRE it does not if the pattern is longer than three characters. + characters surrounding a sub-palindrome. In Perl, this pattern works; + in PCRE it does not if the pattern is longer than three characters. Consider the subject string "abcba": - At the top level, the first character is matched, but as it is not at + At the top level, the first character is matched, but as it is not at the end of the string, the first alternative fails; the second alterna- tive is taken and the recursion kicks in. The recursive call to subpat- - tern 1 successfully matches the next character ("b"). (Note that the + tern 1 successfully matches the next character ("b"). (Note that the beginning and end of line tests are not part of the recursion). - Back at the top level, the next character ("c") is compared with what - subpattern 2 matched, which was "a". This fails. Because the recursion - is treated as an atomic group, there are now no backtracking points, - and so the entire match fails. (Perl is able, at this point, to re- - enter the recursion and try the second alternative.) However, if the + Back at the top level, the next character ("c") is compared with what + subpattern 2 matched, which was "a". This fails. Because the recursion + is treated as an atomic group, there are now no backtracking points, + and so the entire match fails. (Perl is able, at this point, to re- + enter the recursion and try the second alternative.) However, if the pattern is written with the alternatives in the other order, things are different: ^((.)(?1)\2|.)$ - This time, the recursing alternative is tried first, and continues to - recurse until it runs out of characters, at which point the recursion - fails. But this time we do have another alternative to try at the - higher level. That is the big difference: in the previous case the + This time, the recursing alternative is tried first, and continues to + recurse until it runs out of characters, at which point the recursion + fails. But this time we do have another alternative to try at the + higher level. That is the big difference: in the previous case the remaining alternative is at a deeper recursion level, which PCRE cannot use. - To change the pattern so that it matches all palindromic strings, not - just those with an odd number of characters, it is tempting to change + To change the pattern so that it matches all palindromic strings, not + just those with an odd number of characters, it is tempting to change the pattern to this: ^((.)(?1)\2|.?)$ - Again, this works in Perl, but not in PCRE, and for the same reason. - When a deeper recursion has matched a single character, it cannot be - entered again in order to match an empty string. The solution is to - separate the two cases, and write out the odd and even cases as alter- + Again, this works in Perl, but not in PCRE, and for the same reason. + When a deeper recursion has matched a single character, it cannot be + entered again in order to match an empty string. The solution is to + separate the two cases, and write out the odd and even cases as alter- natives at the higher level: ^(?:((.)(?1)\2|)|((.)(?3)\4|.)) - If you want to match typical palindromic phrases, the pattern has to + If you want to match typical palindromic phrases, the pattern has to ignore all non-word characters, which can be done like this: ^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$ If run with the PCRE_CASELESS option, this pattern matches phrases such as "A man, a plan, a canal: Panama!" and it works well in both PCRE and - Perl. Note the use of the possessive quantifier *+ to avoid backtrack- - ing into sequences of non-word characters. Without this, PCRE takes a - great deal longer (ten times or more) to match typical phrases, and + Perl. Note the use of the possessive quantifier *+ to avoid backtrack- + ing into sequences of non-word characters. Without this, PCRE takes a + great deal longer (ten times or more) to match typical phrases, and Perl takes so long that you think it has gone into a loop. - WARNING: The palindrome-matching patterns above work only if the sub- - ject string does not start with a palindrome that is shorter than the - entire string. For example, although "abcba" is correctly matched, if - the subject is "ababa", PCRE finds the palindrome "aba" at the start, - then fails at top level because the end of the string does not follow. - Once again, it cannot jump back into the recursion to try other alter- + WARNING: The palindrome-matching patterns above work only if the sub- + ject string does not start with a palindrome that is shorter than the + entire string. For example, although "abcba" is correctly matched, if + the subject is "ababa", PCRE finds the palindrome "aba" at the start, + then fails at top level because the end of the string does not follow. + Once again, it cannot jump back into the recursion to try other alter- natives, so the entire match fails. - The second way in which PCRE and Perl differ in their recursion pro- - cessing is in the handling of captured values. In Perl, when a subpat- - tern is called recursively or as a subpattern (see the next section), - it has no access to any values that were captured outside the recur- - sion, whereas in PCRE these values can be referenced. Consider this + The second way in which PCRE and Perl differ in their recursion pro- + cessing is in the handling of captured values. In Perl, when a subpat- + tern is called recursively or as a subpattern (see the next section), + it has no access to any values that were captured outside the recur- + sion, whereas in PCRE these values can be referenced. Consider this pattern: ^(.)(\1|a(?2)) - In PCRE, this pattern matches "bab". The first capturing parentheses - match "b", then in the second group, when the back reference \1 fails - to match "b", the second alternative matches "a" and then recurses. In - the recursion, \1 does now match "b" and so the whole match succeeds. - In Perl, the pattern fails to match because inside the recursive call + In PCRE, this pattern matches "bab". The first capturing parentheses + match "b", then in the second group, when the back reference \1 fails + to match "b", the second alternative matches "a" and then recurses. In + the recursion, \1 does now match "b" and so the whole match succeeds. + In Perl, the pattern fails to match because inside the recursive call \1 cannot access the externally set value. SUBPATTERNS AS SUBROUTINES - If the syntax for a recursive subpattern call (either by number or by - name) is used outside the parentheses to which it refers, it operates - like a subroutine in a programming language. The called subpattern may - be defined before or after the reference. A numbered reference can be + If the syntax for a recursive subpattern call (either by number or by + name) is used outside the parentheses to which it refers, it operates + like a subroutine in a programming language. The called subpattern may + be defined before or after the reference. A numbered reference can be absolute or relative, as in these examples: (...(absolute)...)...(?2)... @@ -6784,190 +7144,203 @@ SUBPATTERNS AS SUBROUTINES (sens|respons)e and \1ibility - matches "sense and sensibility" and "response and responsibility", but + matches "sense and sensibility" and "response and responsibility", but not "sense and responsibility". If instead the pattern (sens|respons)e and (?1)ibility - is used, it does match "sense and responsibility" as well as the other - two strings. Another example is given in the discussion of DEFINE + is used, it does match "sense and responsibility" as well as the other + two strings. Another example is given in the discussion of DEFINE above. - All subroutine calls, whether recursive or not, are always treated as - atomic groups. That is, once a subroutine has matched some of the sub- + All subroutine calls, whether recursive or not, are always treated as + atomic groups. That is, once a subroutine has matched some of the sub- ject string, it is never re-entered, even if it contains untried alter- - natives and there is a subsequent matching failure. Any capturing - parentheses that are set during the subroutine call revert to their + natives and there is a subsequent matching failure. Any capturing + parentheses that are set during the subroutine call revert to their previous values afterwards. - Processing options such as case-independence are fixed when a subpat- - tern is defined, so if it is used as a subroutine, such options cannot + Processing options such as case-independence are fixed when a subpat- + tern is defined, so if it is used as a subroutine, such options cannot be changed for different calls. For example, consider this pattern: (abc)(?i:(?-1)) - It matches "abcabc". It does not match "abcABC" because the change of + It matches "abcabc". It does not match "abcABC" because the change of processing option does not affect the called subpattern. ONIGURUMA SUBROUTINE SYNTAX - For compatibility with Oniguruma, the non-Perl syntax \g followed by a + For compatibility with Oniguruma, the non-Perl syntax \g followed by a name or a number enclosed either in angle brackets or single quotes, is - an alternative syntax for referencing a subpattern as a subroutine, - possibly recursively. Here are two of the examples used above, rewrit- + an alternative syntax for referencing a subpattern as a subroutine, + possibly recursively. Here are two of the examples used above, rewrit- ten using this syntax: (? \( ( (?>[^()]+) | \g )* \) ) (sens|respons)e and \g'1'ibility - PCRE supports an extension to Oniguruma: if a number is preceded by a + PCRE supports an extension to Oniguruma: if a number is preceded by a plus or a minus sign it is taken as a relative reference. For example: (abc)(?i:\g<-1>) - Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not - synonymous. The former is a back reference; the latter is a subroutine + Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not + synonymous. The former is a back reference; the latter is a subroutine call. CALLOUTS Perl has a feature whereby using the sequence (?{...}) causes arbitrary - Perl code to be obeyed in the middle of matching a regular expression. + Perl code to be obeyed in the middle of matching a regular expression. This makes it possible, amongst other things, to extract different sub- strings that match the same pair of parentheses when there is a repeti- tion. PCRE provides a similar feature, but of course it cannot obey arbitrary Perl code. The feature is called "callout". The caller of PCRE provides - an external function by putting its entry point in the global variable - pcre_callout (8-bit library) or pcre[16|32]_callout (16-bit or 32-bit - library). By default, this variable contains NULL, which disables all + an external function by putting its entry point in the global variable + pcre_callout (8-bit library) or pcre[16|32]_callout (16-bit or 32-bit + library). By default, this variable contains NULL, which disables all calling out. - Within a regular expression, (?C) indicates the points at which the - external function is to be called. If you want to identify different - callout points, you can put a number less than 256 after the letter C. - The default value is zero. For example, this pattern has two callout + Within a regular expression, (?C) indicates the points at which the + external function is to be called. If you want to identify different + callout points, you can put a number less than 256 after the letter C. + The default value is zero. For example, this pattern has two callout points: (?C1)abc(?C2)def - If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, call- - outs are automatically installed before each item in the pattern. They - are all numbered 255. + If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, call- + outs are automatically installed before each item in the pattern. They + are all numbered 255. If there is a conditional group in the pattern + whose condition is an assertion, an additional callout is inserted just + before the condition. An explicit callout may also be set at this posi- + tion, as in this example: - 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. + (?(?C9)(?=a)abc|def) + + Note that this applies only to assertion conditions, not to other types + of condition. + + During matching, when PCRE reaches a callout point, the external func- + tion is called. It is provided with the number of the callout, the + position in the pattern, and, optionally, one item of data originally + supplied by the caller of the matching function. The callout function + may cause matching to proceed, to backtrack, or to fail altogether. + + By default, PCRE implements a number of optimizations at compile time + and matching time, and one side-effect is that sometimes callouts are + skipped. If you need all possible callouts to happen, you need to set + options that disable the relevant optimizations. More details, and a + complete description of the interface to the callout function, are + given in the pcrecallout documentation. BACKTRACKING CONTROL Perl 5.10 introduced a number of "Special Backtracking Control Verbs", - which are described in the Perl documentation as "experimental and sub- - ject to change or removal in a future version of Perl". It goes on to - say: "Their usage in production code should be noted to avoid problems - during upgrades." The same remarks apply to the PCRE features described - in this section. + which are still described in the Perl documentation as "experimental + and subject to change or removal in a future version of Perl". It goes + on to say: "Their usage in production code should be noted to avoid + problems during upgrades." The same remarks apply to the PCRE features + described in this section. - Since these verbs are specifically related to backtracking, most of - them can be used only when the pattern is to be matched using one of - the traditional matching functions, which use a backtracking algorithm. - With the exception of (*FAIL), which behaves like a failing negative - assertion, they cause an error if encountered by a DFA matching func- - tion. - - If any of these verbs are used in an assertion or in a subpattern that - is called as a subroutine (whether or not recursively), their effect is - confined to that subpattern; it does not extend to the surrounding pat- - tern, with one exception: the name from a *(MARK), (*PRUNE), or (*THEN) - that is encountered in a successful positive assertion is passed back - when a match succeeds (compare capturing parentheses in assertions). - Note that such subpatterns are processed as anchored at the point where - they are tested. Note also that Perl's treatment of subroutines and - assertions is different in some cases. - - The new verbs make use of what was previously invalid syntax: an open- + The new verbs make use of what was previously invalid syntax: an open- ing parenthesis followed by an asterisk. They are generally of the form - (*VERB) or (*VERB:NAME). Some may take either form, with differing be- - haviour, depending on whether or not an argument is present. A name is + (*VERB) or (*VERB:NAME). Some may take either form, possibly behaving + differently depending on whether or not a name is present. A name is any sequence of characters that does not include a closing parenthesis. The maximum length of name is 255 in the 8-bit library and 65535 in the - 16-bit and 32-bit library. If the name is empty, that is, if the clos- - ing parenthesis immediately follows the colon, the effect is as if the - colon were not there. Any number of these verbs may occur in a pattern. + 16-bit and 32-bit libraries. If the name is empty, that is, if the + closing parenthesis immediately follows the colon, the effect is as if + the colon were not there. Any number of these verbs may occur in a + pattern. + + Since these verbs are specifically related to backtracking, most of + them can be used only when the pattern is to be matched using one of + the traditional matching functions, because these use a backtracking + algorithm. With the exception of (*FAIL), which behaves like a failing + negative assertion, the backtracking control verbs cause an error if + encountered by a DFA matching function. + + The behaviour of these verbs in repeated groups, assertions, and in + subpatterns called as subroutines (whether or not recursively) is docu- + mented below. Optimizations that affect backtracking verbs - PCRE contains some optimizations that are used to speed up matching by + PCRE contains some optimizations that are used to speed up matching by running some checks at the start of each match attempt. For example, it - may know the minimum length of matching subject, or that a particular - character must be present. When one of these optimizations suppresses - the running of a match, any included backtracking verbs will not, of + may know the minimum length of matching subject, or that a particular + character must be present. When one of these optimizations bypasses the + running of a match, any included backtracking verbs will not, of course, be processed. You can suppress the start-of-match optimizations - by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_com- + by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_com- pile() or pcre_exec(), or by starting the pattern with (*NO_START_OPT). There is more discussion of this option in the section entitled "Option bits for pcre_exec()" in the pcreapi documentation. - Experiments with Perl suggest that it too has similar optimizations, + Experiments with Perl suggest that it too has similar optimizations, sometimes leading to anomalous results. Verbs that act immediately - The following verbs act as soon as they are encountered. They may not + The following verbs act as soon as they are encountered. They may not be followed by a name. (*ACCEPT) - This verb causes the match to end successfully, skipping the remainder - of the pattern. However, when it is inside a subpattern that is called - as a subroutine, only that subpattern is ended successfully. Matching - then continues at the outer level. If (*ACCEPT) is inside capturing - parentheses, the data so far is captured. For example: + This verb causes the match to end successfully, skipping the remainder + of the pattern. However, when it is inside a subpattern that is called + as a subroutine, only that subpattern is ended successfully. Matching + then continues at the outer level. If (*ACCEPT) in triggered in a posi- + tive assertion, the assertion succeeds; in a negative assertion, the + assertion fails. + + If (*ACCEPT) is inside capturing parentheses, the data so far is cap- + tured. For example: A((?:A|B(*ACCEPT)|C)D) - This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap- + This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap- tured by the outer parentheses. (*FAIL) or (*F) - This verb causes a matching failure, forcing backtracking to occur. It - is equivalent to (?!) but easier to read. The Perl documentation notes - that it is probably useful only when combined with (?{}) or (??{}). - Those are, of course, Perl features that are not present in PCRE. The - nearest equivalent is the callout feature, as for example in this pat- + This verb causes a matching failure, forcing backtracking to occur. It + is equivalent to (?!) but easier to read. The Perl documentation notes + that it is probably useful only when combined with (?{}) or (??{}). + Those are, of course, Perl features that are not present in PCRE. The + nearest equivalent is the callout feature, as for example in this pat- tern: a+(?C)(*FAIL) - A match with the string "aaaa" always fails, but the callout is taken + A match with the string "aaaa" always fails, but the callout is taken before each backtrack happens (in this example, 10 times). Recording which path was taken - There is one verb whose main purpose is to track how a match was - arrived at, though it also has a secondary use in conjunction with + There is one verb whose main purpose is to track how a match was + arrived at, though it also has a secondary use in conjunction with advancing the match starting point (see (*SKIP) below). (*MARK:NAME) or (*:NAME) - A name is always required with this verb. There may be as many - instances of (*MARK) as you like in a pattern, and their names do not + A name is always required with this verb. There may be as many + instances of (*MARK) as you like in a pattern, and their names do not have to be unique. - When a match succeeds, the name of the last-encountered (*MARK) on the - matching path is passed back to the caller as described in the section - entitled "Extra data for pcre_exec()" in the pcreapi documentation. - Here is an example of pcretest output, where the /K modifier requests - the retrieval and outputting of (*MARK) data: + When a match succeeds, the name of the last-encountered (*MARK:NAME), + (*PRUNE:NAME), or (*THEN:NAME) on the matching path is passed back to + the caller as described in the section entitled "Extra data for + pcre_exec()" in the pcreapi documentation. Here is an example of + pcretest output, where the /K modifier requests the retrieval and out- + putting of (*MARK) data: re> /X(*MARK:A)Y|X(*MARK:B)Z/K data> XY @@ -6982,136 +7355,164 @@ BACKTRACKING CONTROL efficient way of obtaining this information than putting each alterna- tive in its own capturing parentheses. - If (*MARK) is encountered in a positive assertion, its name is recorded - and passed back if it is the last-encountered. This does not happen for - negative assertions. + If a verb with a name is encountered in a positive assertion that is + true, the name is recorded and passed back if it is the last-encoun- + tered. This does not happen for negative assertions or failing positive + assertions. - After a partial match or a failed match, the name of the last encoun- - tered (*MARK) in the entire match process is returned. For example: + After a partial match or a failed match, the last encountered name in + the entire match process is returned. For example: re> /X(*MARK:A)Y|X(*MARK:B)Z/K data> XP No match, mark = B - Note that in this unanchored example the mark is retained from the + Note that in this unanchored example the mark is retained from the match attempt that started at the letter "X" in the subject. Subsequent match attempts starting at "P" and then with an empty string do not get as far as the (*MARK) item, but nevertheless do not reset it. - If you are interested in (*MARK) values after failed matches, you - should probably set the PCRE_NO_START_OPTIMIZE option (see above) to + If you are interested in (*MARK) values after failed matches, you + should probably set the PCRE_NO_START_OPTIMIZE option (see above) to ensure that the match is always attempted. Verbs that act after backtracking The following verbs do nothing when they are encountered. Matching con- - tinues with what follows, but if there is no subsequent match, causing - a backtrack to the verb, a failure is forced. That is, backtracking - cannot pass to the left of the verb. However, when one of these verbs - appears inside an atomic group, its effect is confined to that group, - because once the group has been matched, there is never any backtrack- - ing into it. In this situation, backtracking can "jump back" to the - left of the entire atomic group. (Remember also, as stated above, that - this localization also applies in subroutine calls and assertions.) + tinues with what follows, but if there is no subsequent match, causing + a backtrack to the verb, a failure is forced. That is, backtracking + cannot pass to the left of the verb. However, when one of these verbs + appears inside an atomic group or an assertion that is true, its effect + is confined to that group, because once the group has been matched, + there is never any backtracking into it. In this situation, backtrack- + ing can "jump back" to the left of the entire atomic group or asser- + tion. (Remember also, as stated above, that this localization also + applies in subroutine calls.) These verbs differ in exactly what kind of failure occurs when back- - tracking reaches them. + tracking reaches them. The behaviour described below is what happens + when the verb is not in a subroutine or an assertion. Subsequent sec- + tions cover these special cases. (*COMMIT) This verb, which may not be followed by a name, causes the whole match - to fail outright if the rest of the pattern does not match. Even if the - pattern is unanchored, no further attempts to find a match by advancing - the starting point take place. Once (*COMMIT) has been passed, - pcre_exec() is committed to finding a match at the current starting - point, or not at all. For example: + to fail outright if there is a later matching failure that causes back- + tracking to reach it. Even if the pattern is unanchored, no further + attempts to find a match by advancing the starting point take place. If + (*COMMIT) is the only backtracking verb that is encountered, once it + has been passed pcre_exec() is committed to finding a match at the cur- + rent starting point, or not at all. For example: a+(*COMMIT)b - This matches "xxaab" but not "aacaab". It can be thought of as a kind + This matches "xxaab" but not "aacaab". It can be thought of as a kind of dynamic anchor, or "I've started, so I must finish." The name of the - most recently passed (*MARK) in the path is passed back when (*COMMIT) + most recently passed (*MARK) in the path is passed back when (*COMMIT) forces a match failure. + If there is more than one backtracking verb in a pattern, a different + one that follows (*COMMIT) may be triggered first, so merely passing + (*COMMIT) during a match does not always guarantee that a match must be + at this starting point. + Note that (*COMMIT) at the start of a pattern is not the same as an anchor, unless PCRE's start-of-match optimizations are turned off, as - shown in this pcretest example: + shown in this output from pcretest: re> /(*COMMIT)abc/ data> xyzabc 0: abc - xyzabc\Y + data> 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 - the second subject, the match starts at "x" and so the (*COMMIT) causes - it to fail without trying any other starting points. + For this pattern, PCRE knows that any match must start with "a", so the + optimization skips along the subject to "a" before applying the pattern + to the first set of data. The match attempt then succeeds. In the sec- + ond set of data, the escape sequence \Y is interpreted by the pcretest + program. It causes the PCRE_NO_START_OPTIMIZE option to be set when + pcre_exec() is called. This disables the optimization that skips along + to the first character. The pattern is now applied starting at "x", and + so the (*COMMIT) causes the match 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 - uses of (*PRUNE) that cannot be expressed in any other way. The behav- - iour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an - anchored pattern (*PRUNE) has the same effect as (*COMMIT). + the subject if there is a later matching failure that causes backtrack- + ing to reach it. If the pattern is unanchored, the normal "bumpalong" + advance to the next starting character then happens. Backtracking can + occur as usual to the left of (*PRUNE), before it is reached, or when + matching to the right of (*PRUNE), but if there is no match to the + right, backtracking cannot cross (*PRUNE). In simple cases, the use of + (*PRUNE) is just an alternative to an atomic group or possessive quan- + tifier, but there are some uses of (*PRUNE) that cannot be expressed in + any other way. In an anchored pattern (*PRUNE) has the same effect as + (*COMMIT). + + The behaviour of (*PRUNE:NAME) is the not the same as + (*MARK:NAME)(*PRUNE). It is like (*MARK:NAME) in that the name is + remembered for passing back to the caller. However, (*SKIP:NAME) + searches only for names set with (*MARK). (*SKIP) - This verb, when given without a name, is like (*PRUNE), except that if - the pattern is unanchored, the "bumpalong" advance is not to the next + This verb, when given without a name, is like (*PRUNE), except that if + the pattern is unanchored, the "bumpalong" advance is not to the next character, but to the position in the subject where (*SKIP) was encoun- - tered. (*SKIP) signifies that whatever text was matched leading up to + tered. (*SKIP) signifies that whatever text was matched leading up to it cannot be part of a successful match. Consider: a+(*SKIP)b - If the subject is "aaaac...", after the first match attempt fails - (starting at the first character in the string), the starting point + If the subject is "aaaac...", after the first match attempt fails + (starting at the first character in the string), the starting point skips on to start the next attempt at "c". Note that a possessive quan- - tifer does not have the same effect as this example; although it would - suppress backtracking during the first match attempt, the second - attempt would start at the second character instead of skipping on to + tifer does not have the same effect as this example; although it would + suppress backtracking during the first match attempt, the second + attempt would start at the second character instead of skipping on to "c". (*SKIP:NAME) - When (*SKIP) has an associated name, its behaviour is modified. If the - following pattern fails to match, the previous path through the pattern - is searched for the most recent (*MARK) that has the same name. If one - is found, the "bumpalong" advance is to the subject position that cor- - responds to that (*MARK) instead of to where (*SKIP) was encountered. - If no (*MARK) with a matching name is found, the (*SKIP) is ignored. + When (*SKIP) has an associated name, its behaviour is modified. When it + is triggered, the previous path through the pattern is searched for the + most recent (*MARK) that has the same name. If one is found, the + "bumpalong" advance is to the subject position that corresponds to that + (*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with + a matching name is found, the (*SKIP) is ignored. + + Note that (*SKIP:NAME) searches only for names set by (*MARK:NAME). It + ignores names that are set by (*PRUNE:NAME) or (*THEN:NAME). (*THEN) or (*THEN:NAME) - This verb causes a skip to the next innermost alternative if the rest - of the pattern does not match. That is, it cancels pending backtrack- - ing, but only within the current alternative. Its name comes from the - observation that it can be used for a pattern-based if-then-else block: + This verb causes a skip to the next innermost alternative when back- + tracking reaches it. That is, it cancels any further backtracking + within the current alternative. Its name comes from the observation + that it can be used for a pattern-based if-then-else block: ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ... If the COND1 pattern matches, FOO is tried (and possibly further items after the end of the group if FOO succeeds); on failure, the matcher skips to the second alternative and tries COND2, without backtracking - into COND1. The behaviour of (*THEN:NAME) is exactly the same as - (*MARK:NAME)(*THEN). If (*THEN) is not inside an alternation, it acts - like (*PRUNE). + into COND1. If that succeeds and BAR fails, COND3 is tried. If subse- + quently BAZ fails, there are no more alternatives, so there is a back- + track to whatever came before the entire group. If (*THEN) is not + inside an alternation, it acts like (*PRUNE). - 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: + The behaviour of (*THEN:NAME) is the not the same as + (*MARK:NAME)(*THEN). It is like (*MARK:NAME) in that the name is + remembered for passing back to the caller. However, (*SKIP:NAME) + searches only for names set with (*MARK). + + A subpattern that does not contain a | character is just a part of the + enclosing alternative; it is not a nested alternation with only one + alternative. The effect of (*THEN) extends beyond such a subpattern to + the enclosing alternative. Consider this pattern, where A, B, etc. are + complex pattern fragments that do not contain any | characters at this + level: A (B(*THEN)C) | D @@ -7127,7 +7528,7 @@ BACKTRACKING CONTROL tern to fail because there are no more alternatives to try. In this case, matching does now backtrack into A. - Note also that a conditional subpattern is not considered as having two + Note that a conditional subpattern is not considered as having two alternatives, because only one is ever used. In other words, the | character in a conditional subpattern has a different meaning. Ignoring white space, consider: @@ -7151,16 +7552,78 @@ BACKTRACKING CONTROL the advance may be more than one character. (*COMMIT) is the strongest, causing the entire match to fail. - If more than one such verb is present in a pattern, the "strongest" one - wins. For example, consider this pattern, where A, B, etc. are complex - pattern fragments: + More than one backtracking verb - (A(*COMMIT)B(*THEN)C|D) + If more than one backtracking verb is present in a pattern, the one + that is backtracked onto first acts. For example, consider this pat- + tern, where A, B, etc. are complex pattern fragments: - 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. + (A(*COMMIT)B(*THEN)C|ABD) + + If A matches but B fails, the backtrack to (*COMMIT) causes the entire + match to fail. However, if A and B match, but C fails, the backtrack to + (*THEN) causes the next alternative (ABD) to be tried. This behaviour + is consistent, but is not always the same as Perl's. It means that if + two or more backtracking verbs appear in succession, all the the last + of them has no effect. Consider this example: + + ...(*COMMIT)(*PRUNE)... + + If there is a matching failure to the right, backtracking onto (*PRUNE) + causes it to be triggered, and its action is taken. There can never be + a backtrack onto (*COMMIT). + + Backtracking verbs in repeated groups + + PCRE differs from Perl in its handling of backtracking verbs in + repeated groups. For example, consider: + + /(a(*COMMIT)b)+ac/ + + If the subject is "abac", Perl matches, but PCRE fails because the + (*COMMIT) in the second repeat of the group acts. + + Backtracking verbs in assertions + + (*FAIL) in an assertion has its normal effect: it forces an immediate + backtrack. + + (*ACCEPT) in a positive assertion causes the assertion to succeed with- + out any further processing. In a negative assertion, (*ACCEPT) causes + the assertion to fail without any further processing. + + The other backtracking verbs are not treated specially if they appear + in a positive assertion. In particular, (*THEN) skips to the next + alternative in the innermost enclosing group that has alternations, + whether or not this is within the assertion. + + Negative assertions are, however, different, in order to ensure that + changing a positive assertion into a negative assertion changes its + result. Backtracking into (*COMMIT), (*SKIP), or (*PRUNE) causes a neg- + ative assertion to be true, without considering any further alternative + branches in the assertion. Backtracking into (*THEN) causes it to skip + to the next enclosing alternative within the assertion (the normal be- + haviour), but if the assertion does not have such an alternative, + (*THEN) behaves like (*PRUNE). + + Backtracking verbs in subroutines + + These behaviours occur whether or not the subpattern is called recur- + sively. Perl's treatment of subroutines is different in some cases. + + (*FAIL) in a subpattern called as a subroutine has its normal effect: + it forces an immediate backtrack. + + (*ACCEPT) in a subpattern called as a subroutine causes the subroutine + match to succeed without any further processing. Matching then contin- + ues after the subroutine call. + + (*COMMIT), (*SKIP), and (*PRUNE) in a subpattern called as a subroutine + cause the subroutine match to fail. + + (*THEN) skips to the next alternative in the innermost enclosing group + within the subpattern that has alternatives. If there is no such group + within the subpattern, (*THEN) causes the subroutine match to fail. SEE ALSO @@ -7178,18 +7641,18 @@ AUTHOR REVISION - Last updated: 11 November 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 08 January 2014 + Copyright (c) 1997-2014 University of Cambridge. ------------------------------------------------------------------------------ -PCRESYNTAX(3) PCRESYNTAX(3) +PCRESYNTAX(3) Library Functions Manual PCRESYNTAX(3) + NAME PCRE - Perl-compatible regular expressions - PCRE REGULAR EXPRESSION SYNTAX SUMMARY The full syntax and semantics of the regular expressions that are sup- @@ -7212,10 +7675,15 @@ CHARACTERS \n newline (hex 0A) \r carriage return (hex 0D) \t tab (hex 09) + \0dd character with octal code 0dd \ddd character with octal code ddd, or backreference + \o{ddd..} character with octal code ddd.. \xhh character with hex code hh \x{hhh..} character with hex code hhh.. + Note that \0dd is always an octal code, and that \8 and \9 are the lit- + eral characters "8" and "9". + CHARACTER TYPES @@ -7238,9 +7706,12 @@ CHARACTER TYPES \W a "non-word" character \X a Unicode extended grapheme cluster - In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII - characters, even in a UTF mode. However, this can be changed by setting - the PCRE_UCP option. + By default, \d, \s, and \w match only ASCII characters, even in UTF-8 + mode or in the 16- bit and 32-bit libraries. However, if locale-spe- + cific matching is happening, \s and \w may also match characters with + code points in the range 128-255. If the PCRE_UCP option is set, the + behaviour of these escape sequences is changed to use Unicode proper- + ties and they match many more characters. GENERAL CATEGORY PROPERTIES FOR \p and \P @@ -7295,27 +7766,32 @@ PCRE SPECIAL CATEGORY PROPERTIES FOR \p and \P Xan Alphanumeric: union of properties L and N Xps POSIX space: property Z or tab, NL, VT, FF, CR - Xsp Perl space: property Z or tab, NL, FF, CR + Xsp Perl space: property Z or tab, NL, VT, FF, CR + Xuc Univerally-named character: one that can be + represented by a Universal Character Name Xwd Perl word: property Xan or underscore + Perl and POSIX space are now the same. Perl added VT to its space char- + acter set at release 5.18 and PCRE changed at release 8.34. + SCRIPT NAMES FOR \p AND \P - Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, - Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, - Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, - Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, - Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira- - gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip- - tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, - Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, + Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, + Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, + Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, + Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, + Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira- + gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip- + tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, + Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, - Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, - Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, - Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samari- - tan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, - Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, - Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, + Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, + Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, + Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samari- + tan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, + Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, + Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, Yi. @@ -7342,8 +7818,8 @@ CHARACTER CLASSES word same as \w xdigit hexadecimal digit - In PCRE, POSIX character set names recognize only ASCII characters by - default, but some of them use Unicode properties if PCRE_UCP is set. + In PCRE, POSIX character set names recognize only ASCII characters by + default, but some of them use Unicode properties if PCRE_UCP is set. You can use \Q...\E inside a character class. @@ -7387,6 +7863,8 @@ MATCH POINT RESET \K reset start of match + \K is honoured in positive assertions, but ignored in negative ones. + ALTERNATION @@ -7424,9 +7902,13 @@ OPTION SETTING (?x) extended (ignore white space) (?-...) unset option(s) - The following are recognized only at the start of a pattern or after - one of the newline-setting options with similar syntax: + The following are recognized only at the very start of a pattern or + after one of the newline or \R options with similar syntax. More than + one of them may appear. + (*LIMIT_MATCH=d) set the match limit to d (decimal number) + (*LIMIT_RECURSION=d) set the recursion limit to d (decimal number) + (*NO_AUTO_POSSESS) no auto-possessification (PCRE_NO_AUTO_POSSESS) (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE) (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8) (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16) @@ -7434,6 +7916,30 @@ OPTION SETTING (*UTF) set appropriate UTF mode for the library in use (*UCP) set PCRE_UCP (use Unicode properties for \d etc) + Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value of + the limits set by the caller of pcre_exec(), not increase them. + + +NEWLINE CONVENTION + + These are recognized only at the very start of the pattern or after + option settings with a similar syntax. + + (*CR) carriage return only + (*LF) linefeed only + (*CRLF) carriage return followed by linefeed + (*ANYCRLF) all three of the above + (*ANY) any Unicode newline sequence + + +WHAT \R MATCHES + + These are recognized only at the very start of the pattern or after + option setting with a similar syntax. + + (*BSR_ANYCRLF) CR, LF, or CRLF + (*BSR_UNICODE) any Unicode newline sequence + LOOKAHEAD AND LOOKBEHIND ASSERTIONS @@ -7502,7 +8008,7 @@ BACKTRACKING CONTROL (*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- + 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 what happens afterwards. Those that advance the start-of-match point do so only if the pattern is not anchored. @@ -7517,27 +8023,6 @@ BACKTRACKING CONTROL (*THEN:NAME) equivalent to (*MARK:NAME)(*THEN) -NEWLINE CONVENTIONS - - These are recognized only at the very start of the pattern or after a - (*BSR_...), (*UTF8), (*UTF16), (*UTF32) or (*UCP) option. - - (*CR) carriage return only - (*LF) linefeed only - (*CRLF) carriage return followed by linefeed - (*ANYCRLF) all three of the above - (*ANY) any Unicode newline sequence - - -WHAT \R MATCHES - - These are recognized only at the very start of the pattern or after a - (*...) option that sets the newline convention or a UTF or UCP mode. - - (*BSR_ANYCRLF) CR, LF, or CRLF - (*BSR_UNICODE) any Unicode newline sequence - - CALLOUTS (?C) callout @@ -7558,18 +8043,18 @@ AUTHOR REVISION - Last updated: 11 November 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 08 January 2014 + Copyright (c) 1997-2014 University of Cambridge. ------------------------------------------------------------------------------ -PCREUNICODE(3) PCREUNICODE(3) +PCREUNICODE(3) Library Functions Manual PCREUNICODE(3) + NAME PCRE - Perl-compatible regular expressions - UTF-8, UTF-16, UTF-32, AND UNICODE PROPERTY SUPPORT As well as UTF-8 support, PCRE also supports UTF-16 (from release 8.30) @@ -7632,7 +8117,9 @@ UNICODE PROPERTY SUPPORT fication. Earlier releases of PCRE followed the rules of RFC 2279, which allows the full range of 31-bit values (0 to 0x7FFFFFFF). The current check allows only values in the range U+0 to U+10FFFF, exclud- - ing the surrogate area and the non-characters. + ing the surrogate area. (From release 8.33 the so-called "non-charac- + ter" code points are no longer excluded because Unicode corrigendum #9 + makes it clear that they should not be.) Characters in the "Surrogate Area" of Unicode are reserved for use by UTF-16, where they are used in pairs to encode codepoints with values @@ -7641,10 +8128,6 @@ UNICODE PROPERTY SUPPORT other words, the whole surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8 and UTF-32.) - Also excluded are the "Non-Character" code points, which are U+FDD0 to - U+FDEF and the last two code points in each plane, U+??FFFE and - U+??FFFF. - If an invalid UTF-8 string is passed to PCRE, an error return is given. At compile time, the only additional information is the offset to the first byte of the failing character. The run-time functions pcre_exec() @@ -7676,10 +8159,6 @@ UNICODE PROPERTY SUPPORT surrogate range U+D800 to U+DFFF are independent code points. Values in the surrogate range must be used in pairs in the correct manner. - Excluded are the "Non-Character" code points, which are U+FDD0 to - U+FDEF and the last two code points in each plane, U+??FFFE and - U+??FFFF. - If an invalid UTF-16 string is passed to PCRE, an error return is given. At compile time, the only additional information is the offset to the first data unit of the failing character. The run-time functions @@ -7701,77 +8180,76 @@ UNICODE PROPERTY SUPPORT are passed as patterns and subjects are (by default) checked for valid- ity on entry to the relevant functions. This check allows only values in the range U+0 to U+10FFFF, excluding the surrogate area U+D800 to - U+DFFF, and the "Non-Character" code points, which are U+FDD0 to U+FDEF - and the last two characters in each plane, U+??FFFE and U+??FFFF. + U+DFFF. - If an invalid UTF-32 string is passed to PCRE, an error return is - given. At compile time, the only additional information is the offset + If an invalid UTF-32 string is passed to PCRE, an error return is + given. At compile time, the only additional information is the offset to the first data unit of the failing character. The run-time functions pcre32_exec() and pcre32_dfa_exec() also pass back this information, as - well as a more detailed reason code if the caller has provided memory + well as a more detailed reason code if the caller has provided memory in which to do this. - In some situations, you may already know that your strings are valid, - and therefore want to skip these checks in order to improve perfor- - mance. If you set the PCRE_NO_UTF32_CHECK flag at compile time or at + In some situations, you may already know that your strings are valid, + and therefore want to skip these checks in order to improve perfor- + mance. If you set the PCRE_NO_UTF32_CHECK flag at compile time or at run time, PCRE assumes that the pattern or subject it is given (respec- tively) contains only valid UTF-32 sequences. In this case, it does not - diagnose an invalid UTF-32 string. However, if an invalid string is + diagnose an invalid UTF-32 string. However, if an invalid string is passed, the result is undefined. General comments about UTF modes - 1. Codepoints less than 256 can be specified in patterns by either + 1. Codepoints less than 256 can be specified in patterns by either braced or unbraced hexadecimal escape sequences (for example, \x{b3} or \xb3). Larger values have to use braced sequences. - 2. Octal numbers up to \777 are recognized, and in UTF-8 mode they + 2. Octal numbers up to \777 are recognized, and in UTF-8 mode they match two-byte characters for values greater than \177. 3. Repeat quantifiers apply to complete UTF characters, not to individ- ual data units, for example: \x{100}{3}. - 4. The dot metacharacter matches one UTF character instead of a single + 4. The dot metacharacter matches one UTF character instead of a single data unit. - 5. The escape sequence \C can be used to match a single byte in UTF-8 - mode, or a single 16-bit data unit in UTF-16 mode, or a single 32-bit - data unit in UTF-32 mode, but its use can lead to some strange effects - because it breaks up multi-unit characters (see the description of \C - in the pcrepattern documentation). The use of \C is not supported in - the alternative matching function pcre[16|32]_dfa_exec(), nor is it + 5. The escape sequence \C can be used to match a single byte in UTF-8 + mode, or a single 16-bit data unit in UTF-16 mode, or a single 32-bit + data unit in UTF-32 mode, but its use can lead to some strange effects + because it breaks up multi-unit characters (see the description of \C + in the pcrepattern documentation). The use of \C is not supported in + the alternative matching function pcre[16|32]_dfa_exec(), nor is it supported in UTF mode by the JIT optimization of pcre[16|32]_exec(). If - JIT optimization is requested for a UTF pattern that contains \C, it + JIT optimization is requested for a UTF pattern that contains \C, it will not succeed, and so the matching will be carried out by the normal interpretive function. - 6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly + 6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly test characters of any code value, but, by default, the characters that - PCRE recognizes as digits, spaces, or word characters remain the same - set as in non-UTF mode, all with values less than 256. This remains - true even when PCRE is built to include Unicode property support, + PCRE recognizes as digits, spaces, or word characters remain the same + set as in non-UTF mode, all with values less than 256. This remains + true even when PCRE is built to include Unicode property support, because to do otherwise would slow down PCRE in many common cases. Note - in particular that this applies to \b and \B, because they are defined + in particular that this applies to \b and \B, because they are defined in terms of \w and \W. If you really want to test for a wider sense of, - say, "digit", you can use explicit Unicode property tests such as + say, "digit", you can use explicit Unicode property tests such as \p{Nd}. Alternatively, if you set the PCRE_UCP option, the way that the - character escapes work is changed so that Unicode properties are used + character escapes work is changed so that Unicode properties are used to determine which characters match. There are more details in the sec- tion on generic character types in the pcrepattern documentation. - 7. Similarly, characters that match the POSIX named character classes + 7. Similarly, characters that match the POSIX named character classes are all low-valued characters, unless the PCRE_UCP option is set. - 8. However, the horizontal and vertical white space matching escapes - (\h, \H, \v, and \V) do match all the appropriate Unicode characters, + 8. However, the horizontal and vertical white space matching escapes + (\h, \H, \v, and \V) do match all the appropriate Unicode characters, whether or not PCRE_UCP is set. - 9. Case-insensitive matching applies only to characters whose values - are less than 128, unless PCRE is built with Unicode property support. - A few Unicode characters such as Greek sigma have more than two code- + 9. Case-insensitive matching applies only to characters whose values + are less than 128, unless PCRE is built with Unicode property support. + A few Unicode characters such as Greek sigma have more than two code- points that are case-equivalent. Up to and including PCRE release 8.31, - only one-to-one case mappings were supported, but later releases (with - Unicode property support) do treat as case-equivalent all versions of + only one-to-one case mappings were supported, but later releases (with + Unicode property support) do treat as case-equivalent all versions of characters such as Greek sigma. @@ -7784,18 +8262,18 @@ AUTHOR REVISION - Last updated: 11 November 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 27 February 2013 + Copyright (c) 1997-2013 University of Cambridge. ------------------------------------------------------------------------------ -PCREJIT(3) PCREJIT(3) +PCREJIT(3) Library Functions Manual PCREJIT(3) + NAME PCRE - Perl-compatible regular expressions - PCRE JUST-IN-TIME COMPILER SUPPORT Just-in-time compiling is a heavyweight optimization that can greatly @@ -7941,15 +8419,9 @@ UNSUPPORTED OPTIONS AND PATTERN ITEMS BOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PAR- TIAL_HARD, and PCRE_PARTIAL_SOFT. - The unsupported pattern items are: - - \C match a single byte; not supported in UTF-8 mode - (?Cn) callouts - (*PRUNE) ) - (*SKIP) ) backtracking control verbs - (*THEN) ) - - Support for some of these may be added in future. + The only unsupported pattern items are \C (match a single data unit) + when running in a UTF mode, and a callout immediately before an asser- + tion condition in a conditional group. RETURN VALUES FROM JIT EXECUTION @@ -8203,18 +8675,18 @@ AUTHOR REVISION - Last updated: 31 October 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 17 March 2013 + Copyright (c) 1997-2013 University of Cambridge. ------------------------------------------------------------------------------ -PCREPARTIAL(3) PCREPARTIAL(3) +PCREPARTIAL(3) Library Functions Manual PCREPARTIAL(3) + NAME PCRE - Perl-compatible regular expressions - PARTIAL MATCHING IN PCRE In normal use of PCRE, if the subject string that is passed to a match- @@ -8273,7 +8745,7 @@ PARTIAL MATCHING USING pcre_exec() OR pcre[16|32]_exec() A partial match occurs during a call to pcre_exec() or pcre[16|32]_exec() when the end of the subject string is reached suc- cessfully, but matching cannot continue because more characters are - needed. However, at least one character in the subject must have been + needed. However, at least one character in the subject must have been inspected. This character need not form part of the final matched string; lookbehind assertions and the \K escape sequence provide ways of inspecting characters before the start of a matched substring. The @@ -8286,18 +8758,22 @@ PARTIAL MATCHING USING pcre_exec() OR pcre[16|32]_exec() match is returned, the first slot is set to the offset of the earliest character that was inspected. For convenience, the second offset points to the end of the subject so that a substring can easily be identified. + If there are at least three slots in the offsets vector, the third slot + is set to the offset of the character where matching started. - For the majority of patterns, the first offset identifies the start of - the partially matched string. However, for patterns that contain look- - behind assertions, or \K, or begin with \b or \B, earlier characters - have been inspected while carrying out the match. For example: + For the majority of patterns, the contents of the first and third slots + will be the same. However, for patterns that contain lookbehind asser- + tions, or begin with \b or \B, characters before the one where matching + started may have been inspected while carrying out the match. For exam- + ple, consider this pattern: /(?<=abc)123/ This pattern matches "123", but only if it is preceded by "abc". If the - subject string is "xyzabc12", the offsets after a partial match are for - the substring "abc12", because all these characters are needed if - another match is tried with extra characters added to the subject. + subject string is "xyzabc12", the first two offsets after a partial + match are for the substring "abc12", because all these characters were + inspected. However, the third offset is set to 6, because that is the + offset where matching began. What happens when a partial match is identified depends on which of the two partial matching options are set. @@ -8491,6 +8967,16 @@ MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre[16|32]_dfa_exec() matched string. It is up to the calling program to do that if it needs to. + That means that, for an unanchored pattern, if a continued match fails, + it is not possible to try again at a new starting point. All this + facility is capable of doing is continuing with the previous match + attempt. In the previous example, if the second set of data is "ug23" + the result is no match, even though there would be a match for "aug23" + if the entire string were given at once. Depending on the application, + this may or may not be what you want. The only way to allow for start- + ing again at the next character is to retain the matched part of the + subject and try a new complete match. + You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with PCRE_DFA_RESTART to continue partial matching over multiple segments. This facility can be used to pass very long subject strings to the DFA @@ -8523,10 +9009,9 @@ MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre[16|32]_exec() Note: If the pattern contains lookbehind assertions, or \K, or starts with \b or \B, the string that is returned for a partial match includes - characters that precede the partially matched string itself, because - these must be retained when adding on more characters for a subsequent - matching attempt. However, in some cases you may need to retain even - earlier characters, as discussed in the next section. + characters that precede the start of what would be returned for a com- + plete match, because it contains all the characters that were inspected + during the partial match. ISSUES WITH MULTI-SEGMENT MATCHING @@ -8535,23 +9020,44 @@ ISSUES WITH MULTI-SEGMENT MATCHING whichever matching function is used. 1. If the pattern contains a test for the beginning of a line, you need - to pass the PCRE_NOTBOL option when the subject string for any call - does start at the beginning of a line. There is also a PCRE_NOTEOL + to pass the PCRE_NOTBOL option when the subject string for any call + does start at the beginning of a line. There is also a PCRE_NOTEOL option, but in practice when doing multi-segment matching you should be using PCRE_PARTIAL_HARD, which includes the effect of PCRE_NOTEOL. - 2. Lookbehind assertions that have already been obeyed are catered for + 2. Lookbehind assertions that have already been obeyed are catered for in the offsets that are returned for a partial match. However a lookbe- - hind assertion later in the pattern could require even earlier charac- - ters to be inspected. You can handle this case by using the + hind assertion later in the pattern could require even earlier charac- + ters to be inspected. You can handle this case by using the PCRE_INFO_MAXLOOKBEHIND option of the pcre_fullinfo() or - pcre[16|32]_fullinfo() functions to obtain the length of the largest - lookbehind in the pattern. This length is given in characters, not - bytes. If you always retain at least that many characters before the - partially matched string, all should be well. (Of course, near the + pcre[16|32]_fullinfo() functions to obtain the length of the longest + lookbehind in the pattern. This length is given in characters, not + bytes. If you always retain at least that many characters before the + partially matched string, all should be well. (Of course, near the start of the subject, fewer characters may be present; in that case all characters should be retained.) + From release 8.33, there is a more accurate way of deciding which char- + acters to retain. Instead of subtracting the length of the longest + lookbehind from the earliest inspected character (offsets[0]), the + match start position (offsets[2]) should be used, and the next match + attempt started at the offsets[2] character by setting the startoffset + argument of pcre_exec() or pcre_dfa_exec(). + + For example, if the pattern "(?<=123)abc" is partially matched against + the string "xx123a", the three offset values returned are 2, 6, and 5. + This indicates that the matching process that gave a partial match + started at offset 5, but the characters "123a" were all inspected. The + maximum lookbehind for that pattern is 3, so taking that away from 5 + shows that we need only keep "123a", and the next match attempt can be + started at offset 3 (that is, at "a") when further characters have been + added. When the match start is not the earliest inspected character, + pcretest shows it explicitly: + + re> "(?<=123)abc" + data> xx123a\P\P + Partial match at offset 5: 123a + 3. Because a partial match must always contain at least one character, what might be considered a partial match of an empty string actually gives a "no match" result. For example: @@ -8654,18 +9160,18 @@ AUTHOR REVISION - Last updated: 24 June 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 02 July 2013 + Copyright (c) 1997-2013 University of Cambridge. ------------------------------------------------------------------------------ -PCREPRECOMPILE(3) PCREPRECOMPILE(3) +PCREPRECOMPILE(3) Library Functions Manual PCREPRECOMPILE(3) + NAME PCRE - Perl-compatible regular expressions - SAVING AND RE-USING PRECOMPILED PCRE PATTERNS If you are running an application that uses a large number of regular @@ -8758,6 +9264,10 @@ RE-USING A PRECOMPILED PATTERN is used to pass this data, as described in the section on matching a pattern in the pcreapi documentation. + Warning: The tables that pcre_exec() and pcre_dfa_exec() use must be + the same as those that were used when the pattern was compiled. If this + is not the case, the behaviour is undefined. + If you did not provide custom character tables when the pattern was compiled, the pointer in the compiled pattern is NULL, which causes the matching functions to use PCRE's internal tables. Thus, you do not need @@ -8789,18 +9299,18 @@ AUTHOR REVISION - Last updated: 24 June 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 12 November 2013 + Copyright (c) 1997-2013 University of Cambridge. ------------------------------------------------------------------------------ -PCREPERFORM(3) PCREPERFORM(3) +PCREPERFORM(3) Library Functions Manual PCREPERFORM(3) + NAME PCRE - Perl-compatible regular expressions - PCRE PERFORMANCE Two aspects of performance are discussed below: memory usage and pro- @@ -8964,14 +9474,14 @@ REVISION ------------------------------------------------------------------------------ -PCREPOSIX(3) PCREPOSIX(3) +PCREPOSIX(3) Library Functions Manual PCREPOSIX(3) + NAME PCRE - Perl-compatible regular expressions. - -SYNOPSIS OF POSIX API +SYNOPSIS #include @@ -8980,8 +9490,7 @@ SYNOPSIS OF POSIX API int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); - - size_t regerror(int errcode, const regex_t *preg, + size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size); void regfree(regex_t *preg); @@ -9229,13 +9738,13 @@ REVISION ------------------------------------------------------------------------------ -PCRECPP(3) PCRECPP(3) +PCRECPP(3) Library Functions Manual PCRECPP(3) + NAME PCRE - Perl-compatible regular expressions. - SYNOPSIS OF C++ WRAPPER #include @@ -9572,13 +10081,13 @@ REVISION ------------------------------------------------------------------------------ -PCRESAMPLE(3) PCRESAMPLE(3) +PCRESAMPLE(3) Library Functions Manual PCRESAMPLE(3) + NAME PCRE - Perl-compatible regular expressions - PCRE SAMPLE PROGRAM A simple, complete demonstration program, to get you started with using @@ -9658,51 +10167,56 @@ REVISION Last updated: 10 January 2012 Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ -PCRELIMITS(3) PCRELIMITS(3) +PCRELIMITS(3) Library Functions Manual PCRELIMITS(3) + NAME PCRE - Perl-compatible regular expressions - SIZE AND OTHER LIMITATIONS There are some size limitations in PCRE but it is hoped that they will never in practice be relevant. The maximum length of a compiled pattern is approximately 64K data - units (bytes for the 8-bit library, 32-bit units for the 32-bit + units (bytes for the 8-bit library, 16-bit units for the 16-bit library, and 32-bit units for the 32-bit library) if PCRE is compiled - with the default internal linkage size of 2 bytes. If you want to - process regular expressions that are truly enormous, you can compile - PCRE with an internal linkage size of 3 or 4 (when building the 16-bit - or 32-bit library, 3 is rounded up to 4). See the README file in the - source distribution and the pcrebuild documentation for details. In - these cases the limit is substantially larger. However, the speed of + with the default internal linkage size, which is 2 bytes for the 8-bit + and 16-bit libraries, and 4 bytes for the 32-bit library. If you want + to process regular expressions that are truly enormous, you can compile + PCRE with an internal linkage size of 3 or 4 (when building the 16-bit + or 32-bit library, 3 is rounded up to 4). See the README file in the + source distribution and the pcrebuild documentation for details. In + these cases the limit is substantially larger. However, the speed of execution is slower. All values in repeating quantifiers must be less than 65536. There is no limit to the number of parenthesized subpatterns, but there - can be no more than 65535 capturing subpatterns. + can be no more than 65535 capturing subpatterns. There is, however, a + limit to the depth of nesting of parenthesized subpatterns of all + kinds. This is imposed in order to limit the amount of system stack + used at compile time. The limit can be specified when PCRE is built; + the default is 250. There is a limit to the number of forward references to subsequent sub- - patterns of around 200,000. Repeated forward references with fixed - upper limits, for example, (?2){0,100} when subpattern number 2 is to - the right, are included in the count. There is no limit to the number + patterns of around 200,000. Repeated forward references with fixed + upper limits, for example, (?2){0,100} when subpattern number 2 is to + the right, are included in the count. There is no limit to the number of backward references. The maximum length of name for a named subpattern is 32 characters, and the maximum number of named subpatterns is 10000. - The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or - (*THEN) verb is 255 for the 8-bit library and 65535 for the 16-bit and - 32-bit library. + The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or + (*THEN) verb is 255 for the 8-bit library and 65535 for the 16-bit and + 32-bit libraries. - The maximum length of a subject string is the largest positive number - that an integer variable can hold. However, when using the traditional + The maximum length of a subject string is the largest positive number + that an integer variable can hold. However, when using the traditional matching function, PCRE uses recursion to handle subpatterns and indef- - inite repetition. This means that the available stack space may limit + inite repetition. This means that the available stack space may limit the size of a subject string that can be processed by certain patterns. For a discussion of stack issues, see the pcrestack documentation. @@ -9716,18 +10230,18 @@ AUTHOR REVISION - Last updated: 04 May 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 05 November 2013 + Copyright (c) 1997-2013 University of Cambridge. ------------------------------------------------------------------------------ -PCRESTACK(3) PCRESTACK(3) +PCRESTACK(3) Library Functions Manual PCRESTACK(3) + NAME PCRE - Perl-compatible regular expressions - PCRE DISCUSSION OF STACK USAGE When you call pcre[16|32]_exec(), it makes use of an internal function diff --git a/tools/pcre/doc/pcre16.3 b/tools/pcre/doc/pcre16.3 index 2a630842..85126a67 100644 --- a/tools/pcre/doc/pcre16.3 +++ b/tools/pcre/doc/pcre16.3 @@ -1,4 +1,4 @@ -.TH PCRE 3 "08 November 2012" "PCRE 8.32" +.TH PCRE 3 "12 May 2013" "PCRE 8.33" .SH NAME PCRE - Perl-compatible regular expressions .sp @@ -8,140 +8,120 @@ PCRE - Perl-compatible regular expressions .SH "PCRE 16-BIT API BASIC FUNCTIONS" .rs .sp -.SM +.nf .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 " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.sp .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 " int *\fIerrorcodeptr\fP," +.B " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.sp .B pcre16_extra *pcre16_study(const pcre16 *\fIcode\fP, int \fIoptions\fP, -.ti +5n -.B const char **\fIerrptr\fP); -.PP +.B " const char **\fIerrptr\fP);" +.sp .B void pcre16_free_study(pcre16_extra *\fIextra\fP); -.PP +.sp .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 " PCRE_SPTR16 \fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP);" +.sp .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); +.B " PCRE_SPTR16 \fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " int *\fIworkspace\fP, int \fIwscount\fP);" +.fi . . .SH "PCRE 16-BIT API STRING EXTRACTION FUNCTIONS" .rs .sp +.nf .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 " PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP," +.B " PCRE_UCHAR16 *\fIbuffer\fP, int \fIbuffersize\fP);" +.sp .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 \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR16 *\fIbuffer\fP," +.B " int \fIbuffersize\fP);" +.sp .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 " PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP," +.B " PCRE_SPTR16 *\fIstringptr\fP);" +.sp .B int pcre16_get_stringnumber(const pcre16 *\fIcode\fP, -.ti +5n -.B PCRE_SPTR16 \fIname\fP); -.PP +.B " PCRE_SPTR16 \fIname\fP); +.sp .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 " PCRE_SPTR16 \fIname\fP, PCRE_UCHAR16 **\fIfirst\fP, PCRE_UCHAR16 **\fIlast\fP);" +.sp .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 \fIstringcount\fP, int \fIstringnumber\fP," +.B " PCRE_SPTR16 *\fIstringptr\fP);" +.sp .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 " int *\fIovector\fP, int \fIstringcount\fP, PCRE_SPTR16 **\fIlistptr\fP);" +.sp .B void pcre16_free_substring(PCRE_SPTR16 \fIstringptr\fP); -.PP +.sp .B void pcre16_free_substring_list(PCRE_SPTR16 *\fIstringptr\fP); +.fi . . .SH "PCRE 16-BIT API AUXILIARY FUNCTIONS" .rs .sp +.nf .B pcre16_jit_stack *pcre16_jit_stack_alloc(int \fIstartsize\fP, int \fImaxsize\fP); -.PP +.sp .B void pcre16_jit_stack_free(pcre16_jit_stack *\fIstack\fP); -.PP +.sp .B void pcre16_assign_jit_stack(pcre16_extra *\fIextra\fP, -.ti +5n -.B pcre16_jit_callback \fIcallback\fP, void *\fIdata\fP); -.PP +.B " pcre16_jit_callback \fIcallback\fP, void *\fIdata\fP);" +.sp .B const unsigned char *pcre16_maketables(void); -.PP +.sp .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 \fIwhat\fP, void *\fIwhere\fP);" +.sp .B int pcre16_refcount(pcre16 *\fIcode\fP, int \fIadjust\fP); -.PP +.sp .B int pcre16_config(int \fIwhat\fP, void *\fIwhere\fP); -.PP +.sp .B const char *pcre16_version(void); -.PP +.sp .B int pcre16_pattern_to_host_byte_order(pcre16 *\fIcode\fP, -.ti +5n -.B pcre16_extra *\fIextra\fP, const unsigned char *\fItables\fP); +.B " pcre16_extra *\fIextra\fP, const unsigned char *\fItables\fP);" +.fi . . .SH "PCRE 16-BIT API INDIRECTED FUNCTIONS" .rs .sp +.nf .B void *(*pcre16_malloc)(size_t); -.PP +.sp .B void (*pcre16_free)(void *); -.PP +.sp .B void *(*pcre16_stack_malloc)(size_t); -.PP +.sp .B void (*pcre16_stack_free)(void *); -.PP +.sp .B int (*pcre16_callout)(pcre16_callout_block *); +.fi . . .SH "PCRE 16-BIT API 16-BIT-ONLY FUNCTION" .rs .sp +.nf .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); +.B " PCRE_SPTR16 \fIinput\fP, int \fIlength\fP, int *\fIbyte_order\fP," +.B " int \fIkeep_boms\fP);" +.fi . . .SH "THE PCRE 16-BIT LIBRARY" @@ -246,8 +226,9 @@ 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. +The lengths and starting offsets of subject strings must be specified in 16-bit +data units, and the offsets within subject strings that are returned by the +matching functions are in also 16-bit units rather than bytes. . . .SH "NAMED SUBPATTERNS" @@ -385,6 +366,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 08 November 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 12 May 2013 +Copyright (c) 1997-2013 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcre32.3 b/tools/pcre/doc/pcre32.3 index 48205ca0..7cde8c08 100644 --- a/tools/pcre/doc/pcre32.3 +++ b/tools/pcre/doc/pcre32.3 @@ -1,4 +1,4 @@ -.TH PCRE 3 "08 November 2012" "PCRE 8.32" +.TH PCRE 3 "12 May 2013" "PCRE 8.33" .SH NAME PCRE - Perl-compatible regular expressions .sp @@ -8,140 +8,119 @@ PCRE - Perl-compatible regular expressions .SH "PCRE 32-BIT API BASIC FUNCTIONS" .rs .sp -.SM +.nf .B pcre32 *pcre32_compile(PCRE_SPTR32 \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 " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.sp .B pcre32 *pcre32_compile2(PCRE_SPTR32 \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 " int *\fIerrorcodeptr\fP," +.B " const unsigned char *\fItableptr\fP);" +.sp .B pcre32_extra *pcre32_study(const pcre32 *\fIcode\fP, int \fIoptions\fP, -.ti +5n -.B const char **\fIerrptr\fP); -.PP +.B " const char **\fIerrptr\fP);" +.sp .B void pcre32_free_study(pcre32_extra *\fIextra\fP); -.PP +.sp .B int pcre32_exec(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," -.ti +5n -.B "PCRE_SPTR32 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, -.ti +5n -.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); -.PP +.B " PCRE_SPTR32 \fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP);" +.sp .B int pcre32_dfa_exec(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," -.ti +5n -.B "PCRE_SPTR32 \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); +.B " PCRE_SPTR32 \fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " int *\fIworkspace\fP, int \fIwscount\fP);" +.fi . . .SH "PCRE 32-BIT API STRING EXTRACTION FUNCTIONS" .rs .sp +.nf .B int pcre32_copy_named_substring(const pcre32 *\fIcode\fP, -.ti +5n -.B PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP, -.ti +5n -.B PCRE_UCHAR32 *\fIbuffer\fP, int \fIbuffersize\fP); -.PP +.B " PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP," +.B " PCRE_UCHAR32 *\fIbuffer\fP, int \fIbuffersize\fP);" +.sp .B int pcre32_copy_substring(PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR32 *\fIbuffer\fP, -.ti +5n -.B int \fIbuffersize\fP); -.PP +.B " int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR32 *\fIbuffer\fP," +.B " int \fIbuffersize\fP);" +.sp .B int pcre32_get_named_substring(const pcre32 *\fIcode\fP, -.ti +5n -.B PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP, -.ti +5n -.B PCRE_SPTR32 *\fIstringptr\fP); -.PP +.B " PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP," +.B " PCRE_SPTR32 *\fIstringptr\fP);" +.sp .B int pcre32_get_stringnumber(const pcre32 *\fIcode\fP, -.ti +5n -.B PCRE_SPTR32 \fIname\fP); -.PP +.B " PCRE_SPTR32 \fIname\fP);" +.sp .B int pcre32_get_stringtable_entries(const pcre32 *\fIcode\fP, -.ti +5n -.B PCRE_SPTR32 \fIname\fP, PCRE_UCHAR32 **\fIfirst\fP, PCRE_UCHAR32 **\fIlast\fP); -.PP +.B " PCRE_SPTR32 \fIname\fP, PCRE_UCHAR32 **\fIfirst\fP, PCRE_UCHAR32 **\fIlast\fP);" +.sp .B int pcre32_get_substring(PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, int \fIstringnumber\fP, -.ti +5n -.B PCRE_SPTR32 *\fIstringptr\fP); -.PP +.B " int \fIstringcount\fP, int \fIstringnumber\fP," +.B " PCRE_SPTR32 *\fIstringptr\fP);" +.sp .B int pcre32_get_substring_list(PCRE_SPTR32 \fIsubject\fP, -.ti +5n -.B int *\fIovector\fP, int \fIstringcount\fP, "PCRE_SPTR32 **\fIlistptr\fP);" -.PP +.B " int *\fIovector\fP, int \fIstringcount\fP, PCRE_SPTR32 **\fIlistptr\fP);" +.sp .B void pcre32_free_substring(PCRE_SPTR32 \fIstringptr\fP); -.PP +.sp .B void pcre32_free_substring_list(PCRE_SPTR32 *\fIstringptr\fP); +.fi . . .SH "PCRE 32-BIT API AUXILIARY FUNCTIONS" .rs .sp +.nf .B pcre32_jit_stack *pcre32_jit_stack_alloc(int \fIstartsize\fP, int \fImaxsize\fP); -.PP +.sp .B void pcre32_jit_stack_free(pcre32_jit_stack *\fIstack\fP); -.PP +.sp .B void pcre32_assign_jit_stack(pcre32_extra *\fIextra\fP, -.ti +5n -.B pcre32_jit_callback \fIcallback\fP, void *\fIdata\fP); -.PP +.B " pcre32_jit_callback \fIcallback\fP, void *\fIdata\fP);" +.sp .B const unsigned char *pcre32_maketables(void); -.PP +.sp .B int pcre32_fullinfo(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," -.ti +5n -.B int \fIwhat\fP, void *\fIwhere\fP); -.PP +.B " int \fIwhat\fP, void *\fIwhere\fP);" +.sp .B int pcre32_refcount(pcre32 *\fIcode\fP, int \fIadjust\fP); -.PP +.sp .B int pcre32_config(int \fIwhat\fP, void *\fIwhere\fP); -.PP +.sp .B const char *pcre32_version(void); -.PP +.sp .B int pcre32_pattern_to_host_byte_order(pcre32 *\fIcode\fP, -.ti +5n -.B pcre32_extra *\fIextra\fP, const unsigned char *\fItables\fP); +.B " pcre32_extra *\fIextra\fP, const unsigned char *\fItables\fP);" +.fi . . .SH "PCRE 32-BIT API INDIRECTED FUNCTIONS" .rs .sp +.nf .B void *(*pcre32_malloc)(size_t); -.PP +.sp .B void (*pcre32_free)(void *); -.PP +.sp .B void *(*pcre32_stack_malloc)(size_t); -.PP +.sp .B void (*pcre32_stack_free)(void *); -.PP +.sp .B int (*pcre32_callout)(pcre32_callout_block *); +.fi . . .SH "PCRE 32-BIT API 32-BIT-ONLY FUNCTION" .rs .sp +.nf .B int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *\fIoutput\fP, -.ti +5n -.B PCRE_SPTR32 \fIinput\fP, int \fIlength\fP, int *\fIbyte_order\fP, -.ti +5n -.B int \fIkeep_boms\fP); +.B " PCRE_SPTR32 \fIinput\fP, int \fIlength\fP, int *\fIbyte_order\fP," +.B " int \fIkeep_boms\fP);" +.fi . . .SH "THE PCRE 32-BIT LIBRARY" @@ -246,8 +225,9 @@ 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 32-bit units rather than bytes. +The lengths and starting offsets of subject strings must be specified in 32-bit +data units, and the offsets within subject strings that are returned by the +matching functions are in also 32-bit units rather than bytes. . . .SH "NAMED SUBPATTERNS" @@ -384,6 +364,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 08 November 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 12 May 2013 +Copyright (c) 1997-2013 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcre_assign_jit_stack.3 b/tools/pcre/doc/pcre_assign_jit_stack.3 index e1563b6e..0ecf6f2c 100644 --- a/tools/pcre/doc/pcre_assign_jit_stack.3 +++ b/tools/pcre/doc/pcre_assign_jit_stack.3 @@ -6,18 +6,16 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B void pcre_assign_jit_stack(pcre_extra *\fIextra\fP, -.ti +5n -.B pcre_jit_callback \fIcallback\fP, void *\fIdata\fP); -.PP +.B " pcre_jit_callback \fIcallback\fP, void *\fIdata\fP);" +.sp .B void pcre16_assign_jit_stack(pcre16_extra *\fIextra\fP, -.ti +5n -.B pcre16_jit_callback \fIcallback\fP, void *\fIdata\fP); -.PP +.B " pcre16_jit_callback \fIcallback\fP, void *\fIdata\fP);" +.sp .B void pcre32_assign_jit_stack(pcre32_extra *\fIextra\fP, -.ti +5n -.B pcre32_jit_callback \fIcallback\fP, void *\fIdata\fP); +.B " pcre32_jit_callback \fIcallback\fP, void *\fIdata\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_compile.3 b/tools/pcre/doc/pcre_compile.3 index d09768d8..5c16ebe2 100644 --- a/tools/pcre/doc/pcre_compile.3 +++ b/tools/pcre/doc/pcre_compile.3 @@ -1,4 +1,4 @@ -.TH PCRE_COMPILE 3 "24 June 2012" "PCRE 8.30" +.TH PCRE_COMPILE 3 "01 October 2013" "PCRE 8.34" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -6,24 +6,19 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B pcre *pcre_compile(const char *\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 " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.sp .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 " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.sp .B pcre32 *pcre32_compile(PCRE_SPTR32 \fIpattern\fP, int \fIoptions\fP, -.ti +5n -.B const char **\fIerrptr\fP, int *\fIerroffset\fP, -.ti +5n -.B const unsigned char *\fItableptr\fP); +.B " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.fi . .SH DESCRIPTION .rs @@ -56,6 +51,7 @@ The option bits are: PCRE_FIRSTLINE Force matching to be before newline PCRE_JAVASCRIPT_COMPAT JavaScript compatibility PCRE_MULTILINE ^ and $ match newlines within data + PCRE_NEVER_UTF Lock out UTF, e.g. via (*UTF) PCRE_NEWLINE_ANY Recognize any Unicode newline sequence PCRE_NEWLINE_ANYCRLF Recognize CR, LF, and CRLF as newline sequences @@ -64,6 +60,8 @@ The option bits are: PCRE_NEWLINE_LF Set LF as the newline sequence PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren- theses (named ones available) + PCRE_NO_AUTO_POSSESS Disable auto-possessification + PCRE_NO_START_OPTIMIZE Disable match-time start optimizations PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16 validity (only relevant if PCRE_UTF16 is set) diff --git a/tools/pcre/doc/pcre_compile2.3 b/tools/pcre/doc/pcre_compile2.3 index 1fcae433..37742018 100644 --- a/tools/pcre/doc/pcre_compile2.3 +++ b/tools/pcre/doc/pcre_compile2.3 @@ -1,4 +1,4 @@ -.TH PCRE_COMPILE2 3 "24 June 2012" "PCRE 8.30" +.TH PCRE_COMPILE2 3 "01 October 2013" "PCRE 8.34" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -6,30 +6,22 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B pcre *pcre_compile2(const char *\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 " int *\fIerrorcodeptr\fP," +.B " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.sp .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 " int *\fIerrorcodeptr\fP," +.B " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.sp .B pcre32 *pcre32_compile2(PCRE_SPTR32 \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); +.B " int *\fIerrorcodeptr\fP,£ +.B " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.fi . .SH DESCRIPTION .rs @@ -64,6 +56,7 @@ The option bits are: PCRE_FIRSTLINE Force matching to be before newline PCRE_JAVASCRIPT_COMPAT JavaScript compatibility PCRE_MULTILINE ^ and $ match newlines within data + PCRE_NEVER_UTF Lock out UTF, e.g. via (*UTF) PCRE_NEWLINE_ANY Recognize any Unicode newline sequence PCRE_NEWLINE_ANYCRLF Recognize CR, LF, and CRLF as newline sequences @@ -72,6 +65,8 @@ The option bits are: PCRE_NEWLINE_LF Set LF as the newline sequence PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren- theses (named ones available) + PCRE_NO_AUTO_POSSESS Disable auto-possessification + PCRE_NO_START_OPTIMIZE Disable match-time start optimizations PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16 validity (only relevant if PCRE_UTF16 is set) diff --git a/tools/pcre/doc/pcre_config.3 b/tools/pcre/doc/pcre_config.3 index 5a6e6be7..d3de14bb 100644 --- a/tools/pcre/doc/pcre_config.3 +++ b/tools/pcre/doc/pcre_config.3 @@ -1,4 +1,4 @@ -.TH PCRE_CONFIG 3 "24 June 2012" "PCRE 8.30" +.TH PCRE_CONFIG 3 "05 November 2013" "PCRE 8.34" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -33,6 +33,7 @@ point to an unsigned long integer. The available codes are: 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_PARENS_LIMIT Parentheses nesting limit PCRE_CONFIG_MATCH_LIMIT Internal resource limit PCRE_CONFIG_MATCH_LIMIT_RECURSION Internal recursion depth limit diff --git a/tools/pcre/doc/pcre_copy_named_substring.3 b/tools/pcre/doc/pcre_copy_named_substring.3 index e3281d8f..52582aec 100644 --- a/tools/pcre/doc/pcre_copy_named_substring.3 +++ b/tools/pcre/doc/pcre_copy_named_substring.3 @@ -6,30 +6,22 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B int pcre_copy_named_substring(const pcre *\fIcode\fP, -.ti +5n -.B const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, const char *\fIstringname\fP, -.ti +5n -.B char *\fIbuffer\fP, int \fIbuffersize\fP); -.PP +.B " const char *\fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, const char *\fIstringname\fP," +.B " char *\fIbuffer\fP, int \fIbuffersize\fP);" +.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 " PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP," +.B " PCRE_UCHAR16 *\fIbuffer\fP, int \fIbuffersize\fP);" +.sp .B int pcre32_copy_named_substring(const pcre32 *\fIcode\fP, -.ti +5n -.B PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP, -.ti +5n -.B PCRE_UCHAR32 *\fIbuffer\fP, int \fIbuffersize\fP); +.B " PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP," +.B " PCRE_UCHAR32 *\fIbuffer\fP, int \fIbuffersize\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_copy_substring.3 b/tools/pcre/doc/pcre_copy_substring.3 index 96bff3a2..83af6e80 100644 --- a/tools/pcre/doc/pcre_copy_substring.3 +++ b/tools/pcre/doc/pcre_copy_substring.3 @@ -6,24 +6,19 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B int pcre_copy_substring(const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP, -.ti +5n -.B int \fIbuffersize\fP); -.PP +.B " int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP," +.B " int \fIbuffersize\fP);" +.sp .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 \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR16 *\fIbuffer\fP," +.B " int \fIbuffersize\fP);" +.sp .B int pcre32_copy_substring(PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR32 *\fIbuffer\fP, -.ti +5n -.B int \fIbuffersize\fP); +.B " int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR32 *\fIbuffer\fP," +.B " int \fIbuffersize\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_dfa_exec.3 b/tools/pcre/doc/pcre_dfa_exec.3 index d1901a5e..39c2e836 100644 --- a/tools/pcre/doc/pcre_dfa_exec.3 +++ b/tools/pcre/doc/pcre_dfa_exec.3 @@ -1,4 +1,4 @@ -.TH PCRE_DFA_EXEC 3 "24 June 2012" "PCRE 8.30" +.TH PCRE_DFA_EXEC 3 "12 May 2013" "PCRE 8.33" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -6,30 +6,22 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B int pcre_dfa_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," -.ti +5n -.B "const char *\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); -.PP +.B " const char *\fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " int *\fIworkspace\fP, int \fIwscount\fP);" +.sp .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); -.PP +.B " PCRE_SPTR16 \fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " int *\fIworkspace\fP, int \fIwscount\fP);" +.sp .B int pcre32_dfa_exec(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," -.ti +5n -.B "PCRE_SPTR32 \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); +.B " PCRE_SPTR32 \fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " int *\fIworkspace\fP, int \fIwscount\fP);" +.fi . .SH DESCRIPTION .rs @@ -44,16 +36,17 @@ are: \fIextra\fP Points to an associated \fBpcre[16|32]_extra\fP structure, or is NULL \fIsubject\fP Points to the subject string - \fIlength\fP Length of the subject string, in bytes - \fIstartoffset\fP Offset in bytes in the subject at which to - start matching + \fIlength\fP Length of the subject string + \fIstartoffset\fP Offset in the subject at which to start matching \fIoptions\fP Option bits \fIovector\fP Points to a vector of ints for result offsets \fIovecsize\fP Number of elements in the vector \fIworkspace\fP Points to a vector of ints used as working space \fIwscount\fP Number of elements in the vector .sp -The options are: +The units for \fIlength\fP and \fIstartoffset\fP are bytes for +\fBpcre_exec()\fP, 16-bit data items for \fBpcre16_exec()\fP, and 32-bit items +for \fBpcre32_exec()\fP. The options are: .sp PCRE_ANCHORED Match only at the first position PCRE_BSR_ANYCRLF \eR matches only CR, LF, or CRLF diff --git a/tools/pcre/doc/pcre_exec.3 b/tools/pcre/doc/pcre_exec.3 index 78012edd..4686bd6d 100644 --- a/tools/pcre/doc/pcre_exec.3 +++ b/tools/pcre/doc/pcre_exec.3 @@ -1,4 +1,4 @@ -.TH PCRE_EXEC 3 "24 June 2012" "PCRE 8.30" +.TH PCRE_EXEC 3 "12 May 2013" "PCRE 8.33" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -6,24 +6,19 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .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, -.ti +5n -.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); -.PP +.B " const char *\fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP);" +.sp .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 " PCRE_SPTR16 \fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP);" +.sp .B int pcre32_exec(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," -.ti +5n -.B "PCRE_SPTR32 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, -.ti +5n -.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); +.B " PCRE_SPTR32 \fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP);" +.fi . .SH DESCRIPTION .rs @@ -36,14 +31,15 @@ offsets to captured substrings. Its arguments are: \fIextra\fP Points to an associated \fBpcre[16|32]_extra\fP structure, or is NULL \fIsubject\fP Points to the subject string - \fIlength\fP Length of the subject string, in bytes - \fIstartoffset\fP Offset in bytes in the subject at which to - start matching + \fIlength\fP Length of the subject string + \fIstartoffset\fP Offset in the subject at which to start matching \fIoptions\fP Option bits \fIovector\fP Points to a vector of ints for result offsets \fIovecsize\fP Number of elements in the vector (a multiple of 3) .sp -The options are: +The units for \fIlength\fP and \fIstartoffset\fP are bytes for +\fBpcre_exec()\fP, 16-bit data items for \fBpcre16_exec()\fP, and 32-bit items +for \fBpcre32_exec()\fP. The options are: .sp PCRE_ANCHORED Match only at the first position PCRE_BSR_ANYCRLF \eR matches only CR, LF, or CRLF diff --git a/tools/pcre/doc/pcre_fullinfo.3 b/tools/pcre/doc/pcre_fullinfo.3 index ad640fc6..01e2e928 100644 --- a/tools/pcre/doc/pcre_fullinfo.3 +++ b/tools/pcre/doc/pcre_fullinfo.3 @@ -6,18 +6,16 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .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 \fIwhat\fP, void *\fIwhere\fP);" +.sp .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 \fIwhat\fP, void *\fIwhere\fP);" +.sp .B int pcre32_fullinfo(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," -.ti +5n -.B int \fIwhat\fP, void *\fIwhere\fP); +.B " int \fIwhat\fP, void *\fIwhere\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_get_named_substring.3 b/tools/pcre/doc/pcre_get_named_substring.3 index f81a243c..84d4ee7d 100644 --- a/tools/pcre/doc/pcre_get_named_substring.3 +++ b/tools/pcre/doc/pcre_get_named_substring.3 @@ -6,30 +6,22 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B int pcre_get_named_substring(const pcre *\fIcode\fP, -.ti +5n -.B const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, const char *\fIstringname\fP, -.ti +5n -.B const char **\fIstringptr\fP); -.PP +.B " const char *\fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, const char *\fIstringname\fP," +.B " const char **\fIstringptr\fP);" +.sp .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 " PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP," +.B " PCRE_SPTR16 *\fIstringptr\fP);" +.sp .B int pcre32_get_named_substring(const pcre32 *\fIcode\fP, -.ti +5n -.B PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP, -.ti +5n -.B PCRE_SPTR32 *\fIstringptr\fP); +.B " PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, PCRE_SPTR32 \fIstringname\fP," +.B " PCRE_SPTR32 *\fIstringptr\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_get_stringnumber.3 b/tools/pcre/doc/pcre_get_stringnumber.3 index 7def00ba..9fc5291d 100644 --- a/tools/pcre/doc/pcre_get_stringnumber.3 +++ b/tools/pcre/doc/pcre_get_stringnumber.3 @@ -6,18 +6,16 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B int pcre_get_stringnumber(const pcre *\fIcode\fP, -.ti +5n -.B const char *\fIname\fP); -.PP +.B " const char *\fIname\fP);" +.sp .B int pcre16_get_stringnumber(const pcre16 *\fIcode\fP, -.ti +5n -.B PCRE_SPTR16 \fIname\fP); -.PP +.B " PCRE_SPTR16 \fIname\fP);" +.sp .B int pcre32_get_stringnumber(const pcre32 *\fIcode\fP, -.ti +5n -.B PCRE_SPTR32 \fIname\fP); +.B " PCRE_SPTR32 \fIname\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_get_stringtable_entries.3 b/tools/pcre/doc/pcre_get_stringtable_entries.3 index 39178165..5c58c90c 100644 --- a/tools/pcre/doc/pcre_get_stringtable_entries.3 +++ b/tools/pcre/doc/pcre_get_stringtable_entries.3 @@ -6,18 +6,16 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .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 " const char *\fIname\fP, char **\fIfirst\fP, char **\fIlast\fP);" +.sp .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 " PCRE_SPTR16 \fIname\fP, PCRE_UCHAR16 **\fIfirst\fP, PCRE_UCHAR16 **\fIlast\fP);" +.sp .B int pcre32_get_stringtable_entries(const pcre32 *\fIcode\fP, -.ti +5n -.B PCRE_SPTR32 \fIname\fP, PCRE_UCHAR32 **\fIfirst\fP, PCRE_UCHAR32 **\fIlast\fP); +.B " PCRE_SPTR32 \fIname\fP, PCRE_UCHAR32 **\fIfirst\fP, PCRE_UCHAR32 **\fIlast\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_get_substring.3 b/tools/pcre/doc/pcre_get_substring.3 index d5bc60c4..1e62b2c0 100644 --- a/tools/pcre/doc/pcre_get_substring.3 +++ b/tools/pcre/doc/pcre_get_substring.3 @@ -6,24 +6,19 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B int pcre_get_substring(const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, int \fIstringnumber\fP, -.ti +5n -.B const char **\fIstringptr\fP); -.PP +.B " int \fIstringcount\fP, int \fIstringnumber\fP," +.B " const char **\fIstringptr\fP);" +.sp .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 \fIstringcount\fP, int \fIstringnumber\fP," +.B " PCRE_SPTR16 *\fIstringptr\fP);" +.sp .B int pcre32_get_substring(PCRE_SPTR32 \fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, int \fIstringnumber\fP, -.ti +5n -.B PCRE_SPTR32 *\fIstringptr\fP); +.B " int \fIstringcount\fP, int \fIstringnumber\fP," +.B " PCRE_SPTR32 *\fIstringptr\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_get_substring_list.3 b/tools/pcre/doc/pcre_get_substring_list.3 index a1a57496..511a4a39 100644 --- a/tools/pcre/doc/pcre_get_substring_list.3 +++ b/tools/pcre/doc/pcre_get_substring_list.3 @@ -6,18 +6,16 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .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 *\fIovector\fP, int \fIstringcount\fP, const char ***\fIlistptr\fP);" +.sp .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 " int *\fIovector\fP, int \fIstringcount\fP, PCRE_SPTR16 **\fIlistptr\fP);" +.sp .B int pcre32_get_substring_list(PCRE_SPTR32 \fIsubject\fP, -.ti +5n -.B int *\fIovector\fP, int \fIstringcount\fP, "PCRE_SPTR32 **\fIlistptr\fP);" +.B " int *\fIovector\fP, int \fIstringcount\fP, PCRE_SPTR32 **\fIlistptr\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_jit_exec.3 b/tools/pcre/doc/pcre_jit_exec.3 index 8b9d05bf..ba851681 100644 --- a/tools/pcre/doc/pcre_jit_exec.3 +++ b/tools/pcre/doc/pcre_jit_exec.3 @@ -6,30 +6,22 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B int pcre_jit_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," -.ti +5n -.B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, -.ti +5n -.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, -.ti +5n -.B pcre_jit_stack *\fIjstack\fP); -.PP +.B " const char *\fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " pcre_jit_stack *\fIjstack\fP);" +.sp .B int pcre16_jit_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 pcre_jit_stack *\fIjstack\fP); -.PP +.B " PCRE_SPTR16 \fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " pcre_jit_stack *\fIjstack\fP);" +.sp .B int pcre32_jit_exec(const pcre32 *\fIcode\fP, "const pcre32_extra *\fIextra\fP," -.ti +5n -.B "PCRE_SPTR32 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, -.ti +5n -.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, -.ti +5n -.B pcre_jit_stack *\fIjstack\fP); +.B " PCRE_SPTR32 \fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " pcre_jit_stack *\fIjstack\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_jit_stack_alloc.3 b/tools/pcre/doc/pcre_jit_stack_alloc.3 index 5d2a1178..11c97a0f 100644 --- a/tools/pcre/doc/pcre_jit_stack_alloc.3 +++ b/tools/pcre/doc/pcre_jit_stack_alloc.3 @@ -6,18 +6,16 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B pcre_jit_stack *pcre_jit_stack_alloc(int \fIstartsize\fP, -.ti +5n -.B int \fImaxsize\fP); -.PP +.B " int \fImaxsize\fP);" +.sp .B pcre16_jit_stack *pcre16_jit_stack_alloc(int \fIstartsize\fP, -.ti +5n -.B int \fImaxsize\fP); -.PP +.B " int \fImaxsize\fP);" +.sp .B pcre32_jit_stack *pcre32_jit_stack_alloc(int \fIstartsize\fP, -.ti +5n -.B int \fImaxsize\fP); +.B " int \fImaxsize\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_pattern_to_host_byte_order.3 b/tools/pcre/doc/pcre_pattern_to_host_byte_order.3 index 4c306eef..b0c41c38 100644 --- a/tools/pcre/doc/pcre_pattern_to_host_byte_order.3 +++ b/tools/pcre/doc/pcre_pattern_to_host_byte_order.3 @@ -6,18 +6,16 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .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 " pcre_extra *\fIextra\fP, const unsigned char *\fItables\fP);" +.sp .B int pcre16_pattern_to_host_byte_order(pcre16 *\fIcode\fP, -.ti +5n -.B pcre16_extra *\fIextra\fP, const unsigned char *\fItables\fP); -.PP +.B " pcre16_extra *\fIextra\fP, const unsigned char *\fItables\fP);" +.sp .B int pcre32_pattern_to_host_byte_order(pcre32 *\fIcode\fP, -.ti +5n -.B pcre32_extra *\fIextra\fP, const unsigned char *\fItables\fP); +.B " pcre32_extra *\fIextra\fP, const unsigned char *\fItables\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_study.3 b/tools/pcre/doc/pcre_study.3 index 1f2b465a..1200e0a6 100644 --- a/tools/pcre/doc/pcre_study.3 +++ b/tools/pcre/doc/pcre_study.3 @@ -6,18 +6,16 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP, -.ti +5n -.B const char **\fIerrptr\fP); -.PP +.B " const char **\fIerrptr\fP);" +.sp .B pcre16_extra *pcre16_study(const pcre16 *\fIcode\fP, int \fIoptions\fP, -.ti +5n -.B const char **\fIerrptr\fP); -.PP +.B " const char **\fIerrptr\fP);" +.sp .B pcre32_extra *pcre32_study(const pcre32 *\fIcode\fP, int \fIoptions\fP, -.ti +5n -.B const char **\fIerrptr\fP); +.B " const char **\fIerrptr\fP);" +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcre_utf16_to_host_byte_order.3 b/tools/pcre/doc/pcre_utf16_to_host_byte_order.3 index 8f0d2d4e..1851b619 100644 --- a/tools/pcre/doc/pcre_utf16_to_host_byte_order.3 +++ b/tools/pcre/doc/pcre_utf16_to_host_byte_order.3 @@ -6,12 +6,11 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .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); +.B " PCRE_SPTR16 \fIinput\fP, int \fIlength\fP, int *\fIhost_byte_order\fP," +.B " int \fIkeep_boms\fP);" +.fi . . .SH DESCRIPTION diff --git a/tools/pcre/doc/pcre_utf32_to_host_byte_order.3 b/tools/pcre/doc/pcre_utf32_to_host_byte_order.3 index fa4c1796..a415dcf5 100644 --- a/tools/pcre/doc/pcre_utf32_to_host_byte_order.3 +++ b/tools/pcre/doc/pcre_utf32_to_host_byte_order.3 @@ -6,12 +6,11 @@ PCRE - Perl-compatible regular expressions .sp .B #include .PP -.SM +.nf .B int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *\fIoutput\fP, -.ti +5n -.B PCRE_SPTR32 \fIinput\fP, int \fIlength\fP, int *\fIhost_byte_order\fP, -.ti +5n -.B int \fIkeep_boms\fP); +.B " PCRE_SPTR32 \fIinput\fP, int \fIlength\fP, int *\fIhost_byte_order\fP," +.B " int \fIkeep_boms\fP);" +.fi . . .SH DESCRIPTION diff --git a/tools/pcre/doc/pcreapi.3 b/tools/pcre/doc/pcreapi.3 index 0eebf947..ab3eaa0b 100644 --- a/tools/pcre/doc/pcreapi.3 +++ b/tools/pcre/doc/pcreapi.3 @@ -1,4 +1,4 @@ -.TH PCREAPI 3 "08 November 2012" "PCRE 8.32" +.TH PCREAPI 3 "09 February 2014" "PCRE 8.35" .SH NAME PCRE - Perl-compatible regular expressions .sp @@ -8,138 +8,117 @@ PCRE - Perl-compatible regular expressions .SH "PCRE NATIVE API BASIC FUNCTIONS" .rs .sp -.SM +.nf .B pcre *pcre_compile(const char *\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 " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.sp .B pcre *pcre_compile2(const char *\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 " int *\fIerrorcodeptr\fP," +.B " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.sp .B pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP, -.ti +5n -.B const char **\fIerrptr\fP); -.PP +.B " const char **\fIerrptr\fP);" +.sp .B void pcre_free_study(pcre_extra *\fIextra\fP); -.PP +.sp .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, -.ti +5n -.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); -.PP +.B " const char *\fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP);" +.sp .B int pcre_dfa_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," -.ti +5n -.B "const char *\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); +.B " const char *\fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " int *\fIworkspace\fP, int \fIwscount\fP);" +.fi . . .SH "PCRE NATIVE API STRING EXTRACTION FUNCTIONS" .rs .sp +.nf .B int pcre_copy_named_substring(const pcre *\fIcode\fP, -.ti +5n -.B const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, const char *\fIstringname\fP, -.ti +5n -.B char *\fIbuffer\fP, int \fIbuffersize\fP); -.PP +.B " const char *\fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, const char *\fIstringname\fP," +.B " char *\fIbuffer\fP, int \fIbuffersize\fP);" +.sp .B int pcre_copy_substring(const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP, -.ti +5n -.B int \fIbuffersize\fP); -.PP +.B " int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP," +.B " int \fIbuffersize\fP);" +.sp .B int pcre_get_named_substring(const pcre *\fIcode\fP, -.ti +5n -.B const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, const char *\fIstringname\fP, -.ti +5n -.B const char **\fIstringptr\fP); -.PP +.B " const char *\fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, const char *\fIstringname\fP," +.B " const char **\fIstringptr\fP);" +.sp .B int pcre_get_stringnumber(const pcre *\fIcode\fP, -.ti +5n -.B const char *\fIname\fP); -.PP +.B " const char *\fIname\fP);" +.sp .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 " const char *\fIname\fP, char **\fIfirst\fP, char **\fIlast\fP);" +.sp .B int pcre_get_substring(const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, int \fIstringnumber\fP, -.ti +5n -.B const char **\fIstringptr\fP); -.PP +.B " int \fIstringcount\fP, int \fIstringnumber\fP," +.B " const char **\fIstringptr\fP);" +.sp .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 *\fIovector\fP, int \fIstringcount\fP, const char ***\fIlistptr\fP);" +.sp .B void pcre_free_substring(const char *\fIstringptr\fP); -.PP +.sp .B void pcre_free_substring_list(const char **\fIstringptr\fP); +.fi . . .SH "PCRE NATIVE API AUXILIARY FUNCTIONS" .rs .sp +.nf .B int pcre_jit_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," -.ti +5n -.B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, -.ti +5n -.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, -.ti +5n -.B pcre_jit_stack *\fIjstack\fP); -.PP +.B " const char *\fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " pcre_jit_stack *\fIjstack\fP);" +.sp .B pcre_jit_stack *pcre_jit_stack_alloc(int \fIstartsize\fP, int \fImaxsize\fP); -.PP +.sp .B void pcre_jit_stack_free(pcre_jit_stack *\fIstack\fP); -.PP +.sp .B void pcre_assign_jit_stack(pcre_extra *\fIextra\fP, -.ti +5n -.B pcre_jit_callback \fIcallback\fP, void *\fIdata\fP); -.PP +.B " pcre_jit_callback \fIcallback\fP, void *\fIdata\fP);" +.sp .B const unsigned char *pcre_maketables(void); -.PP +.sp .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 \fIwhat\fP, void *\fIwhere\fP);" +.sp .B int pcre_refcount(pcre *\fIcode\fP, int \fIadjust\fP); -.PP +.sp .B int pcre_config(int \fIwhat\fP, void *\fIwhere\fP); -.PP +.sp .B const char *pcre_version(void); -.PP +.sp .B int pcre_pattern_to_host_byte_order(pcre *\fIcode\fP, -.ti +5n -.B pcre_extra *\fIextra\fP, const unsigned char *\fItables\fP); +.B " pcre_extra *\fIextra\fP, const unsigned char *\fItables\fP);" +.fi . . .SH "PCRE NATIVE API INDIRECTED FUNCTIONS" .rs .sp +.nf .B void *(*pcre_malloc)(size_t); -.PP +.sp .B void (*pcre_free)(void *); -.PP +.sp .B void *(*pcre_stack_malloc)(size_t); -.PP +.sp .B void (*pcre_stack_free)(void *); -.PP +.sp .B int (*pcre_callout)(pcre_callout_block *); +.sp +.B int (*pcre_stack_guard)(void); +.fi . . .SH "PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES" @@ -161,10 +140,10 @@ by UTF16 or UTF32, respectively. This facility is in fact just cosmetic; the 16-bit and 32-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, or 32-bit data -quantities and UTF-32 when using the 32-bit library, unless specified -otherwise. More details of the specific differences for the 16-bit and 32-bit -libraries are given in the +16-bit data units and UTF-16 when using the 16-bit library, or 32-bit data +units and UTF-32 when using the 32-bit library, unless specified otherwise. +More details of the specific differences for the 16-bit and 32-bit libraries +are given in the .\" HREF \fBpcre16\fP .\" @@ -309,6 +288,14 @@ points during a matching operation. Details are given in the \fBpcrecallout\fP .\" documentation. +.P +The global variable \fBpcre_stack_guard\fP initially contains NULL. It can be +set by the caller to a function that is called by PCRE whenever it starts +to compile a parenthesized part of a pattern. When parentheses are nested, PCRE +uses recursive function calls, which use up the system stack. This function is +provided so that applications with restricted stacks can force a compilation +error if the stack runs out. The function should return zero if all is well, or +non-zero to force an error. . . .\" HTML @@ -360,7 +347,8 @@ controlled in a similar way, but by separate options. The PCRE functions can be used in multi-threading applications, with the proviso that the memory management functions pointed to by \fBpcre_malloc\fP, \fBpcre_free\fP, \fBpcre_stack_malloc\fP, and \fBpcre_stack_free\fP, and the -callout function pointed to by \fBpcre_callout\fP, are shared by all threads. +callout and stack-checking functions pointed to by \fBpcre_callout\fP and +\fBpcre_stack_guard\fP, are shared by all threads. .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. @@ -482,6 +470,16 @@ the \fBpcreposix\fP .\" documentation. +.sp + PCRE_CONFIG_PARENS_LIMIT +.sp +The output is a long integer that gives the maximum depth of nesting of +parentheses (of any kind) in a pattern. This limit is imposed to cap the amount +of system stack used when a pattern is compiled. It is specified when PCRE is +built; the default is 250. This limit does not take into account the stack that +may already be used by the calling application. For finer control over +compilation stack usage, you can set a pointer to an external checking function +in \fBpcre_stack_guard\fP. .sp PCRE_CONFIG_MATCH_LIMIT .sp @@ -509,19 +507,16 @@ avoiding the use of the stack. .SH "COMPILING A PATTERN" .rs .sp +.nf .B pcre *pcre_compile(const char *\fIpattern\fP, int \fIoptions\fP, -.ti +5n -.B const char **\fIerrptr\fP, int *\fIerroffset\fP, -.ti +5n -.B const unsigned char *\fItableptr\fP); +.B " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" .sp .B pcre *pcre_compile2(const char *\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); +.B " int *\fIerrorcodeptr\fP," +.B " const char **\fIerrptr\fP, int *\fIerroffset\fP," +.B " const unsigned char *\fItableptr\fP);" +.fi .P Either of the functions \fBpcre_compile()\fP or \fBpcre_compile2()\fP can be called to compile a pattern into an internal form. The only difference between @@ -562,15 +557,15 @@ 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. 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. +data unit 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 or UTF-16 string, +the offset is that of the first data unit 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. +offset is in data units, not characters, even in a UTF mode. It may sometimes +point into the middle of a UTF-8 or UTF-16 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 @@ -581,8 +576,9 @@ If the final argument, \fItableptr\fP, is NULL, PCRE uses a default set of character tables that are built when PCRE is compiled, using the default C locale. Otherwise, \fItableptr\fP must be an address that is the result of a call to \fBpcre_maketables()\fP. This value is stored with the compiled -pattern, and used again by \fBpcre_exec()\fP, unless another table pointer is -passed to it. For more discussion, see the section on locale support below. +pattern, and used again by \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP when the +pattern is matched. For more discussion, see the section on locale support +below. .P This code fragment shows a typical straightforward call to \fBpcre_compile()\fP: .sp @@ -670,12 +666,22 @@ documentation. .sp PCRE_EXTENDED .sp -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. +If this bit is set, most white space characters in the pattern are totally +ignored except when escaped or inside a character class. However, white space +is not allowed within sequences such as (?> that introduce various +parenthesized subpatterns, nor within a numerical quantifier such as {1,3}. +However, ignorable white space is permitted between an item and a following +quantifier and between a quantifier and a following + that indicates +possessiveness. +.P +White space did not used to include the VT character (code 11), because Perl +did not treat this character as white space. However, Perl changed at release +5.18, so PCRE followed at release 8.34, and VT is now treated as white space. +.P +PCRE_EXTENDED also causes characters between an unescaped # outside a character +class and the next newline, inclusive, to be ignored. PCRE_EXTENDED is +equivalent to Perl's /x option, and it can be changed within a pattern by a +(?x) option setting. .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 @@ -741,12 +747,14 @@ binary zero character followed by z). .sp PCRE_MULTILINE .sp -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. +By default, for the purposes of matching "start of line" and "end of line", +PCRE treats the subject string as consisting of a single line of characters, +even if it actually contains newlines. The "start of line" metacharacter (^) +matches only at the start of the string, and the "end of line" metacharacter +($) matches only at the end of the string, or before a terminating newline +(except when PCRE_DOLLAR_ENDONLY is set). Note, however, that unless +PCRE_DOTALL is set, the "any character" metacharacter (.) does not match at a +newline. This behaviour (for ^, $, and dot) is the same as Perl. .P 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 @@ -754,6 +762,15 @@ 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 newlines in a subject string, or no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no effect. +.sp + PCRE_NEVER_UTF +.sp +This option locks out interpretation of the pattern as UTF-8 (or UTF-16 or +UTF-32 in the 16-bit and 32-bit libraries). In particular, it prevents the +creator of the pattern from switching to UTF interpretation by starting the +pattern with (*UTF). This may be useful in applications that process patterns +from external sources. The combination of PCRE_UTF8 and PCRE_NEVER_UTF also +causes an error. .sp PCRE_NEWLINE_CR PCRE_NEWLINE_LF @@ -810,12 +827,23 @@ 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. .sp - NO_START_OPTIMIZE + PCRE_NO_AUTO_POSSESS +.sp +If this option is set, it disables "auto-possessification". This is an +optimization that, for example, turns a+b into a++b in order to avoid +backtracks into a+ that can never be successful. However, if callouts are in +use, auto-possessification means that some of them are never taken. You can set +this option if you want the matching functions to do a full unoptimized search +and run all the callouts, but it is mainly provided for testing purposes. +.sp + PCRE_NO_START_OPTIMIZE .sp This is an option that acts at matching time; that is, it is really an option for \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. If it is set at compile time, -it is remembered with the compiled pattern and assumed at matching time. For -details see the discussion of PCRE_NO_START_OPTIMIZE +it is remembered with the compiled pattern and assumed at matching time. This +is necessary if you want to use JIT execution, because the JIT compiler needs +to know whether or not this option is set. For details see the discussion of +PCRE_NO_START_OPTIMIZE .\" HTML .\" below. @@ -873,10 +901,10 @@ 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 only. If the same string is being matched -many times, the option can be safely set for the second and subsequent +undefined. It may cause your program to crash or loop. 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 only. If the same string is being +matched many times, the option can be safely set for the second and subsequent matchings to improve performance. . . @@ -923,7 +951,7 @@ have fallen out of use. To avoid confusion, they have not been re-used. 31 POSIX collating elements are not supported 32 this version of PCRE is compiled without UTF support 33 [this code is not in use] - 34 character value in \ex{...} sequence is too large + 34 character value in \ex{} or \eo{} is too large 35 invalid condition (?(0) 36 \eC not allowed in lookbehind assertion 37 PCRE does not support \eL, \el, \eN{name}, \eU, or \eu @@ -951,7 +979,7 @@ have fallen out of use. To avoid confusion, they have not been re-used. name/number or by a plain number 58 a numbered reference must not be zero 59 an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) - 60 (*VERB) not recognized + 60 (*VERB) not recognized or malformed 61 number is too big 62 subpattern name expected 63 digit expected after (?+ @@ -971,6 +999,14 @@ have fallen out of use. To avoid confusion, they have not been re-used. 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) 76 character value in \eu.... sequence is too large 77 invalid UTF-32 string (specifically UTF-32) + 78 setting UTF is disabled by the application + 79 non-hex character in \ex{} (closing brace missing?) + 80 non-octal character in \eo{} (closing brace missing?) + 81 missing opening brace after \eo + 82 parentheses are too deeply nested + 83 invalid range in character class + 84 group name must start with a non-digit + 85 parentheses are too deeply nested (stack check) .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. @@ -980,9 +1016,10 @@ be used if the limits were changed when PCRE was built. .SH "STUDYING A PATTERN" .rs .sp -.B pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP -.ti +5n -.B const char **\fIerrptr\fP); +.nf +.B pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP, +.B " const char **\fIerrptr\fP);" +.fi .PP If a compiled pattern is going to be used several times, it is worth spending more time analyzing it in order to speed up the time taken for matching. The @@ -1081,11 +1118,17 @@ In 32-bit mode, the bitmap is used for 32-bit values less than 256.) .P 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 +The optimizations can be disabled by setting the PCRE_NO_START_OPTIMIZE option. +You might want to do this if your pattern contains callouts or (*MARK) and you +want to make use of these facilities in cases where matching fails. +.P +PCRE_NO_START_OPTIMIZE can be specified at either compile time or execution +time. However, if PCRE_NO_START_OPTIMIZE is passed to \fBpcre_exec()\fP, (that +is, after any JIT compilation has happened) JIT execution is disabled. For JIT +execution to work with PCRE_NO_START_OPTIMIZE, the option must be set at +compile time. +.P +There is a longer discussion of PCRE_NO_START_OPTIMIZE .\" HTML .\" below. @@ -1098,15 +1141,17 @@ below. .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. +code point. When running in UTF-8 mode, or in the 16- or 32-bit libraries, this +applies only to characters with code points less than 256. By default, +higher-valued code points never match escapes such as \ew or \ed. However, if +PCRE is built with Unicode property support, all characters can be tested with +\ep and \eP, or, alternatively, the PCRE_UCP option can be set when a pattern +is compiled; this causes \ew and friends to use Unicode property support +instead of the built-in tables. +.P +The use of locales with Unicode is discouraged. If you are handling characters +with code points greater than 128, you should either use Unicode support, or +use locales, but not try to mix the two. .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. @@ -1121,10 +1166,10 @@ for this locale support is expected to die away. .P External tables are built by calling the \fBpcre_maketables()\fP function, which has no arguments, in the relevant locale. The result can then be passed -to \fBpcre_compile()\fP or \fBpcre_exec()\fP 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: +to \fBpcre_compile()\fP 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: .sp setlocale(LC_CTYPE, "fr_FR"); tables = pcre_maketables(); @@ -1140,24 +1185,29 @@ needed. .P The pointer that is passed to \fBpcre_compile()\fP is saved with the compiled pattern, and the same tables are used via this pointer by \fBpcre_study()\fP -and normally also by \fBpcre_exec()\fP. Thus, by default, for any single +and also by \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP. Thus, for any single pattern, compilation, studying and matching all happen in the same locale, but -different patterns can be compiled in different locales. +different patterns can be processed in different locales. .P It is possible to pass a table pointer or NULL (indicating the use of the -internal tables) to \fBpcre_exec()\fP. 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. +internal tables) to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP (see the +discussion below in the section on matching a pattern). This facility is +provided for use with pre-compiled patterns that have been saved and reloaded. +Character tables are not saved with patterns, so if a non-standard table was +used at compile time, it must be provided again when the reloaded pattern is +matched. Attempting to use this facility to match a pattern in a different +locale from the one in which it was compiled is likely to lead to anomalous +(usually incorrect) results. . . .\" HTML .SH "INFORMATION ABOUT A PATTERN" .rs .sp +.nf .B int pcre_fullinfo(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," -.ti +5n -.B int \fIwhat\fP, void *\fIwhere\fP); +.B " int \fIwhat\fP, void *\fIwhere\fP);" +.fi .PP The \fBpcre_fullinfo()\fP function returns information about a compiled pattern. It replaces the \fBpcre_info()\fP function, which was removed from the @@ -1176,6 +1226,7 @@ the following negative numbers: PCRE_ERROR_BADENDIANNESS the pattern was compiled with different endianness PCRE_ERROR_BADOPTION the value of \fIwhat\fP was invalid + PCRE_ERROR_UNSET the requested field is not set .sp The "magic number" is placed at the start of each compiled pattern as an simple check against passing an arbitrary memory pointer. The endianness error can @@ -1213,12 +1264,15 @@ information call is provided for internal use by the \fBpcre_study()\fP function. External callers can cause PCRE to use its internal tables by passing a NULL table pointer. .sp - PCRE_INFO_FIRSTBYTE + PCRE_INFO_FIRSTBYTE (deprecated) .sp 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. +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. Negative values are used for special cases. However, this means that +when the 32-bit library is in non-UTF-32 mode, the full 32-bit range of +characters cannot be returned. For this reason, this value is deprecated; use +PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER instead. .P 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 @@ -1236,11 +1290,38 @@ starts with "^", or -1 is returned, indicating that the pattern matches only at the start of a subject string or after any newline within the string. Otherwise -2 is returned. For anchored patterns, -2 is returned. +.sp + PCRE_INFO_FIRSTCHARACTER +.sp +Return the value of the first data unit (non-UTF character) of any matched +string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS returns 1; +otherwise return 0. The fourth argument should point to an \fBuint_t\fP +variable. .P -Since for the 32-bit library using the non-UTF-32 mode, this function is unable -to return the full 32-bit range of the character, this value is deprecated; -instead the PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER values -should be used. +In the 8-bit library, the value is always less than 256. In the 16-bit library +the value can be up to 0xffff. In the 32-bit library in UTF-32 mode the value +can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode. +.sp + PCRE_INFO_FIRSTCHARACTERFLAGS +.sp +Return information about the first data unit of any matched string, for a +non-anchored pattern. The fourth argument should point to an \fBint\fP +variable. +.P +If there is a fixed first value, for example, the letter "c" from a pattern +such as (cat|cow|coyote), 1 is returned, and the character value can be +retrieved using PCRE_INFO_FIRSTCHARACTER. If there is no fixed first value, and +if either +.sp +(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch +starts with "^", or +.sp +(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set +(if it were set, the pattern would be anchored), +.sp +2 is returned, indicating that the pattern matches only at the start of a +subject string or after any newline within the string. Otherwise 0 is +returned. For anchored patterns, 0 is returned. .sp PCRE_INFO_FIRSTTABLE .sp @@ -1290,26 +1371,43 @@ only if it follows something of variable length. For example, for the pattern is -1. .P Since for the 32-bit library using the non-UTF-32 mode, this function is unable -to return the full 32-bit range of the character, this value is deprecated; +to return the full 32-bit range of characters, this value is deprecated; instead the PCRE_INFO_REQUIREDCHARFLAGS and PCRE_INFO_REQUIREDCHAR values should be used. +.sp + PCRE_INFO_MATCH_EMPTY +.sp +Return 1 if the pattern can match an empty string, otherwise 0. The fourth +argument should point to an \fBint\fP variable. +.sp + PCRE_INFO_MATCHLIMIT +.sp +If the pattern set a match limit by including an item of the form +(*LIMIT_MATCH=nnnn) at the start, the value is returned. The fourth argument +should point to an unsigned 32-bit integer. If no such value has been set, the +call to \fBpcre_fullinfo()\fP returns the error PCRE_ERROR_UNSET. .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. +Return the number of characters (NB not data units) in the longest lookbehind +assertion in the pattern. This information is useful when doing multi-segment +matching using the partial matching facilities. Note that the simple assertions +\eb and \eB require a one-character lookbehind. \eA also registers a +one-character lookbehind, though it does not actually inspect the previous +character. This is to ensure that at least one character from the old segment +is retained when a new segment is processed. Otherwise, if there are no +lookbehinds in the pattern, \eA might match incorrectly at the start of a new +segment. .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, 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. +value is a number of characters, which in UTF mode may be different from the +number of data units. The fourth argument should point to an \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. .sp PCRE_INFO_NAMECOUNT PCRE_INFO_NAMEENTRYSIZE @@ -1332,13 +1430,13 @@ length of the longest name. PCRE_INFO_NAMETABLE returns a pointer to the first 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. -In the 32-bit library, the pointer points to 32-bit data units, the first of -which contains the parenthesis number. The rest -of the entry is the corresponding name, zero terminated. +16-bit data units, the first of which contains the parenthesis number. In the +32-bit library, the pointer points to 32-bit data units, the first of which +contains the parenthesis number. The rest of the entry is the corresponding +name, zero terminated. .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 +The names are in alphabetical order. If (?| is used to create multiple groups +with the same number, as described in the .\" HTML .\" section on duplicate subpattern numbers @@ -1347,11 +1445,13 @@ in the .\" HREF \fBpcrepattern\fP .\" -page. Duplicate names for subpatterns with different numbers are permitted only -if PCRE_DUPNAMES is set. In all cases of duplicate names, they appear in the -table in the order in which they were found in the pattern. In the absence of -(?| this is the order of increasing number; when (?| is used this is not -necessarily the case because later subpatterns may have lower numbers. +page, the groups may be given the same name, but there is only one entry in the +table. Different names for groups of the same number are not permitted. +Duplicate names for subpatterns with different numbers are permitted, +but only if PCRE_DUPNAMES is set. They appear in the table in the order in +which they were found in the pattern. In the absence of (?| this is the order +of increasing number; when (?| is used this is not necessarily the case because +later subpatterns may have lower numbers. .P As a simple example of the name/number table, consider the following pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white @@ -1407,10 +1507,17 @@ alternatives begin with one of the following: .sp For such patterns, the PCRE_ANCHORED bit is set in the options returned by \fBpcre_fullinfo()\fP. +.sp + PCRE_INFO_RECURSIONLIMIT +.sp +If the pattern set a recursion limit by including an item of the form +(*LIMIT_RECURSION=nnnn) at the start, the value is returned. The fourth +argument should point to an unsigned 32-bit integer. If no such value has been +set, the call to \fBpcre_fullinfo()\fP returns the error PCRE_ERROR_UNSET. .sp PCRE_INFO_SIZE .sp -Return the size of the compiled pattern in bytes (for both libraries). The +Return the size of the compiled pattern in bytes (for all three 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 @@ -1421,11 +1528,12 @@ does not alter the value returned by this option. .sp PCRE_INFO_STUDYSIZE .sp -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. The \fIstudy_data\fP field is set by \fBpcre_study()\fP -to record information that will speed up matching (see the section entitled +Return the size in bytes (for all three libraries) 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. 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" @@ -1436,50 +1544,6 @@ is made available via this option so that it can be saved and restored (see the \fBpcreprecompile\fP .\" documentation for details). -.sp - PCRE_INFO_FIRSTCHARACTERFLAGS -.sp -Return information about the first data unit of any matched string, for a -non-anchored pattern. The fourth argument should point to an \fBint\fP -variable. -.P -If there is a fixed first value, for example, the letter "c" from a pattern -such as (cat|cow|coyote), 1 is returned, and the character value can be -retrieved using PCRE_INFO_FIRSTCHARACTER. -.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 -.sp -(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set -(if it were set, the pattern would be anchored), -.sp -2 is returned, indicating that the pattern matches only at the start of a -subject string or after any newline within the string. Otherwise 0 is -returned. For anchored patterns, 0 is returned. -.sp - PCRE_INFO_FIRSTCHARACTER -.sp -Return the fixed first character value, if PCRE_INFO_FIRSTCHARACTERFLAGS -returned 1; otherwise returns 0. The fourth argument should point to an -\fBuint_t\fP variable. -.P -In the 8-bit library, the value is always less than 256. In the 16-bit library -the value can be up to 0xffff. In the 32-bit library in UTF-32 mode the value -can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode. -.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 -.sp -(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set -(if it were set, the pattern would be anchored), -.sp --1 is returned, indicating that the pattern matches only at the start of a -subject string or after any newline within the string. Otherwise -2 is -returned. For anchored patterns, -2 is returned. .sp PCRE_INFO_REQUIREDCHARFLAGS .sp @@ -1527,11 +1591,11 @@ is different. (This seems a highly unlikely scenario.) .SH "MATCHING A PATTERN: THE TRADITIONAL FUNCTION" .rs .sp +.nf .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, -.ti +5n -.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); +.B " const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP);" +.fi .P 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 @@ -1641,6 +1705,15 @@ block in which \fImatch_limit\fP is set, and PCRE_EXTRA_MATCH_LIMIT is set in the \fIflags\fP field. If the limit is exceeded, \fBpcre_exec()\fP returns PCRE_ERROR_MATCHLIMIT. .P +A value for the match limit may also be supplied by an item at the start of a +pattern of the form +.sp + (*LIMIT_MATCH=d) +.sp +where d is a decimal number. However, such a setting is ignored unless d is +less than the limit set by the caller of \fBpcre_exec()\fP or, if no such limit +is set, less than the default. +.P The \fImatch_limit_recursion\fP field is similar to \fImatch_limit\fP, but instead of limiting the total number of times that \fBmatch()\fP is called, it limits the depth of recursion. The recursion depth is a smaller number than the @@ -1659,6 +1732,15 @@ with a \fBpcre_extra\fP block in which \fImatch_limit_recursion\fP is set, and PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the \fIflags\fP field. If the limit is exceeded, \fBpcre_exec()\fP returns PCRE_ERROR_RECURSIONLIMIT. .P +A value for the recursion limit may also be supplied by an item at the start of +a pattern of the form +.sp + (*LIMIT_RECURSION=d) +.sp +where d is a decimal number. However, such a setting is ignored unless d is +less than the limit set by the caller of \fBpcre_exec()\fP or, if no such limit +is set, less than the default. +.P The \fIcallout_data\fP field is used in conjunction with the "callout" feature, and is described in the .\" HREF @@ -1666,19 +1748,23 @@ and is described in the .\" documentation. .P -The \fItables\fP field is used to pass a character tables pointer to -\fBpcre_exec()\fP; 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 \fBpcre_compile()\fP via its \fItableptr\fP argument. -If NULL is passed to \fBpcre_exec()\fP 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 \fBpcre_exec()\fP is -called. See the +The \fItables\fP field is provided for use with patterns that have been +pre-compiled using custom character tables, saved to disc or elsewhere, and +then reloaded, because the tables that were used to compile a pattern are not +saved with it. See the .\" HREF \fBpcreprecompile\fP .\" -documentation for a discussion of saving compiled patterns for later use. +documentation for a discussion of saving compiled patterns for later use. If +NULL is passed using this mechanism, it forces PCRE's internal tables to be +used. +.P +\fBWarning:\fP The tables that \fBpcre_exec()\fP uses must be the same as those +that were used when the pattern was compiled. If this is not the case, the +behaviour of \fBpcre_exec()\fP is undefined. Therefore, when a pattern is +compiled and matched in the same process, this field should never be set. In +this (the most common) case, the correct table pointer is automatically passed +with the compiled pattern from \fBpcre_compile()\fP to \fBpcre_exec()\fP. .P If PCRE_EXTRA_MARK is set in the \fIflags\fP field, the \fImark\fP field must be set to point to a suitable variable. If the pattern contains any @@ -1824,18 +1910,19 @@ unanchored match must start with a specific character, it searches the subject for that character, and fails immediately if it cannot find it, without actually running the main matching function. This means that a special item such as (*COMMIT) at the start of a pattern is not considered until after a -suitable starting point for the match has been found. When callouts or (*MARK) -items are in use, these "start-up" optimizations can cause them to be skipped -if the pattern is never actually used. The start-up optimizations are in effect -a pre-scan of the subject that takes place before the pattern is run. +suitable starting point for the match has been found. Also, when callouts or +(*MARK) items are in use, these "start-up" optimizations can cause them to be +skipped if the pattern is never actually used. The start-up optimizations are +in effect a pre-scan of the subject that takes place before the pattern is run. .P The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, possibly causing performance to suffer, but ensuring that in cases where the result is "no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) are considered at every possible starting position in the subject string. If PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching -time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, -matching is always done using interpretively. +time. The use of PCRE_NO_START_OPTIMIZE at matching time (that is, passing it +to \fBpcre_exec()\fP) disables JIT execution; in this situation, matching is +always done using interpretively. .P Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. Consider the pattern @@ -1901,7 +1988,7 @@ 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 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. +undefined. Your program may crash or loop. .sp PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT @@ -1935,13 +2022,18 @@ documentation. .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 -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, -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 subject). Unlike the -pattern string, the subject may contain binary zero bytes. +\fIsubject\fP, a length in \fIlength\fP, and a starting offset in +\fIstartoffset\fP. The units for \fIlength\fP and \fIstartoffset\fP are bytes +for the 8-bit library, 16-bit data items for the 16-bit library, and 32-bit +data items for the 32-bit library. +.P +If \fIstartoffset\fP 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, and this +is by far the most common case. In UTF-8 or UTF-16 mode, the offset must point +to the start of a character, or the end of the subject (in UTF-32 mode, one +data unit equals one character, so all offsets are valid). Unlike the pattern +string, the subject may contain binary zeroes. .P A non-zero starting offset is useful when searching for another match in the same subject by calling \fBpcre_exec()\fP again after a previous success. @@ -2005,10 +2097,12 @@ rounded down. When a match is successful, information about captured substrings is returned in pairs of integers, starting at the beginning of \fIovector\fP, 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. \fBNote\fP: these values are always byte offsets, even in UTF-8 -mode. They are not character counts. +each pair is set to the offset of the first character in a substring, and the +second is set to the offset of the first character after the end of a +substring. These values are always data unit offsets, even in UTF mode. They +are byte offsets in the 8-bit library, 16-bit data item offsets in the 16-bit +library, and 32-bit data item offsets in the 32-bit library. \fBNote\fP: they +are not character counts. .P The first pair of integers, \fIovector[0]\fP and \fIovector[1]\fP, identify the portion of the subject string matched by the entire pattern. The next pair is @@ -2346,30 +2440,29 @@ character. The first byte of a character has the value 0xfe or 0xff. These values can never occur in a valid UTF-8 string. .sp - PCRE_UTF8_ERR2 + PCRE_UTF8_ERR22 .sp -Non-character. These are the last two characters in each plane (0xfffe, 0xffff, -0x1fffe, 0x1ffff .. 0x10fffe, 0x10ffff), and the characters 0xfdd0..0xfdef. +This error code was formerly used when the presence of a so-called +"non-character" caused an error. Unicode corrigendum #9 makes it clear that +such characters should not cause a string to be rejected, and so this code is +no longer in use and is never returned. . . .SH "EXTRACTING CAPTURED SUBSTRINGS BY NUMBER" .rs .sp +.nf .B int pcre_copy_substring(const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP, -.ti +5n -.B int \fIbuffersize\fP); -.PP +.B " int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP," +.B " int \fIbuffersize\fP);" +.sp .B int pcre_get_substring(const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, int \fIstringnumber\fP, -.ti +5n -.B const char **\fIstringptr\fP); -.PP +.B " int \fIstringcount\fP, int \fIstringnumber\fP," +.B " const char **\fIstringptr\fP);" +.sp .B int pcre_get_substring_list(const char *\fIsubject\fP, -.ti +5n -.B int *\fIovector\fP, int \fIstringcount\fP, "const char ***\fIlistptr\fP);" +.B " int *\fIovector\fP, int \fIstringcount\fP, const char ***\fIlistptr\fP);" +.fi .PP Captured substrings can be accessed directly by using the offsets returned by \fBpcre_exec()\fP in \fIovector\fP. For convenience, the functions @@ -2448,25 +2541,20 @@ provided. .SH "EXTRACTING CAPTURED SUBSTRINGS BY NAME" .rs .sp +.nf .B int pcre_get_stringnumber(const pcre *\fIcode\fP, -.ti +5n -.B const char *\fIname\fP); -.PP +.B " const char *\fIname\fP);" +.sp .B int pcre_copy_named_substring(const pcre *\fIcode\fP, -.ti +5n -.B const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, const char *\fIstringname\fP, -.ti +5n -.B char *\fIbuffer\fP, int \fIbuffersize\fP); -.PP +.B " const char *\fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, const char *\fIstringname\fP," +.B " char *\fIbuffer\fP, int \fIbuffersize\fP);" +.sp .B int pcre_get_named_substring(const pcre *\fIcode\fP, -.ti +5n -.B const char *\fIsubject\fP, int *\fIovector\fP, -.ti +5n -.B int \fIstringcount\fP, const char *\fIstringname\fP, -.ti +5n -.B const char **\fIstringptr\fP); +.B " const char *\fIsubject\fP, int *\fIovector\fP," +.B " int \fIstringcount\fP, const char *\fIstringname\fP," +.B " const char **\fIstringptr\fP);" +.fi .PP To extract a substring by name, you first have to find associated number. For example, for this pattern @@ -2518,9 +2606,10 @@ same number causes an error at compile time. .SH "DUPLICATE SUBPATTERN NAMES" .rs .sp +.nf .B int pcre_get_stringtable_entries(const pcre *\fIcode\fP, -.ti +5n -.B const char *\fIname\fP, char **\fIfirst\fP, char **\fIlast\fP); +.B " const char *\fIname\fP, char **\fIfirst\fP, char **\fIlast\fP);" +.fi .PP 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 @@ -2609,13 +2698,12 @@ the value returned is the size of each block that is obtained from the heap. .SH "MATCHING A PATTERN: THE ALTERNATIVE FUNCTION" .rs .sp +.nf .B int pcre_dfa_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," -.ti +5n -.B "const char *\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); +.B " const char *\fIsubject\fP, int \fIlength\fP, int \fIstartoffset\fP," +.B " int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP," +.B " int *\fIworkspace\fP, int \fIwscount\fP);" +.fi .P The function \fBpcre_dfa_exec()\fP is called to match a subject string against a compiled pattern, using a matching algorithm that scans the subject string @@ -2742,6 +2830,14 @@ 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. Unlike \fBpcre_exec()\fP, \fBpcre_dfa_exec()\fP can use the entire \fIovector\fP for returning matched strings. +.P +NOTE: PCRE's "auto-possessification" optimization usually applies to character +repeats at the end of a pattern (as well as internally). For example, the +pattern "a\ed+" is compiled as if it were "a\ed++" because there is no point +even considering the possibility of backtracking into the repeated digits. For +DFA matching, this means that only one possible match is found. If you really +do want multiple matches in such cases, either use an ungreedy repeat +("a\ed+?") or set the PCRE_NO_AUTO_POSSESS option when compiling. . . .SS "Error returns from \fBpcre_dfa_exec()\fP" @@ -2818,6 +2914,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 08 November 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 09 February 2014 +Copyright (c) 1997-2014 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcrebuild.3 b/tools/pcre/doc/pcrebuild.3 index b9ae4744..403f2ae3 100644 --- a/tools/pcre/doc/pcrebuild.3 +++ b/tools/pcre/doc/pcrebuild.3 @@ -1,24 +1,54 @@ -.TH PCREBUILD 3 "30 October 2012" "PCRE 8.32" +.TH PCREBUILD 3 "12 May 2013" "PCRE 8.33" .SH NAME PCRE - Perl-compatible regular expressions . . +.SH "BUILDING PCRE" +.rs +.sp +PCRE is distributed with a \fBconfigure\fP script that can be used to build the +library in Unix-like environments using the applications known as Autotools. +Also in the distribution are files to support building using \fBCMake\fP +instead of \fBconfigure\fP. The text file +.\" HTML +.\" +\fBREADME\fP +.\" +contains general information about building with Autotools (some of which is +repeated below), and also has some comments about building on various operating +systems. There is a lot more information about building PCRE without using +Autotools (including information about using \fBCMake\fP and building "by +hand") in the text file called +.\" HTML +.\" +\fBNON-AUTOTOOLS-BUILD\fP. +.\" +You should consult this file as well as the +.\" HTML +.\" +\fBREADME\fP +.\" +file if you are building in a non-Unix-like environment. +. +. .SH "PCRE BUILD-TIME OPTIONS" .rs .sp -This document describes the optional features of PCRE that can be selected when -the library is compiled. It assumes use of the \fBconfigure\fP script, where -the optional features are selected or deselected by providing options to -\fBconfigure\fP before running the \fBmake\fP command. However, the same -options can be selected in both Unix-like and non-Unix-like environments using -the GUI facility of \fBcmake-gui\fP if you are using \fBCMake\fP instead of -\fBconfigure\fP to build PCRE. +The rest of this document describes the optional features of PCRE that can be +selected when the library is compiled. It assumes use of the \fBconfigure\fP +script, where the optional features are selected or deselected by providing +options to \fBconfigure\fP before running the \fBmake\fP command. However, the +same options can be selected in both Unix-like and non-Unix-like environments +using the GUI facility of \fBcmake-gui\fP if you are using \fBCMake\fP instead +of \fBconfigure\fP to build PCRE. .P -There is a lot more information about building PCRE without using -\fBconfigure\fP (including information about using \fBCMake\fP or building "by -hand") in the file called \fINON-AUTOTOOLS-BUILD\fP, which is part of the PCRE -distribution. You should consult this file as well as the \fIREADME\fP file if -you are building in a non-Unix-like environment. +If you are not using Autotools or \fBCMake\fP, option selection can be done by +editing the \fBconfig.h\fP file, or by passing parameter settings to the +compiler, as described in +.\" HTML +.\" +\fBNON-AUTOTOOLS-BUILD\fP. +.\" .P The complete list of options for \fBconfigure\fP (which includes the standard ones such as the selection of the installation directory) can be obtained by @@ -45,7 +75,7 @@ strings, by adding .sp --enable-pcre16 .sp -to the \fBconfigure\fP command. You can also build a separate +to the \fBconfigure\fP command. You can also build yet another separate library, called \fBlibpcre32\fP, in which strings are contained in vectors of 32-bit data units and interpreted either as single-unit characters or UTF-32 strings, by adding @@ -65,8 +95,8 @@ an 8-bit program. None of these are built if you select only the 16-bit or .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 +The Autotools PCRE building process uses \fBlibtool\fP to build both shared and +static libraries by default. You can suppress one of these by adding one of .sp --disable-shared --disable-static @@ -515,6 +545,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 30 October 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 12 May 2013 +Copyright (c) 1997-2013 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcrecallout.3 b/tools/pcre/doc/pcrecallout.3 index 5681335c..8ebc9959 100644 --- a/tools/pcre/doc/pcrecallout.3 +++ b/tools/pcre/doc/pcrecallout.3 @@ -1,4 +1,4 @@ -.TH PCRECALLOUT 3 "24 June 2012" "PCRE 8.30" +.TH PCRECALLOUT 3 "12 November 2013" "PCRE 8.34" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -41,26 +41,64 @@ it is processed as if it were (?C255)A(?C255)((?C255)\ed{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255) .sp 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 +alternation bar. If the pattern contains a conditional group whose condition is +an assertion, an automatic callout is inserted immediately before the +condition. Such a callout may also be inserted explicitly, for example: +.sp + (?(?C9)(?=a)ab|de) +.sp +This applies only to assertion conditions (because they are themselves +independent groups). +.P +Automatic callouts can be used for tracking the progress of pattern matching. +The .\" HREF \fBpcretest\fP .\" -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. +program has a pattern qualifier (/C) that sets automatic callouts; when it is +used, the output indicates how the pattern is being matched. This is useful +information when you are trying to optimize the performance of a particular +pattern. . . .SH "MISSING CALLOUTS" .rs .sp -You should be aware that, because of optimizations in the way PCRE matches -patterns by default, callouts sometimes do not happen. For example, if the -pattern is +You should be aware that, because of optimizations in the way PCRE compiles and +matches patterns, callouts sometimes do not happen exactly as you might expect. +.P +At compile time, PCRE "auto-possessifies" repeated items when it knows that +what follows cannot be part of the repeat. For example, a+[bc] is compiled as +if it were a++[bc]. The \fBpcretest\fP output when this pattern is anchored and +then applied with automatic callouts to the string "aaaa" is: +.sp + --->aaaa + +0 ^ ^ + +1 ^ a+ + +3 ^ ^ [bc] + No match +.sp +This indicates that when matching [bc] fails, there is no backtracking into a+ +and therefore the callouts that would be taken for the backtracks do not occur. +You can disable the auto-possessify feature by passing PCRE_NO_AUTO_POSSESS +to \fBpcre_compile()\fP, or starting the pattern with (*NO_AUTO_POSSESS). If +this is done in \fBpcretest\fP (using the /O qualifier), the output changes to +this: +.sp + --->aaaa + +0 ^ ^ + +1 ^ a+ + +3 ^ ^ [bc] + +3 ^ ^ [bc] + +3 ^ ^ [bc] + +3 ^^ [bc] + No match +.sp +This time, when matching [bc] fails, the matcher backtracks into a+ and tries +again, repeatedly, until a+ itself fails. +.P +Other optimizations that provide fast "no match" results also affect callouts. +For example, if the pattern is .sp ab(?C4)cd .sp @@ -84,11 +122,11 @@ callouts such as the example above are obeyed. .rs .sp During matching, when PCRE reaches a callout point, the external function -defined by \fIpcre_callout\fP or \fIpcre[16|32]_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 \fBpcre[16|32]_callout\fP block. -These structures contains the following fields: +defined by \fIpcre_callout\fP or \fIpcre[16|32]_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 +\fBpcre[16|32]_callout\fP block. These structures contains the following +fields: .sp int \fIversion\fP; int \fIcallout_number\fP; @@ -119,10 +157,10 @@ automatically generated callouts). .P The \fIoffset_vector\fP field is a pointer to the vector of offsets that was passed by the caller to the matching function. When \fBpcre_exec()\fP or -\fBpcre[16|32]_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 the DFA matching functions, this -field is not useful. +\fBpcre[16|32]_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 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 the matching function. @@ -144,8 +182,10 @@ 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 for the DFA matching functions. +substring. However, when a recursion exits, the value reverts to what it was +outside the recursion, as do the values of all captured substrings. If no +substrings have been captured, the value of \fIcapture_last\fP is -1. This is +always the case for the DFA matching functions. .P 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 @@ -173,11 +213,12 @@ 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 \fBpcre[16|32]_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. +callouts from \fBpcre_exec()\fP or \fBpcre[16|32]_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" @@ -209,6 +250,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 24 June 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 12 November 2013 +Copyright (c) 1997-2013 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcrecompat.3 b/tools/pcre/doc/pcrecompat.3 index f24823f8..0cc40198 100644 --- a/tools/pcre/doc/pcrecompat.3 +++ b/tools/pcre/doc/pcrecompat.3 @@ -1,4 +1,4 @@ -.TH PCRECOMPAT 3 "24 June 2012" "PCRE 8.30" +.TH PCRECOMPAT 3 "10 November 2013" "PCRE 8.34" .SH NAME PCRE - Perl-compatible regular expressions .SH "DIFFERENCES BETWEEN PCRE AND PERL" @@ -23,10 +23,8 @@ 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 -numerical variables from any such patterns that are matched before the -assertion fails to match something (thereby succeeding), but only if the -negative lookahead assertion contains just one branch. +counted, but their entries in the offsets vector are never set. Perl sometimes +(but not always) sets its numerical variables from inside negative assertions. .P 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 normal C string, @@ -91,22 +89,28 @@ in the .\" page. .P -10. If any of the backtracking control verbs are used in an assertion or in a -subpattern that is called as a subroutine (whether or not recursively), their -effect is confined to that subpattern; it does not extend to the surrounding -pattern. This is not always the case in Perl. In particular, if (*THEN) is -present in a group that is called as a subroutine, its action is limited to -that group, even if the group does not contain any | characters. There is one -exception to this: the name from a *(MARK), (*PRUNE), or (*THEN) that is -encountered in a 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. +10. If any of the backtracking control verbs are used in a subpattern that is +called as a subroutine (whether or not recursively), their effect is confined +to that subpattern; it does not extend to the 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. Note that such subpatterns are +processed as anchored at the point where they are tested. .P -11. There are some differences that are concerned with the settings of captured +11. If a pattern contains more than one backtracking control verb, the first +one that is backtracked onto acts. For example, in the pattern +A(*COMMIT)B(*PRUNE)C a failure in B triggers (*COMMIT), but a failure in C +triggers (*PRUNE). Perl's behaviour is more complex; in many cases it is the +same as PCRE, but there are examples where it differs. +.P +12. Most backtracking verbs in assertions have their normal actions. They are +not confined to the assertion. +.P +13. There are some differences that are concerned with the settings of captured strings when part of a pattern is repeated. For example, matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b". .P -12. PCRE's handling of duplicate subpattern numbers and duplicate subpattern +14. 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)|(? +#include +#include + +#define OVECCOUNT 30 /* should be a multiple of 3 */ + + +int main(int argc, char **argv) +{ +pcre *re; +const char *error; +char *pattern; +char *subject; +unsigned char *name_table; +unsigned int option_bits; +int erroffset; +int find_all; +int crlf_is_newline; +int namecount; +int name_entry_size; +int ovector[OVECCOUNT]; +int subject_length; +int rc, i; +int utf8; + + +/************************************************************************** +* First, sort out the command line. There is only one possible option at * +* the moment, "-g" to request repeated matching to find all occurrences, * +* like Perl's /g option. We set the variable find_all to a non-zero value * +* if the -g option is present. Apart from that, there must be exactly two * +* arguments. * +**************************************************************************/ + +find_all = 0; +for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-g") == 0) find_all = 1; + else break; + } + +/* After the options, we require exactly two arguments, which are the pattern, +and the subject string. */ + +if (argc - i != 2) + { + printf("Two arguments required: a regex and a subject string\en"); + return 1; + } + +pattern = argv[i]; +subject = argv[i+1]; +subject_length = (int)strlen(subject); + + +/************************************************************************* +* Now we are going to compile the regular expression pattern, and handle * +* and errors that are detected. * +*************************************************************************/ + +re = pcre_compile( + pattern, /* the pattern */ + 0, /* default options */ + &error, /* for error message */ + &erroffset, /* for error offset */ + NULL); /* use default character tables */ + +/* Compilation failed: print the error message and exit */ + +if (re == NULL) + { + printf("PCRE compilation failed at offset %d: %s\en", erroffset, error); + return 1; + } + + +/************************************************************************* +* If the compilation succeeded, we call PCRE again, in order to do a * +* pattern match against the subject string. This does just ONE match. If * +* further matching is needed, it will be done below. * +*************************************************************************/ + +rc = pcre_exec( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + subject, /* the subject string */ + subject_length, /* the length of the subject */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + ovector, /* output vector for substring information */ + OVECCOUNT); /* number of elements in the output vector */ + +/* Matching failed: handle error cases */ + +if (rc < 0) + { + switch(rc) + { + case PCRE_ERROR_NOMATCH: printf("No match\en"); break; + /* + Handle other special cases if you like + */ + default: printf("Matching error %d\en", rc); break; + } + pcre_free(re); /* Release memory used for the compiled pattern */ + return 1; + } + +/* Match succeded */ + +printf("\enMatch succeeded at offset %d\en", ovector[0]); + + +/************************************************************************* +* We have found the first match within the subject string. If the output * +* vector wasn't big enough, say so. Then output any substrings that were * +* captured. * +*************************************************************************/ + +/* The output vector wasn't big enough */ + +if (rc == 0) + { + rc = OVECCOUNT/3; + printf("ovector only has room for %d captured substrings\en", rc - 1); + } + +/* Show substrings stored in the output vector by number. Obviously, in a real +application you might want to do things other than print them. */ + +for (i = 0; i < rc; i++) + { + char *substring_start = subject + ovector[2*i]; + int substring_length = ovector[2*i+1] - ovector[2*i]; + printf("%2d: %.*s\en", i, substring_length, substring_start); + } + + +/************************************************************************** +* That concludes the basic part of this demonstration program. We have * +* compiled a pattern, and performed a single match. The code that follows * +* shows first how to access named substrings, and then how to code for * +* repeated matches on the same subject. * +**************************************************************************/ + +/* See if there are any named substrings, and if so, show them by name. First +we have to extract the count of named parentheses from the pattern. */ + +(void)pcre_fullinfo( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + PCRE_INFO_NAMECOUNT, /* number of named substrings */ + &namecount); /* where to put the answer */ + +if (namecount <= 0) printf("No named substrings\en"); else + { + unsigned char *tabptr; + printf("Named substrings\en"); + + /* Before we can access the substrings, we must extract the table for + translating names to numbers, and the size of each entry in the table. */ + + (void)pcre_fullinfo( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + PCRE_INFO_NAMETABLE, /* address of the table */ + &name_table); /* where to put the answer */ + + (void)pcre_fullinfo( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + PCRE_INFO_NAMEENTRYSIZE, /* size of each entry in the table */ + &name_entry_size); /* where to put the answer */ + + /* Now we can scan the table and, for each entry, print the number, the name, + and the substring itself. */ + + tabptr = name_table; + for (i = 0; i < namecount; i++) + { + int n = (tabptr[0] << 8) | tabptr[1]; + printf("(%d) %*s: %.*s\en", n, name_entry_size - 3, tabptr + 2, + ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); + tabptr += name_entry_size; + } + } + + +/************************************************************************* +* If the "-g" option was given on the command line, we want to continue * +* to search for additional matches in the subject string, in a similar * +* way to the /g option in Perl. This turns out to be trickier than you * +* might think because of the possibility of matching an empty string. * +* What happens is as follows: * +* * +* If the previous match was NOT for an empty string, we can just start * +* the next match at the end of the previous one. * +* * +* If the previous match WAS for an empty string, we can't do that, as it * +* would lead to an infinite loop. Instead, a special call of pcre_exec() * +* is made with the PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED flags set. * +* The first of these tells PCRE that an empty string at the start of the * +* subject is not a valid match; other possibilities must be tried. The * +* second flag restricts PCRE to one match attempt at the initial string * +* position. If this match succeeds, an alternative to the empty string * +* match has been found, and we can print it and proceed round the loop, * +* advancing by the length of whatever was found. If this match does not * +* succeed, we still stay in the loop, advancing by just one character. * +* In UTF-8 mode, which can be set by (*UTF8) in the pattern, this may be * +* 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 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. * +*************************************************************************/ + +if (!find_all) /* Check for -g */ + { + pcre_free(re); /* Release the memory used for the compiled pattern */ + return 0; /* Finish unless -g was given */ + } + +/* Before running the loop, check for UTF-8 and whether CRLF is a valid newline +sequence. First, find the options with which the regex was compiled; extract +the UTF-8 state, and mask off all but the newline options. */ + +(void)pcre_fullinfo(re, NULL, PCRE_INFO_OPTIONS, &option_bits); +utf8 = option_bits & PCRE_UTF8; +option_bits &= PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_CRLF| + PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF; + +/* If no newline options were set, find the default newline convention from the +build configuration. */ + +if (option_bits == 0) + { + int 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. */ + option_bits = (d == 13)? PCRE_NEWLINE_CR : + (d == 10)? PCRE_NEWLINE_LF : + (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF : + (d == -2)? PCRE_NEWLINE_ANYCRLF : + (d == -1)? PCRE_NEWLINE_ANY : 0; + } + +/* See if CRLF is a valid newline sequence. */ + +crlf_is_newline = + option_bits == PCRE_NEWLINE_ANY || + option_bits == PCRE_NEWLINE_CRLF || + option_bits == PCRE_NEWLINE_ANYCRLF; + +/* Loop for second and subsequent matches */ + +for (;;) + { + int options = 0; /* Normally no options */ + int start_offset = ovector[1]; /* Start at end of previous match */ + + /* If the previous match was for an empty string, we are finished if we are + at the end of the subject. Otherwise, arrange to run another match at the + same point to see if a non-empty match can be found. */ + + if (ovector[0] == ovector[1]) + { + if (ovector[0] == subject_length) break; + options = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED; + } + + /* Run the next matching operation */ + + rc = pcre_exec( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + subject, /* the subject string */ + subject_length, /* the length of the subject */ + start_offset, /* starting offset in the subject */ + options, /* options */ + ovector, /* output vector for substring information */ + OVECCOUNT); /* number of elements in the output vector */ + + /* This time, a result of NOMATCH isn't an error. If the value in "options" + is zero, it just means we have found all possible matches, so the loop ends. + Otherwise, it means we have failed to find a non-empty-string match at a + point where there was a previous empty-string match. In this case, we do what + Perl does: advance the matching position by one character, and continue. We + do this by setting the "end of previous match" offset, because that is picked + up at the top of the loop as the point at which to start again. + + There are two complications: (a) When CRLF is a valid newline sequence, and + the current position is just before it, advance by an extra byte. (b) + Otherwise we must ensure that we skip an entire UTF-8 character if we are in + UTF-8 mode. */ + + if (rc == PCRE_ERROR_NOMATCH) + { + if (options == 0) break; /* All matches found */ + ovector[1] = start_offset + 1; /* Advance one byte */ + if (crlf_is_newline && /* If CRLF is newline & */ + start_offset < subject_length - 1 && /* we are at CRLF, */ + subject[start_offset] == '\er' && + subject[start_offset + 1] == '\en') + ovector[1] += 1; /* Advance by one more. */ + else if (utf8) /* Otherwise, ensure we */ + { /* advance a whole UTF-8 */ + while (ovector[1] < subject_length) /* character. */ + { + if ((subject[ovector[1]] & 0xc0) != 0x80) break; + ovector[1] += 1; + } + } + continue; /* Go round the loop again */ + } + + /* Other matching errors are not recoverable. */ + + if (rc < 0) + { + printf("Matching error %d\en", rc); + pcre_free(re); /* Release memory used for the compiled pattern */ + return 1; + } + + /* Match succeded */ + + printf("\enMatch succeeded again at offset %d\en", ovector[0]); + + /* The match succeeded, but the output vector wasn't big enough. */ + + if (rc == 0) + { + rc = OVECCOUNT/3; + printf("ovector only has room for %d captured substrings\en", rc - 1); + } + + /* As before, show substrings stored in the output vector by number, and then + also any named substrings. */ + + for (i = 0; i < rc; i++) + { + char *substring_start = subject + ovector[2*i]; + int substring_length = ovector[2*i+1] - ovector[2*i]; + printf("%2d: %.*s\en", i, substring_length, substring_start); + } + + if (namecount <= 0) printf("No named substrings\en"); else + { + unsigned char *tabptr = name_table; + printf("Named substrings\en"); + for (i = 0; i < namecount; i++) + { + int n = (tabptr[0] << 8) | tabptr[1]; + printf("(%d) %*s: %.*s\en", n, name_entry_size - 3, tabptr + 2, + ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); + tabptr += name_entry_size; + } + } + } /* End of loop to find second and subsequent matches */ + +printf("\en"); +pcre_free(re); /* Release memory used for the compiled pattern */ +return 0; +} + +/* End of pcredemo.c */ +.EE diff --git a/tools/pcre/doc/pcregrep.1 b/tools/pcre/doc/pcregrep.1 index 7fa5b65e..98866754 100644 --- a/tools/pcre/doc/pcregrep.1 +++ b/tools/pcre/doc/pcregrep.1 @@ -1,4 +1,4 @@ -.TH PCREGREP 1 "13 September 2012" "PCRE 8.32" +.TH PCREGREP 1 "03 April 2014" "PCRE 8.35" .SH NAME pcregrep - a grep with Perl-compatible regular expressions. .SH SYNOPSIS @@ -11,9 +11,13 @@ pcregrep - a grep with Perl-compatible regular expressions. grep commands do, but it uses the PCRE regular expression library to support patterns that are compatible with the regular expressions of Perl 5. See .\" HREF +\fBpcresyntax\fP(3) +.\" +for a quick-reference summary of pattern syntax, or +.\" HREF \fBpcrepattern\fP(3) .\" -for a full description of syntax and semantics of the regular expressions +for a full description of the syntax and semantics of the regular expressions that PCRE supports. .P Patterns, whether supplied on the command line or in a separate file, are given @@ -674,6 +678,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 13 September 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 03 April 2014 +Copyright (c) 1997-2014 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcregrep.txt b/tools/pcre/doc/pcregrep.txt index 0d5a12fb..97d9a7bd 100644 --- a/tools/pcre/doc/pcregrep.txt +++ b/tools/pcre/doc/pcregrep.txt @@ -1,10 +1,10 @@ -PCREGREP(1) PCREGREP(1) +PCREGREP(1) General Commands Manual PCREGREP(1) + NAME pcregrep - a grep with Perl-compatible regular expressions. - SYNOPSIS pcregrep [options] [long options] [pattern] [path1 path2 ...] @@ -14,394 +14,395 @@ DESCRIPTION pcregrep searches files for character patterns, in the same way as other grep commands do, but it uses the PCRE regular expression library to support patterns that are compatible with the regular expressions of - Perl 5. See pcrepattern(3) for a full description of syntax and seman- + Perl 5. See pcresyntax(3) for a quick-reference summary of pattern syn- + tax, or pcrepattern(3) for a full description of the syntax and seman- tics of the regular expressions that PCRE supports. - Patterns, whether supplied on the command line or in a separate file, + Patterns, whether supplied on the command line or in a separate file, are given without delimiters. For example: pcregrep Thursday /etc/motd If you attempt to use delimiters (for example, by surrounding a pattern - with slashes, as is common in Perl scripts), they are interpreted as - part of the pattern. Quotes can of course be used to delimit patterns - on the command line because they are interpreted by the shell, and - indeed quotes are required if a pattern contains white space or shell + with slashes, as is common in Perl scripts), they are interpreted as + part of the pattern. Quotes can of course be used to delimit patterns + on the command line because they are interpreted by the shell, and + indeed quotes are required if a pattern contains white space or shell metacharacters. - The first argument that follows any option settings is treated as the - single pattern to be matched when neither -e nor -f is present. Con- - versely, when one or both of these options are used to specify pat- + The first argument that follows any option settings is treated as the + single pattern to be matched when neither -e nor -f is present. Con- + versely, when one or both of these options are used to specify pat- terns, all arguments are treated as path names. At least one of -e, -f, or an argument pattern must be provided. If no files are specified, pcregrep reads the standard input. The stan- - dard input can also be referenced by a name consisting of a single + dard input can also be referenced by a name consisting of a single hyphen. For example: pcregrep some-pattern /file1 - /file3 - By default, each line that matches a pattern is copied to the standard - output, and if there is more than one file, the file name is output at + By default, each line that matches a pattern is copied to the standard + output, and if there is more than one file, the file name is output at the start of each line, followed by a colon. However, there are options - that can change how pcregrep behaves. In particular, the -M option - makes it possible to search for patterns that span line boundaries. - What defines a line boundary is controlled by the -N (--newline) + that can change how pcregrep behaves. In particular, the -M option + makes it possible to search for patterns that span line boundaries. + What defines a line boundary is controlled by the -N (--newline) option. 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" + 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 can be no longer than 8K or BUFSIZ bytes, whichever is the - greater. BUFSIZ is defined in . When there is more than one + Patterns can be no longer than 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 + 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 a line, no further patterns + By default, as soon as one pattern matches a line, no further patterns are considered. However, if --colour (or --color) is used to colour the - matching substrings, or if --only-matching, --file-offsets, or --line- - offsets is used to output only the part of the line that matched + matching substrings, or if --only-matching, --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 follow the one that matched + 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 follow the one that matched are not tried on the earlier part of the line. - This behaviour means that the order in which multiple patterns are - specified can affect the output when one of the above options is used. - This is no longer the same behaviour as GNU grep, which now manages to - display earlier matches for later patterns (as long as there is no + This behaviour means that the order in which multiple patterns are + specified can affect the output when one of the above options is used. + This is no longer the same behaviour as GNU grep, which now manages to + display earlier matches for later patterns (as long as there is no overlap). - 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 + 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. Similarly, except where noted below, if an option is - given twice, the later setting is used. Numerical values for options - may be followed by K or M, to signify multiplication by 1024 or + 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. Similarly, except where noted below, if an option is + given twice, the later setting is used. Numerical values for options + may be followed by K or M, to signify multiplication by 1024 or 1024*1024 respectively. -- 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- + 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. -A number, --after-context=number - Output number lines of context after each matching line. If + Output number lines of context after 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 following text avail- able for context output. -a, --text - Treat binary files as text. This is equivalent to --binary- + 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 + 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 + 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 + 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. -c, --count - Do not output individual lines from the files that are being + Do not output individual lines from the files that are being scanned; instead output the number of lines that would other- - wise have been shown. If no lines are selected, the number - zero is output. If several files are are being scanned, a - count is output for each of them. However, if the --files- - with-matches option is also used, only those files whose + wise have been shown. If no lines are selected, the number + zero is output. If several files are are being scanned, a + count is output for each of them. However, if the --files- + with-matches option is also used, only those files whose counts are greater than zero are listed. When -c is used, the -A, -B, and -C options are ignored. --colour, --color If this option is given without any data, it is equivalent to - "--colour=auto". If data is required, it must be given in + "--colour=auto". If data is required, it must be given in the same shell item, separated by an equals sign. --colour=value, --color=value This option specifies under what circumstances the parts of a line that matched a pattern should be coloured in the output. - By default, the output is not coloured. The value (which is - optional, see above) may be "never", "always", or "auto". In - the latter case, colouring happens only if the standard out- - put is connected to a terminal. More resources are used when - colouring is enabled, because pcregrep has to search for all - possible matches in a line, not just one, in order to colour + By default, the output is not coloured. The value (which is + optional, see above) may be "never", "always", or "auto". In + the latter case, colouring happens only if the standard out- + put is connected to a terminal. More resources are used when + colouring is enabled, because pcregrep has to search for all + possible matches in a line, not just one, in order to colour them all. The colour that is used can be specified by setting the envi- ronment variable PCREGREP_COLOUR or PCREGREP_COLOR. The value of this variable should be a string of two numbers, separated - by a semicolon. They are copied directly into the control - string for setting colour on a terminal, so it is your - responsibility to ensure that they make sense. If neither of - the environment variables is set, the default is "1;31", + by a semicolon. They are copied directly into the control + string for setting colour on a terminal, so it is your + responsibility to ensure that they make sense. If neither of + the environment variables is set, the default is "1;31", which gives red. -D action, --devices=action - If an input path is not a regular file or a directory, - "action" specifies how it is to be processed. Valid values + If an input path is not a regular file or a directory, + "action" specifies how it is to be processed. Valid values are "read" (the default) or "skip" (silently skip the path). -d action, --directories=action If an input path is a directory, "action" specifies how it is - to be processed. Valid values are "read" (the default in - non-Windows environments, for compatibility with GNU grep), - "recurse" (equivalent to the -r option), or "skip" (silently - skip the path, the default in Windows environments). In the - "read" case, directories are read as if they were ordinary - files. In some operating systems the effect of reading a + to be processed. Valid values are "read" (the default in + non-Windows environments, for compatibility with GNU grep), + "recurse" (equivalent to the -r option), or "skip" (silently + skip the path, the default in Windows environments). In the + "read" case, directories are read as if they were ordinary + files. In some operating systems the effect of reading a directory like this is an immediate end-of-file; in others it may provoke an error. -e pattern, --regex=pattern, --regexp=pattern Specify a pattern to be matched. This option can be used mul- tiple times in order to specify several patterns. It can also - be used as a way of specifying a single pattern that starts - with a hyphen. When -e is used, no argument pattern is taken - from the command line; all arguments are treated as file - names. There is no limit to the number of patterns. They are - applied to each line in the order in which they are defined + be used as a way of specifying a single pattern that starts + with a hyphen. When -e is used, no argument pattern is taken + from the command line; all arguments are treated as file + names. There is no limit to the number of patterns. They are + applied to each line in the order in which they are defined until one matches. - If -f is used with -e, the command line patterns are matched + If -f is used with -e, the command line patterns are matched first, followed by the patterns from the file(s), independent - of the order in which these options are specified. Note that - multiple use of -e is not the same as a single pattern with + of the order in which these options are specified. Note that + multiple use of -e is not the same as a single pattern with alternatives. For example, X|Y finds the first character in a - line that is X or Y, whereas if the two patterns are given - separately, with X first, pcregrep finds X if it is present, + line that is X or Y, whereas if the two patterns are given + separately, with X first, pcregrep finds X if it is present, even if it follows Y in the line. It finds Y only if there is - no X in the line. This matters only if you are using -o or + no X in the line. This matters only if you are using -o or --colo(u)r to show the part(s) of the line that matched. --exclude=pattern Files (but not directories) whose names match the pattern are - skipped without being processed. This applies to all files, - whether listed on the command line, obtained from --file- + skipped without being processed. This applies to all files, + whether listed on the command line, obtained from --file- list, or by scanning a directory. The pattern is a PCRE regu- lar expression, and is matched against the final component of - the file name, not the entire path. The -F, -w, and -x + the file name, not the entire path. The -F, -w, and -x options do not apply to this pattern. The option may be given any number of times in order to specify multiple patterns. If - a file name matches both an --include and an --exclude pat- + a file name matches both an --include and an --exclude pat- tern, it is excluded. There is no short form for this option. --exclude-from=filename - Treat each non-empty line of the file as the data for an + Treat each non-empty line of the file as the data for an --exclude option. What constitutes a newline when reading the - file is the operating system's default. The --newline option - has no effect on this option. This option may be given more + file is the operating system's default. The --newline option + has no effect on this option. This option may be given more than once in order to specify a number of files to read. --exclude-dir=pattern Directories whose names match the pattern are skipped without - being processed, whatever the setting of the --recursive - option. This applies to all directories, whether listed on + being processed, whatever the setting of the --recursive + option. This applies to all directories, whether listed on the command line, obtained from --file-list, or by scanning a - parent directory. The pattern is a PCRE regular expression, - and is matched against the final component of the directory - name, not the entire path. The -F, -w, and -x options do not - apply to this pattern. The option may be given any number of - times in order to specify more than one pattern. If a direc- - tory matches both --include-dir and --exclude-dir, it is + parent directory. The pattern is a PCRE regular expression, + and is matched against the final component of the directory + name, not the entire path. The -F, -w, and -x options do not + apply to this pattern. The option may be given any number of + times in order to specify more than one pattern. If a direc- + tory matches both --include-dir and --exclude-dir, it is excluded. There is no short form for this option. -F, --fixed-strings - Interpret each data-matching pattern as a list of fixed - strings, separated by newlines, instead of as a regular - expression. What constitutes a newline for this purpose is - controlled by the --newline option. The -w (match as a word) - and -x (match whole line) options can be used with -F. They + Interpret each data-matching pattern as a list of fixed + strings, separated by newlines, instead of as a regular + expression. What constitutes a newline for this purpose is + controlled by the --newline option. The -w (match as a word) + and -x (match whole line) options can be used with -F. They apply to each of the fixed strings. A line is selected if any of the fixed strings are found in it (subject to -w or -x, if - present). This option applies only to the patterns that are - matched against the contents of files; it does not apply to - patterns specified by any of the --include or --exclude + present). This option applies only to the patterns that are + matched against the contents of files; it does not apply to + patterns specified by any of the --include or --exclude options. -f filename, --file=filename - Read patterns from the file, one per line, and match them - against each line of input. What constitutes a newline when - reading the file is the operating system's default. The + Read patterns from the file, one per line, and match them + against each line of input. What constitutes a newline when + reading the file is the operating system's default. The --newline option has no effect on this option. Trailing white space is removed from each line, and blank lines are ignored. - An empty file contains no patterns and therefore matches + 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 + a single pattern with alternatives in the description of -e above. - If this option is given more than once, all the specified - files are read. A data line is output if any of the patterns - match it. A 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 + If this option is given more than once, all the specified + files are read. A data line is output if any of the patterns + match it. A 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 the names of paths to be searched. --file-list=filename - Read a list of files and/or directories that are to be - scanned from the given file, one per line. Trailing white + Read a list of files and/or directories that are to be + scanned from the given file, one per line. Trailing white space is removed from each line, and blank lines are ignored. - These paths are processed before any that are listed on the - command line. The filename can be given as "-" to refer to + These paths are processed before any that are listed on the + command line. The filename can be given as "-" to refer to the standard input. If --file and --file-list are both spec- - ified 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. If this option is given more than once, all the + ified 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. If this option is given more than once, all the specified files are read. --file-offsets - Instead of showing lines or parts of lines that match, show - each match as an offset from the start of the file and a - length, separated by a comma. In this mode, no context is - shown. That is, the -A, -B, and -C options are ignored. If + Instead of showing lines or parts of lines that match, show + each match as an offset from the start of the file and a + length, 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 - separately. This option is mutually exclusive with --line- + separately. This option is mutually exclusive with --line- offsets and --only-matching. -H, --with-filename - Force the inclusion of the filename at the start of output - lines when searching a single file. By default, the filename - is not shown in this case. For matching lines, the filename + Force the inclusion of the filename at the start of output + lines when searching a single file. By default, the filename + is not shown in this case. For matching lines, the filename is followed by a colon; for context lines, a hyphen separator - is used. If a line number is also being output, it follows + is used. If a line number is also being output, it follows the file name. -h, --no-filename - Suppress the output filenames when searching multiple files. - By default, filenames are shown when multiple files are - searched. For matching lines, the filename is followed by a - colon; for context lines, a hyphen separator is used. If a + Suppress the output filenames when searching multiple files. + By default, filenames are shown when multiple files are + searched. For matching lines, the filename is followed by a + colon; for context lines, a hyphen separator is used. If a line number is also being output, it follows the file name. - --help Output a help message, giving brief details of the command - options and file type support, and then exit. Anything else + --help Output a help message, giving brief details of the command + options and file type support, and then exit. Anything else on the command line is ignored. - -I Treat binary files as never matching. This is equivalent to + -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. --include=pattern - If any --include patterns are specified, the only files that - are processed are those that match one of the patterns (and - do not match an --exclude pattern). This option does not - affect directories, but it applies to all files, whether - listed on the command line, obtained from --file-list, or by - scanning a directory. The pattern is a PCRE regular expres- - sion, and is matched against the final component of the file - name, not the entire path. The -F, -w, and -x options do not - apply to this pattern. The option may be given any number of - times. If a file name matches both an --include and an - --exclude pattern, it is excluded. There is no short form + If any --include patterns are specified, the only files that + are processed are those that match one of the patterns (and + do not match an --exclude pattern). This option does not + affect directories, but it applies to all files, whether + listed on the command line, obtained from --file-list, or by + scanning a directory. The pattern is a PCRE regular expres- + sion, and is matched against the final component of the file + name, not the entire path. The -F, -w, and -x options do not + apply to this pattern. The option may be given any number of + times. If a file name matches both an --include and an + --exclude pattern, it is excluded. There is no short form for this option. --include-from=filename - Treat each non-empty line of the file as the data for an + Treat each non-empty line of the file as the data for an --include option. What constitutes a newline for this purpose - is the operating system's default. The --newline option has + is the operating system's default. The --newline option has no effect on this option. This option may be given any number of times; all the files are read. --include-dir=pattern - If any --include-dir patterns are specified, the only direc- - tories that are processed are those that match one of the - patterns (and do not match an --exclude-dir pattern). This - applies to all directories, whether listed on the command - line, obtained from --file-list, or by scanning a parent - directory. The pattern is a PCRE regular expression, and is - matched against the final component of the directory name, - not the entire path. The -F, -w, and -x options do not apply + If any --include-dir patterns are specified, the only direc- + tories that are processed are those that match one of the + patterns (and do not match an --exclude-dir pattern). This + applies to all directories, whether listed on the command + line, obtained from --file-list, or by scanning a parent + directory. The pattern is a PCRE regular expression, and is + matched against the final component of the directory name, + not the entire path. The -F, -w, and -x options do not apply to this pattern. The option may be given any number of times. - If a directory matches both --include-dir and --exclude-dir, + If a directory 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. @@ -411,313 +412,313 @@ OPTIONS 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-like environments). Output to - terminal is normally automatically flushed by the operating + 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-like environments). Output to + terminal is normally automatically flushed by the operating system. 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- + 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 (form feed, - 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 to scan files + ANY. This makes it possible to use pcregrep to scan files that have come from other environments without having to mod- - ify their line endings. If the data that is being scanned - does not agree with the convention set by this option, pcre- - grep may behave in strange ways. Note that this option does - not apply to files specified by the -f, --exclude-from, or + ify their line endings. If the data that is being scanned + does not agree with the convention set by this option, pcre- + grep may behave in strange ways. Note that this option does + not apply to files specified by the -f, --exclude-from, or --include-from options, which are expected to use the operat- ing system's standard newline sequence. -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 + --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- + 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 - is, the -A, -B, and -C options are ignored. If there is more - than one match in a line, each of them is shown separately. - If -o is combined with -v (invert the sense of the match to - find non-matching lines), no output is generated, but the - return code is set appropriately. If the matched portion of - the line is empty, nothing is output unless the file name or - line number are being printed, in which case they are shown + of the whole line. 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 separately. + If -o is combined with -v (invert the sense of the match to + find non-matching lines), no output is generated, but the + return code is set appropriately. If the matched portion of + the line is empty, nothing is output unless the file name or + line number are being printed, in which case they are shown on an otherwise empty line. This option is mutually exclusive with --file-offsets and --line-offsets. -onumber, --only-matching=number - Show only the part of the line that matched the capturing + Show only the part of the line that matched the capturing parentheses of the given number. Up to 32 capturing parenthe- ses are supported, and -o0 is equivalent to -o without a num- - ber. Because these options can be given without an argument - (see above), if an argument is present, it must be given in - the same shell item, for example, -o3 or --only-matching=2. + ber. Because these options can be given without an argument + (see above), if an argument is present, it must be given in + the same shell item, for example, -o3 or --only-matching=2. The comments given for the non-argument case above also apply - to this case. If the specified capturing parentheses do not - exist in the pattern, or were not set in the match, nothing - is output unless the file name or line number are being + to this case. If the specified capturing parentheses do not + exist in the pattern, or were not set in the match, nothing + is output unless the file name or line number are being printed. - If this option is given multiple times, multiple substrings - are output, in the order the options are given. For example, + If this option is given multiple times, multiple substrings + are output, in the order the options are given. For example, -o3 -o1 -o3 causes the substrings matched by capturing paren- - theses 3 and 1 and then 3 again to be output. By default, + theses 3 and 1 and then 3 again to be output. By default, there is no separator (but see the next option). --om-separator=text - Specify a separating string for multiple occurrences of -o. - The default is an empty string. Separating strings are never + Specify a separating string for multiple occurrences of -o. + The default is an empty string. Separating strings are never coloured. -q, --quiet Work quietly, that is, display nothing except error messages. - The exit status indicates whether or not any matches were + The exit status indicates whether or not any matches were found. -r, --recursive - If any given path is a directory, recursively scan the files - it contains, taking note of any --include and --exclude set- - tings. By default, a directory is read as a normal file; in - some operating systems this gives an immediate end-of-file. - This option is a shorthand for setting the -d option to + If any given path is a directory, recursively scan the files + it contains, taking note of any --include and --exclude set- + tings. By default, a directory is read as a normal file; in + some operating systems this gives an immediate end-of-file. + This option is a shorthand for setting the -d option to "recurse". --recursion-limit=number See --match-limit above. -s, --no-messages - Suppress error messages about non-existent or unreadable - files. Such files are quietly skipped. However, the return + Suppress error messages about non-existent or unreadable + files. Such files are quietly skipped. However, the return code is still 2, even if matches were found in other files. -u, --utf-8 - Operate in UTF-8 mode. This option is available only if PCRE + Operate in UTF-8 mode. This option is available only if PCRE has been compiled with UTF-8 support. All patterns (including - those for any --exclude and --include options) and all sub- - ject lines that are scanned must be valid strings of UTF-8 + those for any --exclude and --include options) and all sub- + ject lines that are scanned must be valid strings of UTF-8 characters. -V, --version Write the version numbers of pcregrep and the PCRE library to - the standard output and then exit. Anything else on the com- + the standard output and then exit. Anything else on the com- mand line is ignored. -v, --invert-match - Invert the sense of the match, so that lines which do not + Invert the sense of the match, so that lines which do not match any of the patterns are the ones that are found. -w, --word-regex, --word-regexp Force the patterns to match only whole words. This is equiva- - lent to having \b at the start and end of the pattern. This - option applies only to the patterns that are matched against - the contents of files; it does not apply to patterns speci- + lent to having \b at the start and end of the pattern. This + option applies only to the patterns that are matched against + the contents of files; it does not apply to patterns speci- fied by any of the --include or --exclude options. -x, --line-regex, --line-regexp - Force the patterns to be anchored (each must start matching - at the beginning of a line) and in addition, require them to - match entire lines. This is equivalent to having ^ and $ + Force the patterns to be anchored (each must start matching + at the beginning of a line) and in addition, require them to + match entire lines. This is equivalent to having ^ and $ characters at the start and end of each alternative branch in - every pattern. This option applies only to the patterns that - are matched against the contents of files; it does not apply - to patterns specified by any of the --include or --exclude + every pattern. This option applies only to the patterns that + are matched against the contents of files; it does not apply + to patterns specified by any of the --include or --exclude options. 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 + 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 - The -N (--newline) option allows pcregrep to scan files with different + The -N (--newline) option allows pcregrep to scan files with different newline conventions from the default. Any parts of the input files that - are written to the standard output are copied identically, with what- - ever newline sequences they have in the input. However, the setting of - this option does not affect the interpretation of files specified by + are written to the standard output are copied identically, with what- + ever newline sequences they have in the input. However, the setting of + this option does not affect the interpretation of files specified by the -f, --exclude-from, or --include-from options, which are assumed to - use the operating system's standard newline sequence, nor does it - affect the way in which pcregrep writes informational messages to the + use the operating system's standard newline sequence, nor does it + affect the way in which pcregrep writes informational messages to the standard error and output streams. For these it uses the string "\n" to - indicate newlines, relying on the C I/O library to convert this to an + indicate newlines, relying on the C I/O library to convert this to an appropriate sequence. OPTIONS COMPATIBILITY - Many of the short and long forms of pcregrep's options are the same as - 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, --om-separa- - tor, --recursion-limit, -u, and --utf-8 options are specific to pcre- - grep, as is the use of the --only-matching option with a capturing + Many of the short and long forms of pcregrep's options are the same as + 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, --om-separa- + tor, --recursion-limit, -u, and --utf-8 options are specific to pcre- + grep, 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 - glob for GNU grep, but a regular expression for pcregrep. If both the - -c and -l options are given, GNU grep lists only file names, without + 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 + glob for GNU grep, but a regular expression for pcregrep. If both the + -c and -l options are given, GNU grep lists only file names, without counts, but pcregrep gives the counts. OPTIONS WITH DATA There are four different ways in which an option with data can be spec- - ified. If a short form option is used, the data may follow immedi- + ified. If a short form option is used, the data may follow immedi- ately, or (with one exception) in the next command line item. For exam- ple: -f/some/file -f /some/file - The exception is the -o option, which may appear with or without data. - Because of this, if data is present, it must follow immediately in the + The exception is the -o option, which may appear with or without data. + Because of this, if data is present, it must follow immediately in the same item, for example -o3. - If a long form option is used, the data may appear in the same command - line item, separated by an equals character, or (with two exceptions) + If a long form option is used, the data may appear in the same command + line item, separated by an equals character, or (with two exceptions) it may appear in the next command line item. For example: --file=/some/file --file /some/file - Note, however, that if you want to supply a file name beginning with ~ - as data in a shell command, and have the shell expand ~ to a home + Note, however, that if you want to supply a file name beginning with ~ + as data in a shell command, and have the shell expand ~ to a home directory, you must separate the file name from the option, because the shell does not treat ~ specially unless it is at the start of an item. - The exceptions to the above are the --colour (or --color) and --only- - matching options, for which the data is optional. If one of these - options does have data, it must be given in the first form, using an + The exceptions to the above are the --colour (or --color) and --only- + matching options, for which the data is optional. If one of these + 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 - 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 repeats, for example: (a+)*\d when matched against a - line of a's with no final digit. The PCRE matching function has a - resource limit that causes it to abort in these circumstances. If this + 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 repeats, for example: (a+)*\d when matched against a + line of a's with no final digit. The PCRE matching function has a + resource limit that causes it to abort in these circumstances. If this happens, pcregrep outputs an error message and the line that caused the - problem to the standard error stream. If there are more than 20 such + problem to the standard error stream. If there are more than 20 such errors, pcregrep gives up. - The --match-limit option of pcregrep can be used to set the overall - resource limit; there is a second option called --recursion-limit that - sets a limit on the amount of memory (usually stack) that is used (see + The --match-limit option of pcregrep can be used to set the overall + resource limit; there is a second option called --recursion-limit that + sets a limit on the amount of memory (usually stack) that is used (see the discussion of these options above). DIAGNOSTICS Exit status is 0 if any matches were found, 1 if no matches were found, - and 2 for syntax errors, overlong lines, non-existent or inaccessible - files (even if matches were found in other files) or too many matching + 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. @@ -736,5 +737,5 @@ AUTHOR REVISION - Last updated: 13 September 2012 - Copyright (c) 1997-2012 University of Cambridge. + Last updated: 03 April 2014 + Copyright (c) 1997-2014 University of Cambridge. diff --git a/tools/pcre/doc/pcrejit.3 b/tools/pcre/doc/pcrejit.3 index f05ad653..341403f7 100644 --- a/tools/pcre/doc/pcrejit.3 +++ b/tools/pcre/doc/pcrejit.3 @@ -1,4 +1,4 @@ -.TH PCREJIT 3 "31 October 2012" "PCRE 8.32" +.TH PCREJIT 3 "17 March 2013" "PCRE 8.33" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE JUST-IN-TIME COMPILER SUPPORT" @@ -151,15 +151,9 @@ PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NO_UTF32_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. +The only unsupported pattern items are \eC (match a single data unit) when +running in a UTF mode, and a callout immediately before an assertion condition +in a conditional group. . . .SH "RETURN VALUES FROM JIT EXECUTION" @@ -432,6 +426,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 31 October 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 17 March 2013 +Copyright (c) 1997-2013 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcrelimits.3 b/tools/pcre/doc/pcrelimits.3 index 14ffbc46..423d6a27 100644 --- a/tools/pcre/doc/pcrelimits.3 +++ b/tools/pcre/doc/pcrelimits.3 @@ -1,4 +1,4 @@ -.TH PCRELIMITS 3 "24 June 2012" "PCRE 8.30" +.TH PCRELIMITS 3 "05 November 2013" "PCRE 8.34" .SH NAME PCRE - Perl-compatible regular expressions .SH "SIZE AND OTHER LIMITATIONS" @@ -8,9 +8,10 @@ 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, 32-bit units for the 32-bit library, and 32-bit units for -the 32-bit library) if PCRE is compiled with the default internal linkage size -of 2 bytes. If you want to process regular expressions that are truly enormous, +for the 8-bit library, 16-bit units for the 16-bit library, and 32-bit units for +the 32-bit library) if PCRE is compiled with the default internal linkage size, +which is 2 bytes for the 8-bit and 16-bit libraries, and 4 bytes for the 32-bit +library. If you want to process regular expressions that are truly enormous, you can compile PCRE with an internal linkage size of 3 or 4 (when building the 16-bit or 32-bit library, 3 is rounded up to 4). See the \fBREADME\fP file in the source distribution and the @@ -23,7 +24,10 @@ However, the speed of execution is slower. 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. +no more than 65535 capturing subpatterns. There is, however, a limit to the +depth of nesting of parenthesized subpatterns of all kinds. This is imposed in +order to limit the amount of system stack used at compile time. The limit can +be specified when PCRE is built; the default is 250. .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 @@ -34,7 +38,7 @@ 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 and 32-bit library. +is 255 for the 8-bit library and 65535 for the 16-bit and 32-bit libraries. .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 @@ -62,6 +66,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 04 May 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 05 November 2013 +Copyright (c) 1997-2013 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcrematching.3 b/tools/pcre/doc/pcrematching.3 index a9977d5e..268baf9b 100644 --- a/tools/pcre/doc/pcrematching.3 +++ b/tools/pcre/doc/pcrematching.3 @@ -1,4 +1,4 @@ -.TH PCREMATCHING 3 "08 January 2012" "PCRE 8.30" +.TH PCREMATCHING 3 "12 November 2013" "PCRE 8.34" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE MATCHING ALGORITHMS" @@ -106,6 +106,14 @@ the three strings "caterpillar", "cater", and "cat" that start at the fifth character of the subject. The algorithm does not automatically move on to find matches that start at later positions. .P +PCRE's "auto-possessification" optimization usually applies to character +repeats at the end of a pattern (as well as internally). For example, the +pattern "a\ed+" is compiled as if it were "a\ed++" because there is no point +even considering the possibility of backtracking into the repeated digits. For +DFA matching, this means that only one possible match is found. If you really +do want multiple matches in such cases, either use an ungreedy repeat +("a\ed+?") or set the PCRE_NO_AUTO_POSSESS option when compiling. +.P There are a number of features of PCRE regular expressions that are not supported by the alternative matching algorithm. They are as follows: .P @@ -201,6 +209,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 08 January 2012 +Last updated: 12 November 2013 Copyright (c) 1997-2012 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcrepartial.3 b/tools/pcre/doc/pcrepartial.3 index d5cd74e2..14d0124f 100644 --- a/tools/pcre/doc/pcrepartial.3 +++ b/tools/pcre/doc/pcrepartial.3 @@ -1,4 +1,4 @@ -.TH PCREPARTIAL 3 "24 June 2012" "PCRE 8.31" +.TH PCREPARTIAL 3 "02 July 2013" "PCRE 8.34" .SH NAME PCRE - Perl-compatible regular expressions .SH "PARTIAL MATCHING IN PCRE" @@ -56,31 +56,34 @@ strings. This optimization is also disabled for partial matching. .rs .sp A partial match occurs during a call to \fBpcre_exec()\fP or -\fBpcre[16|32]_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. +\fBpcre[16|32]_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. +subject so that a substring can easily be identified. If there are at least +three slots in the offsets vector, the third slot is set to the offset of the +character where matching started. .P -For the majority of patterns, the first offset identifies the start of the -partially matched string. However, for patterns that contain lookbehind -assertions, or \eK, or begin with \eb or \eB, earlier characters have been -inspected while carrying out the match. For example: +For the majority of patterns, the contents of the first and third slots will be +the same. However, for patterns that contain lookbehind assertions, or begin +with \eb or \eB, characters before the one where matching started may have been +inspected while carrying out the match. For example, consider this pattern: .sp /(?<=abc)123/ .sp This pattern matches "123", but only if it is preceded by "abc". If the subject -string is "xyzabc12", the offsets after a partial match are for the substring -"abc12", because all these characters are needed if another match is tried -with extra characters added to the subject. +string is "xyzabc12", the first two offsets after a partial match are for the +substring "abc12", because all these characters were inspected. However, the +third offset is set to 6, because that is the offset where matching began. .P What happens when a partial match is identified depends on which of the two partial matching options are set. @@ -277,6 +280,15 @@ 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. .P +That means that, for an unanchored pattern, if a continued match fails, it is +not possible to try again at a new starting point. All this facility is capable +of doing is continuing with the previous match attempt. In the previous +example, if the second set of data is "ug23" the result is no match, even +though there would be a match for "aug23" if the entire string were given at +once. Depending on the application, this may or may not be what you want. +The only way to allow for starting again at the next character is to retain the +matched part of the subject and try a new complete match. +.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 the DFA matching @@ -308,10 +320,9 @@ 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 includes -characters that precede the partially matched string itself, because these must -be retained when adding on more characters for a subsequent matching attempt. -However, in some cases you may need to retain even earlier characters, as -discussed in the next section. +characters that precede the start of what would be returned for a complete +match, because it contains all the characters that were inspected during the +partial match. . . .SH "ISSUES WITH MULTI-SEGMENT MATCHING" @@ -330,12 +341,32 @@ includes the effect of PCRE_NOTEOL. 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 \fBpcre[16|32]_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.) +\fBpcre_fullinfo()\fP or \fBpcre[16|32]_fullinfo()\fP functions to obtain the +length of the longest lookbehind in the pattern. This length is given in +characters, not bytes. If you always retain at least that many characters +before the partially matched string, all should be well. (Of course, near the +start of the subject, fewer characters may be present; in that case all +characters should be retained.) +.P +From release 8.33, there is a more accurate way of deciding which characters to +retain. Instead of subtracting the length of the longest lookbehind from the +earliest inspected character (\fIoffsets[0]\fP), the match start position +(\fIoffsets[2]\fP) should be used, and the next match attempt started at the +\fIoffsets[2]\fP character by setting the \fIstartoffset\fP argument of +\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. +.P +For example, if the pattern "(?<=123)abc" is partially +matched against the string "xx123a", the three offset values returned are 2, 6, +and 5. This indicates that the matching process that gave a partial match +started at offset 5, but the characters "123a" were all inspected. The maximum +lookbehind for that pattern is 3, so taking that away from 5 shows that we need +only keep "123a", and the next match attempt can be started at offset 3 (that +is, at "a") when further characters have been added. When the match start is +not the earliest inspected character, \fBpcretest\fP shows it explicitly: +.sp + re> "(?<=123)abc" + data> xx123a\eP\eP + Partial match at offset 5: 123a .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 @@ -440,6 +471,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 24 June 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 02 July 2013 +Copyright (c) 1997-2013 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcrepattern.3 b/tools/pcre/doc/pcrepattern.3 index c9c7b45d..f1c45cda 100644 --- a/tools/pcre/doc/pcrepattern.3 +++ b/tools/pcre/doc/pcrepattern.3 @@ -1,4 +1,4 @@ -.TH PCREPATTERN 3 "11 November 2012" "PCRE 8.32" +.TH PCREPATTERN 3 "08 January 2014" "PCRE 8.35" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE REGULAR EXPRESSION DETAILS" @@ -20,6 +20,34 @@ have copious examples. Jeffrey Friedl's "Mastering Regular Expressions", published by O'Reilly, covers regular expressions in great detail. This description of PCRE's regular expressions is intended as reference material. .P +This document discusses the patterns that are supported by PCRE when one its +main matching functions, \fBpcre_exec()\fP (8-bit) or \fBpcre[16|32]_exec()\fP +(16- or 32-bit), is used. PCRE also has alternative matching functions, +\fBpcre_dfa_exec()\fP and \fBpcre[16|32_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 +.\" +page. +. +. +.SH "SPECIAL START-OF-PATTERN ITEMS" +.rs +.sp +A number of options that can be passed to \fBpcre_compile()\fP can also be set +by special items at the start of a pattern. These are not Perl-compatible, but +are provided to make these options accessible to pattern writers who are not +able to change the program that processes the pattern. Any number of these +items may appear, but they must all be together right at the start of the +pattern string, and the letters must be in upper case. +. +. +.SS "UTF support" +.rs +.sp The original operation of PCRE was on strings of one-byte characters. However, there is now also support for UTF-8 strings in the original library, an extra library that supports 16-bit and UTF-16 character strings, and a @@ -36,55 +64,57 @@ these special sequences: .sp (*UTF) is a generic sequence that can be used with any of the libraries. Starting a pattern with such a sequence is equivalent to setting the relevant -option. This feature is not Perl-compatible. How setting a UTF mode affects -pattern matching is mentioned in several places below. There is also a summary -of features in the +option. How setting a UTF mode affects pattern matching is mentioned in several +places below. There is also a summary of features in the .\" HREF \fBpcreunicode\fP .\" page. .P -Another special sequence that may appear at the start of a pattern or in -combination with (*UTF8), (*UTF16), (*UTF32) or (*UTF) is: -.sp - (*UCP) +Some applications that allow their users to supply patterns may wish to +restrict them to non-UTF data for security reasons. If the PCRE_NEVER_UTF +option is set at compile time, (*UTF) etc. are not allowed, and their +appearance causes an error. +. +. +.SS "Unicode property support" +.rs .sp +Another special sequence that may appear at the start of a pattern is (*UCP). This has the same effect as setting the PCRE_UCP option: it causes sequences such as \ed and \ew to use Unicode properties to determine character types, instead of recognizing only characters with codes less than 128 via a lookup table. -.P -If a pattern starts with (*NO_START_OPT), it has the same effect as setting the -PCRE_NO_START_OPTIMIZE option either at compile or matching time. There are -also some more of these special sequences that are concerned with the handling -of newlines; they are described below. -.P -The remainder of this document discusses the patterns that are supported by -PCRE when one its main matching functions, \fBpcre_exec()\fP (8-bit) or -\fBpcre[16|32]_exec()\fP (16- or 32-bit), is used. PCRE also has alternative -matching functions, \fBpcre_dfa_exec()\fP and \fBpcre[16|32_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 -.\" -page. . . -.SH "EBCDIC CHARACTER CODES" +.SS "Disabling auto-possessification" .rs .sp -PCRE can be compiled to run in an environment that uses EBCDIC as its character -code rather than ASCII or Unicode (typically a mainframe system). In the -sections below, character code values are ASCII or Unicode; in an EBCDIC -environment these characters may have different code values, and there are no -code points greater than 255. +If a pattern starts with (*NO_AUTO_POSSESS), it has the same effect as setting +the PCRE_NO_AUTO_POSSESS option at compile time. This stops PCRE from making +quantifiers possessive when what follows cannot match the repeated item. For +example, by default a+b is treated as a++b. For more details, see the +.\" HREF +\fBpcreapi\fP +.\" +documentation. +. +. +.SS "Disabling start-up optimizations" +.rs +.sp +If a pattern starts with (*NO_START_OPT), it has the same effect as setting the +PCRE_NO_START_OPTIMIZE option either at compile or matching time. This disables +several optimizations for quickly reaching "no match" results. For more +details, see the +.\" HREF +\fBpcreapi\fP +.\" +documentation. . . .\" HTML -.SH "NEWLINE CONVENTIONS" +.SS "Newline conventions" .rs .sp PCRE supports five different conventions for indicating line breaks in @@ -117,9 +147,7 @@ example, on a Unix system where LF is the default newline sequence, the pattern (*CR)a.b .sp changes the convention to CR. That pattern matches "a\enb" because LF is no -longer a newline. Note that these special settings, which are not -Perl-compatible, are recognized only at the very start of a pattern, and that -they must be in upper case. If more than one of them is present, the last one +longer a newline. If more than one of these settings is present, the last one is used. .P The newline convention affects where the circumflex and dollar assertions are @@ -136,6 +164,38 @@ below. A change of \eR setting can be combined with a change of newline convention. . . +.SS "Setting match and recursion limits" +.rs +.sp +The caller of \fBpcre_exec()\fP can set a limit on the number of times the +internal \fBmatch()\fP function is called and on the maximum depth of +recursive calls. These facilities are provided to catch runaway matches that +are provoked by patterns with huge matching trees (a typical example is a +pattern with nested unlimited repeats) and to avoid running out of system stack +by too much recursion. When one of these limits is reached, \fBpcre_exec()\fP +gives an error return. The limits can also be set by items at the start of the +pattern of the form +.sp + (*LIMIT_MATCH=d) + (*LIMIT_RECURSION=d) +.sp +where d is any number of decimal digits. However, the value of the setting must +be less than the value set (or defaulted) by the caller of \fBpcre_exec()\fP +for it to have any effect. In other words, the pattern writer can lower the +limits set by the programmer, but not raise them. If there is more than one +setting of one of these limits, the lower value is used. +. +. +.SH "EBCDIC CHARACTER CODES" +.rs +.sp +PCRE can be compiled to run in an environment that uses EBCDIC as its character +code rather than ASCII or Unicode (typically a mainframe system). In the +sections below, character code values are ASCII or Unicode; in an EBCDIC +environment these characters may have different code values, and there are no +code points greater than 255. +. +. .SH "CHARACTERS AND METACHARACTERS" .rs .sp @@ -213,10 +273,11 @@ 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, 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 white space or # character as part of the pattern. +If a pattern is compiled with the PCRE_EXTENDED option, most white space in the +pattern (other than in a character class), and characters between a # outside a +character class and the next newline, inclusive, are ignored. An escaping +backslash can be used to include a white space or # character as part of the +pattern. .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 @@ -256,7 +317,9 @@ one of the following escape sequences than the binary character it represents: \en linefeed (hex 0A) \er carriage return (hex 0D) \et tab (hex 09) + \e0dd character with octal code 0dd \eddd character with octal code ddd, or back reference + \eo{ddd..} character with octal code ddd.. \exhh character with hex code hh \ex{hhh..} character with hex code hhh.. (non-JavaScript mode) \euhhhh character with hex code hhhh (JavaScript mode only) @@ -277,47 +340,27 @@ byte are inverted. Thus \ecA becomes hex 01, as in ASCII (A is C1), but because the EBCDIC letters are disjoint, \ecZ becomes hex 29 (Z is E9), and other characters also generate different values. .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 - 32-bit non-UTF mode less than 0x80000000 - 32-bit UTF-32 mode less than 0x10ffff and a valid codepoint -.sp -Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called -"surrogate" codepoints), and 0xffef. -.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 (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 specifies two binary zeros followed by a BEL character (code value 7). Make sure you supply two digits after the initial zero if the pattern character that follows is itself an octal digit. .P -The handling of a backslash followed by a digit other than 0 is complicated. -Outside a character class, PCRE reads it and any following digits as a decimal -number. If the number is less than 10, or if there have been at least that many +The escape \eo must be followed by a sequence of octal digits, enclosed in +braces. An error occurs if this is not the case. This escape is a recent +addition to Perl; it provides way of specifying character code points as octal +numbers greater than 0777, and it also allows octal numbers and back references +to be unambiguously specified. +.P +For greater clarity and unambiguity, it is best to avoid following \e by a +digit greater than zero. Instead, use \eo{} or \ex{} to specify character +numbers, and \eg{} to specify back references. The following paragraphs +describe the old, ambiguous syntax. +.P +The handling of a backslash followed by a digit other than 0 is complicated, +and Perl has changed in recent releases, causing PCRE also to change. Outside a +character class, PCRE reads the digit and any following digits as a decimal +number. If the number is less than 8, or if there have been at least that many previous capturing left parentheses in the expression, the entire sequence is taken as a \fIback reference\fP. A description of how this works is given .\" HTML @@ -330,12 +373,11 @@ following the discussion of parenthesized subpatterns. .\" .P -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. The value of the character is -constrained in the same way as characters specified in hexadecimal. -For example: +Inside a character class, or if the decimal number following \e is greater than +7 and there have not been that many capturing subpatterns, PCRE handles \e8 and +\e9 as the literal characters "8" and "9", and otherwise re-reads up to three +octal digits following the backslash, using them to generate a data character. +Any subsequent digits stand for themselves. For example: .sp \e040 is another way of writing an ASCII space .\" JOIN @@ -354,12 +396,51 @@ For example: \e377 might be a back reference, otherwise the value 255 (decimal) .\" JOIN - \e81 is either a back reference, or a binary zero - followed by the two characters "8" and "1" + \e81 is either a back reference, or the two + characters "8" and "1" .sp -Note that octal values of 100 or greater must not be introduced by a leading -zero, because no more than three octal digits are ever read. +Note that octal values of 100 or greater that are specified using this syntax +must not be introduced by a leading zero, because no more than three octal +digits are ever read. .P +By default, after \ex that is not followed by {, 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 }. If a character other than +a hexadecimal digit appears between \ex{ and }, or if there is no terminating +}, an error occurs. +.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. +.P +Characters whose value is less than 256 can be defined by either of the two +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). +. +. +.SS "Constraints on character values" +.rs +.sp +Characters that are specified using octal or hexadecimal numbers are +limited to certain values, 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 + 32-bit non-UTF mode less than 0x100000000 + 32-bit UTF-32 mode less than 0x10ffff and a valid codepoint +.sp +Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called +"surrogate" codepoints), and 0xffef. +. +. +.SS "Escape sequences in character classes" +.rs +.sp All the sequences that define a single character value can be used both inside and outside character classes. In addition, inside a character class, \eb is interpreted as the backspace character (hex 08). @@ -450,11 +531,14 @@ classes. They each match one character of the appropriate type. If the current matching point is at the end of the subject string, all of them fail, because there is no character to match. .P -For compatibility with Perl, \es does not match the VT character (code 11). -This makes it different from the the POSIX "space" class. The \es characters -are HT (9), LF (10), FF (12), CR (13), and space (32). If "use locale;" is -included in a Perl script, \es may match the VT character. In PCRE, it never -does. +For compatibility with Perl, \es did not used to match the VT character (code +11), which made it different from the the POSIX "space" class. However, Perl +added VT at release 5.18, and PCRE followed suit at release 8.34. The default +\es characters are now HT (9), LF (10), VT (11), FF (12), CR (13), and space +(32), which are defined as white space in the "C" locale. This list may vary if +locale-specific matching is taking place. For example, in some locales the +"non-breaking space" character (\exA0) is recognized as white space, and in +others the VT character is not. .P A "word" character is an underscore or any character that is a letter or digit. By default, the definition of letters and digits is controlled by PCRE's @@ -469,20 +553,22 @@ in the \fBpcreapi\fP .\" page). For example, in a French locale such as "fr_FR" in Unix-like systems, -or "french" in Windows, some character codes greater than 128 are used for +or "french" in Windows, some character codes greater than 127 are used for accented letters, and these are then matched by \ew. The use of locales with Unicode is discouraged. .P -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 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: +By default, characters whose code points are greater than 127 never match \ed, +\es, or \ew, and always match \eD, \eS, and \eW, although this may vary for +characters in the range 128-255 when locale-specific matching is happening. +These escape sequences retain their original meanings from before Unicode +support was available, mainly for efficiency reasons. 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: .sp - \ed any character that \ep{Nd} matches (decimal digit) - \es any character that \ep{Z} matches, plus HT, LF, FF, CR - \ew any character that \ep{L} or \ep{N} matches, plus underscore + \ed any character that matches \ep{Nd} (decimal digit) + \es any character that matches \ep{Z} or \eh or \ev + \ew any character that matches \ep{L} or \ep{N}, plus underscore .sp The upper case escapes match the inverse sets of characters. Note that \ed matches only decimal digits, whereas \ew matches any Unicode digit, as well as @@ -492,7 +578,7 @@ is noticeably slower when PCRE_UCP is set. .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, +characters by default, these always match certain high-valued code points, whether or not PCRE_UCP is set. The horizontal space characters are: .sp U+0009 Horizontal tab (HT) @@ -802,7 +888,8 @@ Instead, this property is assumed for any code point that is not in the Unicode table. .P Specifying caseless matching does not affect these escape sequences. For -example, \ep{Lu} always matches only upper case letters. +example, \ep{Lu} always matches only upper case letters. This is different from +the behaviour of current versions of Perl. .P Matching characters by Unicode property is not fast, because PCRE has to do a multistage table lookup in order to find a character's property. That is why @@ -861,8 +948,9 @@ the "mark" property always have the "extend" grapheme breaking property. .sp As well as the standard Unicode properties described above, PCRE supports four more that make it possible to convert traditional escape sequences such as \ew -and \es and POSIX character classes to use Unicode properties. PCRE uses these -non-standard, non-Perl properties internally when PCRE_UCP is set. They are: +and \es to use Unicode properties. PCRE uses these non-standard, non-Perl +properties internally when PCRE_UCP is set. However, they may also be used +explicitly. These properties are: .sp Xan Any alphanumeric character Xps Any POSIX space character @@ -872,8 +960,18 @@ non-standard, non-Perl properties internally when PCRE_UCP is set. They are: Xan matches characters that have either the L (letter) or the N (number) 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. +Xsp is the same as Xps; it used to exclude vertical tab, for Perl +compatibility, but Perl changed, and so PCRE followed at release 8.34. Xwd +matches the same characters as Xan, plus underscore. +.P +There is another non-standard property, Xuc, which matches any character that +can be represented by a Universal Character Name in C++ and other programming +languages. These are the characters $, @, ` (grave accent), and all characters +with Unicode code points greater than or equal to U+00A0, except for the +surrogates U+D800 to U+DFFF. Note that most base (ASCII) characters are +excluded. (Universal Character Names are of the form \euHHHH or \eUHHHHHHHH +where H is a hexadecimal digit. Note that the Xuc property does not match these +sequences but the characters that they represent.) . . .\" HTML @@ -906,7 +1004,9 @@ matches "foobar", the first substring is still set to "foo". .P Perl documents that the use of \eK within assertions is "not well defined". In PCRE, \eK is acted upon when it occurs inside positive assertions, but is -ignored in negative assertions. +ignored in negative assertions. Note that when a pattern such as (?=ab\eK) +matches, the reported start of the match can be greater than the end of the +match. . . .\" HTML @@ -1160,7 +1260,9 @@ The minus (hyphen) character can be used to specify a range of characters 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. +indicating a range, typically as the first or last character in the class, or +immediately after a range. For example, [b-d-z] matches letters in the range b +to d, a hyphen character, or z. .P It is not possible to have the literal character "]" as the end character of a range. A pattern such as [W-]46] is interpreted as a class of two characters @@ -1170,6 +1272,11 @@ the end of range, so [W-\e]46] is interpreted 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. .P +An error is generated if a POSIX character class (see below) or an escape +sequence other than one that defines a single character appears at a point +where a range ending character is expected. For example, [z-\exff] is valid, +but [A-\ed] and [A-[:digit:]] are not. +.P Ranges operate in the collating sequence of character values. They can also be used for characters specified numerically, for example [\e000-\e037]. Ranges can include any characters that are valid for the current mode. @@ -1208,9 +1315,9 @@ 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, escaping other non-alphanumeric characters -does no harm. +introducing a POSIX class name, or for a special compatibility feature - see +the next two sections), and the terminating closing square bracket. However, +escaping other non-alphanumeric characters does no harm. . . .SH "POSIX CHARACTER CLASSES" @@ -1235,15 +1342,17 @@ are: lower lower case letters print printing characters, including space punct printing characters, excluding letters and digits and space - space white space (not quite the same as \es) + space white space (the same as \es from PCRE 8.34) upper upper case letters word "word" characters (same as \ew) xdigit hexadecimal digits .sp -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 \es, which does not include VT (for Perl -compatibility). +The default "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), +and space (32). If locale-specific matching is taking place, the list of space +characters may be different; there may be fewer or more of them. "Space" used +to be different to \es, which did not include VT, for Perl compatibility. +However, Perl changed at release 5.18, and PCRE followed at release 8.34. +"Space" and \es now match the same set of characters. .P 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 @@ -1255,11 +1364,11 @@ 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. .P -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 -by other sequences, as follows: +By default, characters with values greater than 128 do not match any of the +POSIX character classes. However, if the PCRE_UCP option is passed to +\fBpcre_compile()\fP, some of the classes are changed so that Unicode character +properties are used. This is achieved by replacing certain POSIX classes by +other sequences, as follows: .sp [:alnum:] becomes \ep{Xan} [:alpha:] becomes \ep{L} @@ -1270,9 +1379,54 @@ by other sequences, as follows: [:upper:] becomes \ep{Lu} [:word:] becomes \ep{Xwd} .sp -Negated versions, such as [:^alpha:] use \eP instead of \ep. The other POSIX -classes are unchanged, and match only characters with code points less than -128. +Negated versions, such as [:^alpha:] use \eP instead of \ep. Three other POSIX +classes are handled specially in UCP mode: +.TP 10 +[:graph:] +This matches characters that have glyphs that mark the page when printed. In +Unicode property terms, it matches all characters with the L, M, N, P, S, or Cf +properties, except for: +.sp + U+061C Arabic Letter Mark + U+180E Mongolian Vowel Separator + U+2066 - U+2069 Various "isolate"s +.sp +.TP 10 +[:print:] +This matches the same characters as [:graph:] plus space characters that are +not controls, that is, characters with the Zs property. +.TP 10 +[:punct:] +This matches all characters that have the Unicode P (punctuation) property, +plus those characters whose code points are less than 128 that have the S +(Symbol) property. +.P +The other POSIX classes are unchanged, and match only characters with code +points less than 128. +. +. +.SH "COMPATIBILITY FEATURE FOR WORD BOUNDARIES" +.rs +.sp +In the POSIX.2 compliant library that was included in 4.4BSD Unix, the ugly +syntax [[:<:]] and [[:>:]] is used for matching "start of word" and "end of +word". PCRE treats these items as follows: +.sp + [[:<:]] is converted to \eb(?=\ew) + [[:>:]] is converted to \eb(?<=\ew) +.sp +Only these exact character sequences are recognized. A sequence such as +[a[:<:]b] provokes error for an unrecognized POSIX class name. This support is +not compatible with Perl. It is provided to help migrations from other +environments, and is best not used in any new patterns. Note that \eb matches +at the start and the end of a word (see +.\" HTML +.\" +"Simple assertions" +.\" +above), and in a Perl-style pattern the preceding or following character +normally shows which is wanted, without the need for the assertions that are +used above in order to give exactly the POSIX behaviour. . . .SH "VERTICAL BAR" @@ -1355,7 +1509,8 @@ above. There are also the (*UTF8), (*UTF16),(*UTF32), 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, PCRE_UTF32 and the PCRE_UCP options, respectively. The (*UTF) sequence is a generic version that can be -used with any of the libraries. +used with any of the libraries. However, the application can set the +PCRE_NEVER_UTF option, which locks out the use of the (*UTF) sequences. . . .\" HTML @@ -1491,11 +1646,12 @@ conditions, .\" can be made by name as well as by number. .P -Names consist of up to 32 alphanumeric characters and underscores. Named -capturing parentheses are still allocated numbers as well as names, exactly as -if the names were not present. The PCRE API provides function calls for -extracting the name-to-number translation table from a compiled pattern. There -is also a convenience function for extracting a captured substring by name. +Names consist of up to 32 alphanumeric characters and underscores, but must +start with a non-digit. Named capturing parentheses are still allocated numbers +as well as names, exactly as if the names were not present. The PCRE API +provides function calls for extracting the name-to-number translation table +from a compiled pattern. There is also a convenience function for extracting a +captured substring by name. .P 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 @@ -1521,9 +1677,20 @@ 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. .P If you make a back reference to a non-unique named subpattern from elsewhere in -the pattern, the one that corresponds to the first occurrence of the name is -used. In the absence of duplicate numbers (see the previous section) this is -the one with the lowest number. If you use a named reference in a condition +the pattern, the subpatterns to which the name refers are checked in the order +in which they appear in the overall pattern. The first one that is set is used +for the reference. For example, this pattern matches both "foofoo" and +"barbar" but not "foobar" or "barfoo": +.sp + (?:(?foo)|(?bar))\ek +.sp +.P +If you make a subroutine call to a non-unique named subpattern, the one that +corresponds to the first occurrence of the name is used. In the absence of +duplicate numbers (see the previous section) this is the one with the lowest +number. +.P +If you use a named reference in a condition test (see the .\" .\" HTML @@ -1543,8 +1710,9 @@ documentation. \fBWarning:\fP You cannot use different names to distinguish between two subpatterns with the same number because PCRE uses only the numbers when matching. For this reason, an error is given at compile time if different 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. +are given to subpatterns with the same number. However, you can always give the +same name to subpatterns with the same number, even when PCRE_DUPNAMES is not +set. . . .SH REPETITION @@ -1964,8 +2132,8 @@ except that it does not cause the current matching position to be changed. 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. +capturing is carried out only for positive assertions. (Perl sometimes, but not +always, does do capturing in 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 @@ -2215,12 +2383,7 @@ This makes the fragment independent of the parentheses in the larger pattern. .sp 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 syntax, 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 number, which must be greater than zero. Using subpattern -names that consist entirely of digits is not recommended. +this facility before Perl, the syntax (?(name)...) is also recognized. .P Rewriting the above example to use a named subpattern gives this: .sp @@ -2629,14 +2792,26 @@ For example, this pattern has two callout points: .sp 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. +255. If there is a conditional group in the pattern whose condition is an +assertion, an additional callout is inserted just before the condition. An +explicit callout may also be set at this position, as in this example: +.sp + (?(?C9)(?=a)abc|def) +.sp +Note that this applies only to assertion conditions, not to other types of +condition. .P 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 +backtrack, or to fail altogether. +.P +By default, PCRE implements a number of optimizations at compile time and +matching time, and one side-effect is that sometimes callouts are skipped. If +you need all possible callouts to happen, you need to set options that disable +the relevant optimizations. More details, and a complete description of the +interface to the callout function, are given in the .\" HREF \fBpcrecallout\fP .\" @@ -2648,35 +2823,43 @@ documentation. .rs .sp Perl 5.10 introduced a number of "Special Backtracking Control Verbs", which -are described in the Perl documentation as "experimental and subject to change -or removal in a future version of Perl". It goes on to say: "Their usage in -production code should be noted to avoid problems during upgrades." The same +are still described in the Perl documentation as "experimental and subject to +change or removal in a future version of Perl". It goes on to say: "Their usage +in production code should be noted to avoid problems during upgrades." The same remarks apply to the PCRE features described in this section. .P -Since these verbs are specifically related to backtracking, most of them can be -used only when the pattern is to be matched using one of the traditional -matching functions, which use a backtracking algorithm. With the exception of -(*FAIL), which behaves like a failing negative assertion, they cause an error -if encountered by a DFA matching 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. A name is any sequence of -characters that does not include a closing parenthesis. The maximum length of -name is 255 in the 8-bit library and 65535 in the 16-bit and 32-bit library. -If the name is empty, that is, if the 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, possibly behaving +differently depending on whether or not a name is present. A name is any +sequence of characters that does not include a closing parenthesis. The maximum +length of name is 255 in the 8-bit library and 65535 in the 16-bit and 32-bit +libraries. If the name is empty, that is, if the closing parenthesis +immediately follows the colon, the effect is as if the colon were not there. +Any number of these verbs may occur in a pattern. +.P +Since these verbs are specifically related to backtracking, most of them can be +used only when the pattern is to be matched using one of the traditional +matching functions, because these use a backtracking algorithm. With the +exception of (*FAIL), which behaves like a failing negative assertion, the +backtracking control verbs cause an error if encountered by a DFA matching +function. +.P +The behaviour of these verbs in +.\" HTML +.\" +repeated groups, +.\" +.\" HTML +.\" +assertions, +.\" +and in +.\" HTML +.\" +subpatterns called as subroutines +.\" +(whether or not recursively) is documented below. . . .\" HTML @@ -2686,7 +2869,7 @@ verbs may occur in a pattern. PCRE contains some optimizations that are used to speed up matching by running some checks at the start of each match attempt. For example, it may know the minimum length of matching subject, or that a particular character must be -present. When one of these optimizations suppresses the running of a match, any +present. When one of these optimizations bypasses the running of a match, any included backtracking verbs will not, of course, be processed. You can suppress the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option when calling \fBpcre_compile()\fP or \fBpcre_exec()\fP, or by starting the @@ -2717,8 +2900,11 @@ followed by a name. 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: +at the outer level. If (*ACCEPT) in triggered in a positive assertion, the +assertion succeeds; in a negative assertion, the assertion fails. +.P +If (*ACCEPT) is inside capturing parentheses, the data so far is captured. For +example: .sp A((?:A|B(*ACCEPT)|C)D) .sp @@ -2751,8 +2937,9 @@ starting point (see (*SKIP) below). 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) on the matching -path is passed back to the caller as described in the section entitled +When a match succeeds, the name of the last-encountered (*MARK:NAME), +(*PRUNE:NAME), or (*THEN:NAME) on the matching path is passed back to the +caller as described in the section entitled .\" HTML .\" "Extra data for \fBpcre_exec()\fP" @@ -2777,12 +2964,12 @@ indicates which of the two alternatives matched. This is a more efficient way of obtaining this information than putting each alternative in its own capturing parentheses. .P -If (*MARK) is encountered in a positive assertion, its name is recorded and -passed back if it is the last-encountered. This does not happen for negative -assertions. +If a verb with a name is encountered in a positive assertion that is true, the +name is recorded and passed back if it is the last-encountered. This does not +happen for negative assertions or failing positive 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: +After a partial match or a failed match, the last encountered name in the +entire match process is returned. For example: .sp re> /X(*MARK:A)Y|X(*MARK:B)Z/K data> XP @@ -2808,22 +2995,27 @@ to ensure that the match is always attempted. The following verbs do nothing when they are encountered. Matching continues 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 backtracking 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.) +the verb. However, when one of these verbs appears inside an atomic group or an +assertion that is true, its effect is confined to that group, because once the +group has been matched, there is never any backtracking into it. In this +situation, backtracking can "jump back" to the left of the entire atomic group +or assertion. (Remember also, as stated above, that this localization also +applies in subroutine calls.) .P These verbs differ in exactly what kind of failure occurs when backtracking -reaches them. +reaches them. The behaviour described below is what happens when the verb is +not in a subroutine or an assertion. Subsequent sections cover these special +cases. .sp (*COMMIT) .sp 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, \fBpcre_exec()\fP is committed to -finding a match at the current starting point, or not at all. For example: +outright if there is a later matching failure that causes backtracking to reach +it. Even if the pattern is unanchored, no further attempts to find a match by +advancing the starting point take place. If (*COMMIT) is the only backtracking +verb that is encountered, once it has been passed \fBpcre_exec()\fP is +committed to finding a match at the current starting point, or not at all. For +example: .sp a+(*COMMIT)b .sp @@ -2832,34 +3024,45 @@ 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) forces a match failure. .P +If there is more than one backtracking verb in a pattern, a different one that +follows (*COMMIT) may be triggered first, so merely passing (*COMMIT) during a +match does not always guarantee that a match must be at this starting point. +.P 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 -\fBpcretest\fP example: +output from \fBpcretest\fP: .sp re> /(*COMMIT)abc/ data> xyzabc 0: abc - xyzabc\eY + data> xyzabc\eY No match .sp -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 \eY escape in the second subject, the match -starts at "x" and so the (*COMMIT) causes it to fail without trying any other -starting points. +For this pattern, PCRE knows that any match must start with "a", so the +optimization skips along the subject to "a" before applying the pattern to the +first set of data. The match attempt then succeeds. In the second set of data, +the escape sequence \eY is interpreted by the \fBpcretest\fP program. It causes +the PCRE_NO_START_OPTIMIZE option to be set when \fBpcre_exec()\fP is called. +This disables the optimization that skips along to the first character. The +pattern is now applied starting at "x", and so the (*COMMIT) causes the match +to fail without trying any other starting points. .sp (*PRUNE) or (*PRUNE:NAME) .sp 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 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). In an -anchored pattern (*PRUNE) has the same effect as (*COMMIT). +subject if there is a later matching failure that causes backtracking to reach +it. If the pattern is unanchored, the normal "bumpalong" advance to the next +starting character then happens. Backtracking can occur as usual to the left of +(*PRUNE), before it is reached, or when matching to the right of (*PRUNE), but +if there is no match to the right, backtracking cannot cross (*PRUNE). In +simple cases, the use of (*PRUNE) is just an alternative to an atomic group or +possessive quantifier, but there are some uses of (*PRUNE) that cannot be +expressed in any other way. In an anchored pattern (*PRUNE) has the same effect +as (*COMMIT). +.P +The behaviour of (*PRUNE:NAME) is the not the same as (*MARK:NAME)(*PRUNE). +It is like (*MARK:NAME) in that the name is remembered for passing back to the +caller. However, (*SKIP:NAME) searches only for names set with (*MARK). .sp (*SKIP) .sp @@ -2880,30 +3083,38 @@ instead of skipping on to "c". .sp (*SKIP:NAME) .sp -When (*SKIP) has an associated name, its behaviour is modified. If the -following pattern fails to match, the previous path through the pattern is -searched for the most recent (*MARK) that has the same name. If one is found, -the "bumpalong" advance is to the subject position that corresponds to that -(*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a -matching name is found, the (*SKIP) is ignored. +When (*SKIP) has an associated name, its behaviour is modified. When it is +triggered, the previous path through the pattern is searched for the most +recent (*MARK) that has the same name. If one is found, the "bumpalong" advance +is to the subject position that corresponds to that (*MARK) instead of to where +(*SKIP) was encountered. If no (*MARK) with a matching name is found, the +(*SKIP) is ignored. +.P +Note that (*SKIP:NAME) searches only for names set by (*MARK:NAME). It ignores +names that are set by (*PRUNE:NAME) or (*THEN:NAME). .sp (*THEN) or (*THEN:NAME) .sp -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: +This verb causes a skip to the next innermost alternative when backtracking +reaches it. That is, it cancels any further backtracking within the current +alternative. Its name comes from the observation that it can be used for a +pattern-based if-then-else block: .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 -second alternative and tries COND2, without backtracking into COND1. The -behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN). -If (*THEN) is not inside an alternation, it acts like (*PRUNE). +second alternative and tries COND2, without backtracking into COND1. If that +succeeds and BAR fails, COND3 is tried. If subsequently BAZ fails, there are no +more alternatives, so there is a backtrack to whatever came before the entire +group. If (*THEN) is not inside an alternation, it acts like (*PRUNE). .P -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 +The behaviour of (*THEN:NAME) is the not the same as (*MARK:NAME)(*THEN). +It is like (*MARK:NAME) in that the name is remembered for passing back to the +caller. However, (*SKIP:NAME) searches only for names set with (*MARK). +.P +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: @@ -2922,7 +3133,7 @@ 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 +Note that a conditional subpattern is not considered as having two alternatives, because only one is ever used. In other words, the | character in a conditional subpattern has a different meaning. Ignoring white space, consider: @@ -2944,17 +3155,88 @@ 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. +. +. +.SS "More than one backtracking verb" +.rs +.sp +If more than one backtracking verb is present in a pattern, the one that is +backtracked onto first acts. For example, consider this pattern, where A, B, +etc. are complex pattern fragments: +.sp + (A(*COMMIT)B(*THEN)C|ABD) +.sp +If A matches but B fails, the backtrack to (*COMMIT) causes the entire match to +fail. However, if A and B match, but C fails, the backtrack to (*THEN) causes +the next alternative (ABD) to be tried. This behaviour is consistent, but is +not always the same as Perl's. It means that if two or more backtracking verbs +appear in succession, all the the last of them has no effect. Consider this +example: +.sp + ...(*COMMIT)(*PRUNE)... +.sp +If there is a matching failure to the right, backtracking onto (*PRUNE) causes +it to be triggered, and its action is taken. There can never be a backtrack +onto (*COMMIT). +. +. +.\" HTML +.SS "Backtracking verbs in repeated groups" +.rs +.sp +PCRE differs from Perl in its handling of backtracking verbs in repeated +groups. For example, consider: +.sp + /(a(*COMMIT)b)+ac/ +.sp +If the subject is "abac", Perl matches, but PCRE fails because the (*COMMIT) in +the second repeat of the group acts. +. +. +.\" HTML +.SS "Backtracking verbs in assertions" +.rs +.sp +(*FAIL) in an assertion has its normal effect: it forces an immediate backtrack. .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: +(*ACCEPT) in a positive assertion causes the assertion to succeed without any +further processing. In a negative assertion, (*ACCEPT) causes the assertion to +fail without any further processing. +.P +The other backtracking verbs are not treated specially if they appear in a +positive assertion. In particular, (*THEN) skips to the next alternative in the +innermost enclosing group that has alternations, whether or not this is within +the assertion. +.P +Negative assertions are, however, different, in order to ensure that changing a +positive assertion into a negative assertion changes its result. Backtracking +into (*COMMIT), (*SKIP), or (*PRUNE) causes a negative assertion to be true, +without considering any further alternative branches in the assertion. +Backtracking into (*THEN) causes it to skip to the next enclosing alternative +within the assertion (the normal behaviour), but if the assertion does not have +such an alternative, (*THEN) behaves like (*PRUNE). +. +. +.\" HTML +.SS "Backtracking verbs in subroutines" +.rs .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 alternative (that is, D) does not happen because (*COMMIT) -overrides. +These behaviours occur whether or not the subpattern is called recursively. +Perl's treatment of subroutines is different in some cases. +.P +(*FAIL) in a subpattern called as a subroutine has its normal effect: it forces +an immediate backtrack. +.P +(*ACCEPT) in a subpattern called as a subroutine causes the subroutine match to +succeed without any further processing. Matching then continues after the +subroutine call. +.P +(*COMMIT), (*SKIP), and (*PRUNE) in a subpattern called as a subroutine cause +the subroutine match to fail. +.P +(*THEN) skips to the next alternative in the innermost enclosing group within +the subpattern that has alternatives. If there is no such group within the +subpattern, (*THEN) causes the subroutine match to fail. . . .SH "SEE ALSO" @@ -2978,6 +3260,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 11 November 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 08 January 2014 +Copyright (c) 1997-2014 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcreposix.3 b/tools/pcre/doc/pcreposix.3 index b25a8919..77890f36 100644 --- a/tools/pcre/doc/pcreposix.3 +++ b/tools/pcre/doc/pcreposix.3 @@ -1,25 +1,22 @@ .TH PCREPOSIX 3 "09 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions. -.SH "SYNOPSIS OF POSIX API" +.SH "SYNOPSIS" .rs .sp .B #include .PP -.SM +.nf .B int regcomp(regex_t *\fIpreg\fP, const char *\fIpattern\fP, -.ti +5n -.B int \fIcflags\fP); -.PP +.B " int \fIcflags\fP);" +.sp .B int regexec(regex_t *\fIpreg\fP, const char *\fIstring\fP, -.ti +5n -.B size_t \fInmatch\fP, regmatch_t \fIpmatch\fP[], int \fIeflags\fP); -.PP -.B size_t regerror(int \fIerrcode\fP, const regex_t *\fIpreg\fP, -.ti +5n -.B char *\fIerrbuf\fP, size_t \fIerrbuf_size\fP); -.PP +.B " size_t \fInmatch\fP, regmatch_t \fIpmatch\fP[], int \fIeflags\fP);" +.B " size_t regerror(int \fIerrcode\fP, const regex_t *\fIpreg\fP," +.B " char *\fIerrbuf\fP, size_t \fIerrbuf_size\fP);" +.sp .B void regfree(regex_t *\fIpreg\fP); +.fi . .SH DESCRIPTION .rs diff --git a/tools/pcre/doc/pcreprecompile.3 b/tools/pcre/doc/pcreprecompile.3 index 39eb82b0..40f257a9 100644 --- a/tools/pcre/doc/pcreprecompile.3 +++ b/tools/pcre/doc/pcreprecompile.3 @@ -1,4 +1,4 @@ -.TH PCREPRECOMPILE 3 "24 June 2012" "PCRE 8.30" +.TH PCREPRECOMPILE 3 "12 November 2013" "PCRE 8.34" .SH NAME PCRE - Perl-compatible regular expressions .SH "SAVING AND RE-USING PRECOMPILED PCRE PATTERNS" @@ -90,8 +90,8 @@ study data. .rs .sp Re-using a precompiled pattern is straightforward. Having reloaded it into main -memory, called \fBpcre[16|32]_pattern_to_host_byte_order()\fP if necessary, -you pass its pointer to \fBpcre[16|32]_exec()\fP or \fBpcre[16|32]_dfa_exec()\fP in +memory, called \fBpcre[16|32]_pattern_to_host_byte_order()\fP if necessary, you +pass its pointer to \fBpcre[16|32]_exec()\fP or \fBpcre[16|32]_dfa_exec()\fP in the usual way. .P However, if you passed a pointer to custom character tables when the pattern @@ -110,15 +110,19 @@ in the .\" documentation. .P +\fBWarning:\fP The tables that \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP use +must be the same as those that were used when the pattern was compiled. If this +is not the case, the behaviour is undefined. +.P If you did not provide custom character tables when the pattern was compiled, the pointer in the compiled pattern is NULL, which causes the matching functions to use PCRE's internal tables. Thus, you do not need 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[16|32]_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[16|32]_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[16|32]_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. @@ -146,6 +150,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 24 June 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 12 November 2013 +Copyright (c) 1997-2013 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcresyntax.3 b/tools/pcre/doc/pcresyntax.3 index 868f427d..fd878da4 100644 --- a/tools/pcre/doc/pcresyntax.3 +++ b/tools/pcre/doc/pcresyntax.3 @@ -1,4 +1,4 @@ -.TH PCRESYNTAX 3 "11 November 2012" "PCRE 8.32" +.TH PCRESYNTAX 3 "08 January 2014" "PCRE 8.35" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE REGULAR EXPRESSION SYNTAX SUMMARY" @@ -29,9 +29,14 @@ documentation. This document contains a quick-reference summary of the syntax. \en newline (hex 0A) \er carriage return (hex 0D) \et tab (hex 09) + \e0dd character with octal code 0dd \eddd character with octal code ddd, or backreference + \eo{ddd..} character with octal code ddd.. \exhh character with hex code hh \ex{hhh..} character with hex code hhh.. +.sp +Note that \e0dd is always an octal code, and that \e8 and \e9 are the literal +characters "8" and "9". . . .SH "CHARACTER TYPES" @@ -56,9 +61,11 @@ documentation. This document contains a quick-reference summary of the syntax. \eW a "non-word" character \eX a Unicode extended grapheme cluster .sp -In PCRE, by default, \ed, \eD, \es, \eS, \ew, and \eW recognize only ASCII -characters, even in a UTF mode. However, this can be changed by setting the -PCRE_UCP option. +By default, \ed, \es, and \ew match only ASCII characters, even in UTF-8 mode +or in the 16- bit and 32-bit libraries. However, if locale-specific matching is +happening, \es and \ew may also match characters with code points in the range +128-255. If the PCRE_UCP option is set, the behaviour of these escape sequences +is changed to use Unicode properties and they match many more characters. . . .SH "GENERAL CATEGORY PROPERTIES FOR \ep and \eP" @@ -115,8 +122,13 @@ PCRE_UCP option. .sp Xan Alphanumeric: union of properties L and N Xps POSIX space: property Z or tab, NL, VT, FF, CR - Xsp Perl space: property Z or tab, NL, FF, CR + Xsp Perl space: property Z or tab, NL, VT, FF, CR + Xuc Univerally-named character: one that can be + represented by a Universal Character Name Xwd Perl word: property Xan or underscore +.sp +Perl and POSIX space are now the same. Perl added VT to its space character set +at release 5.18 and PCRE changed at release 8.34. . . .SH "SCRIPT NAMES FOR \ep AND \eP" @@ -297,6 +309,8 @@ but some of them use Unicode properties if PCRE_UCP is set. You can use .rs .sp \eK reset start of match +.sp +\eK is honoured in positive assertions, but ignored in negative ones. . . .SH "ALTERNATION" @@ -342,15 +356,45 @@ but some of them use Unicode properties if PCRE_UCP is set. You can use (?x) extended (ignore white space) (?-...) unset option(s) .sp -The following are recognized only at the start of a pattern or after one of the -newline-setting options with similar syntax: +The following are recognized only at the very start of a pattern or after one +of the newline or \eR options with similar syntax. More than one of them may +appear. .sp + (*LIMIT_MATCH=d) set the match limit to d (decimal number) + (*LIMIT_RECURSION=d) set the recursion limit to d (decimal number) + (*NO_AUTO_POSSESS) no auto-possessification (PCRE_NO_AUTO_POSSESS) (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE) (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8) (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16) (*UTF32) set UTF-32 mode: 32-bit library (PCRE_UTF32) (*UTF) set appropriate UTF mode for the library in use (*UCP) set PCRE_UCP (use Unicode properties for \ed etc) +.sp +Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value of the +limits set by the caller of pcre_exec(), not increase them. +. +. +.SH "NEWLINE CONVENTION" +.rs +.sp +These are recognized only at the very start of the pattern or after option +settings with a similar syntax. +.sp + (*CR) carriage return only + (*LF) linefeed only + (*CRLF) carriage return followed by linefeed + (*ANYCRLF) all three of the above + (*ANY) any Unicode newline sequence +. +. +.SH "WHAT \eR MATCHES" +.rs +.sp +These are recognized only at the very start of the pattern or after option +setting with a similar syntax. +.sp + (*BSR_ANYCRLF) CR, LF, or CRLF + (*BSR_UNICODE) any Unicode newline sequence . . .SH "LOOKAHEAD AND LOOKBEHIND ASSERTIONS" @@ -440,29 +484,6 @@ pattern is not anchored. (*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_...), (*UTF8), (*UTF16), (*UTF32) or (*UCP) option. -.sp - (*CR) carriage return only - (*LF) linefeed only - (*CRLF) carriage return followed by linefeed - (*ANYCRLF) all three of the above - (*ANY) any Unicode newline sequence -. -. -.SH "WHAT \eR MATCHES" -.rs -.sp -These are recognized only at the very start of the pattern or after a -(*...) 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 -. -. .SH "CALLOUTS" .rs .sp @@ -491,6 +512,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 11 November 2012 -Copyright (c) 1997-2012 University of Cambridge. +Last updated: 08 January 2014 +Copyright (c) 1997-2014 University of Cambridge. .fi diff --git a/tools/pcre/doc/pcretest.1 b/tools/pcre/doc/pcretest.1 index 41ef6ac2..92640da8 100644 --- a/tools/pcre/doc/pcretest.1 +++ b/tools/pcre/doc/pcretest.1 @@ -1,4 +1,4 @@ -.TH PCRETEST 1 "10 September 2012" "PCRE 8.32" +.TH PCRETEST 1 "09 February 2014" "PCRE 8.35" .SH NAME pcretest - a program for testing Perl-compatible regular expressions. .SH SYNOPSIS @@ -40,23 +40,34 @@ PCRE, and are unlikely to be of use otherwise. They are all documented here, but without much justification. . . +.SH "INPUT DATA FORMAT" +.rs +.sp +Input to \fBpcretest\fP is processed line by line, either by calling the C +library's \fBfgets()\fP function, or via the \fBlibreadline\fP library (see +below). In Unix-like environments, \fBfgets()\fP treats any bytes other than +newline as data characters. However, in some Windows environments character 26 +(hex 1A) causes an immediate end of file, and no further data is read. For +maximum portability, therefore, it is safest to use only ASCII characters in +\fBpcretest\fP input files. +. +. .SH "PCRE's 8-BIT, 16-BIT AND 32-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. From release 8.32, a third -library can be built, supporting character strings encoded in 32-bit units. -The \fBpcretest\fP program can be -used to test all three libraries. However, it is itself still an 8-bit program, -reading 8-bit input and writing 8-bit output. When testing the 16-bit or 32-bit -library, the patterns and data strings are converted to 16- or 32-bit format -before being passed to the PCRE library functions. Results are converted to -8-bit for output. +character strings encoded in 16-bit units. From release 8.32, a third library +can be built, supporting character strings encoded in 32-bit units. The +\fBpcretest\fP program can be used to test all three libraries. However, it is +itself still an 8-bit program, reading 8-bit input and writing 8-bit output. +When testing the 16-bit or 32-bit library, the patterns and data strings are +converted to 16- or 32-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|32]_xx\fP below -mean "\fBpcre_xx\fP when using the 8-bit library or \fBpcre16_xx\fP when using -the 16-bit library". +mean "\fBpcre_xx\fP when using the 8-bit library, \fBpcre16_xx\fP when using +the 16-bit library, or \fBpcre32_xx\fP when using the 32-bit library". . . .SH "COMMAND LINE OPTIONS" @@ -85,22 +96,29 @@ 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. All other options -are ignored. +about the optional features that are included, and then exit with zero exit +code. 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: +following options output the value and set the exit code as indicated: .sp ebcdic-nl the code for LF (= NL) in an EBCDIC environment: 0x15 or 0x25 0 if used in an ASCII environment - linksize the internal link size (2, 3, or 4) + exit code is always 0 + linksize the configured internal link size (2, 3, or 4) + exit code is set to the link size newline the default newline setting: CR, LF, CRLF, ANYCRLF, or ANY + exit code is always 0 + bsr the default setting for what \eR matches: + ANYCRLF or ANY + exit code is always 0 .sp -The following options output 1 for true or zero for false: +The following options output 1 for true or 0 for false, and set the exit code +to the same value: .sp ebcdic compiled for an EBCDIC environment jit just-in-time support is available @@ -108,7 +126,10 @@ The following options output 1 for true or zero for false: pcre32 the 32-bit library was built pcre8 the 8-bit library was built ucp Unicode property support is available - utf UTF-8 and/or UTF-16 and/or UTF-32 support is available + utf UTF-8 and/or UTF-16 and/or UTF-32 support + is available +.sp +If an unknown option is given, an error message is output; the exit code is 0. .TP 10 \fB-d\fP Behave as if each pattern has the \fB/D\fP (debug) modifier; the internal @@ -137,6 +158,10 @@ Output the size of each compiled pattern after it has been compiled. This is equivalent to adding \fB/M\fP to each regular expression. The size is given in bytes for both libraries. .TP 10 +\fB-O\fP +Behave as if each pattern has the \fB/O\fP modifier, that is disable +auto-possessification for all patterns. +.TP 10 \fB-o\fP \fIosize\fP Set the number of elements in the output vector that is used when calling \fBpcre[16|32]_exec()\fP or \fBpcre[16|32]_dfa_exec()\fP to be \fIosize\fP. The @@ -198,17 +223,21 @@ contains (*MARK) items there may also be differences, for the same reason. The 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 -\fB-t\fP, because you will then get the size output a zillion times, and the -timing will be distorted. You can control the number of iterations that are -used for timing by following \fB-t\fP with a number (as a separate item on the -command line). For example, "-t 1000" would iterate 1000 times. The default is -to iterate 500000 times. +Run each compile, study, and match many times with a timer, and output the +resulting times per compile, study, or match (in milliseconds). Do not set +\fB-m\fP with \fB-t\fP, because you will then get the size output a zillion +times, and the timing will be distorted. You can control the number of +iterations that are used for timing by following \fB-t\fP with a number (as a +separate item on the command line). For example, "-t 1000" iterates 1000 times. +The default is to iterate 500000 times. .TP 10 \fB-tm\fP This is like \fB-t\fP except that it times only the matching phase, not the compile or study phases. +.TP 10 +\fB-T\fP \fB-TM\fP +These behave like \fB-t\fP and \fB-tm\fP, but in addition, at the end of a run, +the total times for all compiles, studies, and matches are output. . . .SH DESCRIPTION @@ -228,7 +257,7 @@ option states whether or not \fBreadline()\fP will be used. .P The program handles any number of sets of input on a single input file. Each set starts with a regular expression, and continues with any number of data -lines to be matched against the pattern. +lines to be matched against that pattern. .P Each data line is matched separately and independently. If you want to do multi-line matches, you have to use the \en escape sequence (or \er or \er\en, @@ -280,6 +309,7 @@ fall into several groups that are described in detail in the following sections. .sp \fB/8\fP set UTF mode + \fB/9\fP set PCRE_NEVER_UTF (locks out UTF mode) \fB/?\fP disable UTF validity check \fB/+\fP show remainder of subject after match \fB/=\fP show all captures (not just those that are set) @@ -301,7 +331,9 @@ sections. \fB/M\fP show compiled memory size \fB/m\fP set PCRE_MULTILINE \fB/N\fP set PCRE_NO_AUTO_CAPTURE + \fB/O\fP set PCRE_NO_AUTO_POSSESS \fB/P\fP use the POSIX wrapper + \fB/Q\fP test external stack check function \fB/S\fP study the pattern after compilation \fB/s\fP set PCRE_DOTALL \fB/T\fP select character tables @@ -350,12 +382,14 @@ options that do not correspond to anything in Perl: \fB/8\fP PCRE_UTF32 ) when using the 32-bit \fB/?\fP PCRE_NO_UTF32_CHECK ) library .sp + \fB/9\fP PCRE_NEVER_UTF \fB/A\fP PCRE_ANCHORED \fB/C\fP PCRE_AUTO_CALLOUT \fB/E\fP PCRE_DOLLAR_ENDONLY \fB/f\fP PCRE_FIRSTLINE \fB/J\fP PCRE_DUPNAMES \fB/N\fP PCRE_NO_AUTO_CAPTURE + \fB/O\fP PCRE_NO_AUTO_POSSESS \fB/U\fP PCRE_UNGREEDY \fB/W\fP PCRE_UCP \fB/X\fP PCRE_EXTRA @@ -453,7 +487,10 @@ below. 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[16|32]_fullinfo()\fP after compiling a -pattern. If the pattern is studied, the results of that are also output. +pattern. If the pattern is studied, the results of that are also output. In +this output, the word "char" means a non-UTF character, that is, the value of a +single data item (8-bit, 16-bit, or 32-bit, depending on the library that is +being tested). .P The \fB/K\fP modifier requests \fBpcretest\fP to show names from backtracking control verbs that are returned from calls to \fBpcre[16|32]_exec()\fP. It causes @@ -483,13 +520,22 @@ the compiled pattern to be output. This does not include the size of the successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the JIT compiled code is also output. .P +The \fB/Q\fP modifier is used to test the use of \fBpcre_stack_guard\fP. It +must be followed by '0' or '1', specifying the return code to be given from an +external function that is passed to PCRE and used for stack checking during +compilation (see the +.\" HREF +\fBpcreapi\fP +.\" +documentation for details). +.P The \fB/S\fP modifier causes \fBpcre[16|32]_study()\fP to be called after the expression has been compiled, and the results used when the expression is matched. There are a number of qualifying characters that may follow \fB/S\fP. They may appear in any order. .P -If \fBS\fP is followed by an exclamation mark, \fBpcre[16|32]_study()\fP is called -with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a +If \fB/S\fP is followed by an exclamation mark, \fBpcre[16|32]_study()\fP is +called with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a \fBpcre_extra\fP block, even when studying discovers no useful information. .P If \fB/S\fP is followed by a second S character, it suppresses studying, even @@ -565,6 +611,37 @@ The \fB/+\fP modifier works as described above. All other modifiers are ignored. . . +.SS "Locking out certain modifiers" +.rs +.sp +PCRE can be compiled with or without support for certain features such as +UTF-8/16/32 or Unicode properties. Accordingly, the standard tests are split up +into a number of different files that are selected for running depending on +which features are available. When updating the tests, it is all too easy to +put a new test into the wrong file by mistake; for example, to put a test that +requires UTF support into a file that is used when it is not available. To help +detect such mistakes as early as possible, there is a facility for locking out +specific modifiers. If an input line for \fBpcretest\fP starts with the string +"< forbid " the following sequence of characters is taken as a list of +forbidden modifiers. For example, in the test files that must not use UTF or +Unicode property support, this line appears: +.sp + < forbid 8W +.sp +This locks out the /8 and /W modifiers. An immediate error is given if they are +subsequently encountered. If the character string contains < but not >, all the +multi-character modifiers that begin with < are locked out. Otherwise, such +modifiers must be explicitly listed, for example: +.sp + < forbid +.sp +There must be a single space between < and "forbid" for this feature to be +recognised. If there is not, the line is interpreted either as a request to +re-load a pre-compiled pattern (see "SAVING AND RELOADING COMPILED PATTERNS" +below) or, if there is a another < character, as a pattern that uses < as its +delimiter. +. +. .SH "DATA LINES" .rs .sp @@ -588,6 +665,7 @@ recognized: \ev vertical tab (\ex0b) \ennn octal character (up to 3 octal digits); always a byte unless > 255 in UTF-8 or 16-bit or 32-bit mode + \eo{dd...} octal character (any number of octal digits} \exhh hexadecimal byte (up to 2 hex digits) \ex{hh...} hexadecimal character (any number of hex digits) .\" JOIN @@ -1011,10 +1089,9 @@ exact copy of the compiled pattern. If there is additional study data, this writing the file, \fBpcretest\fP expects to read a new pattern. .P 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: +name instead of a pattern. There must be no space between < and the file name, +which must not contain a < character, as otherwise \fBpcretest\fP will +interpret the line as a pattern delimited by < characters. For example: .sp re> , all the multi-character modifiers that begin with < are + locked out. Otherwise, such modifiers must be explicitly listed, for + example: + + < forbid + + There must be a single space between < and "forbid" for this feature to + be recognised. If there is not, the line is interpreted either as a + request to re-load a pre-compiled pattern (see "SAVING AND RELOADING + COMPILED PATTERNS" below) or, if there is a another < character, as a + pattern that uses < as its delimiter. + DATA LINES @@ -561,6 +634,7 @@ DATA LINES \v vertical tab (\x0b) \nnn octal character (up to 3 octal digits); always a byte unless > 255 in UTF-8 or 16-bit or 32-bit mode + \o{dd...} octal character (any number of octal digits} \xhh hexadecimal byte (up to 2 hex digits) \x{hh...} hexadecimal character (any number of hex digits) \A pass the PCRE_ANCHORED option to pcre[16|32]_exec() @@ -952,50 +1026,51 @@ SAVING AND RELOADING COMPILED PATTERNS 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: + file name instead of a pattern. There must be no space between < and + the file name, which must not contain a < character, as otherwise + pcretest will interpret the line as a pattern delimited by < charac- + ters. For example: re> &2 exit 1 fi - # It's OK to call `install-sh -d' without argument. + # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi @@ -240,7 +240,7 @@ fi for src do - # Protect names problematic for `test' and other utilities. + # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac @@ -354,7 +354,7 @@ do if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. + # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in diff --git a/tools/pcre/ltmain.sh b/tools/pcre/ltmain.sh index 3061e3c5..63ae69dc 100644 --- a/tools/pcre/ltmain.sh +++ b/tools/pcre/ltmain.sh @@ -1,9 +1,9 @@ -# libtool (GNU libtool) 2.4 +# libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, -# 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# 2007, 2008, 2009, 2010, 2011 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. @@ -41,6 +41,7 @@ # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) +# --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages @@ -69,7 +70,7 @@ # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4 +# $progname: (GNU libtool) 2.4.2 # automake: $automake_version # autoconf: $autoconf_version # @@ -79,9 +80,9 @@ PROGRAM=libtool PACKAGE=libtool -VERSION=2.4 +VERSION=2.4.2 TIMESTAMP="" -package_revision=1.3293 +package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then @@ -136,15 +137,10 @@ progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} -: ${EGREP="grep -E"} -: ${FGREP="grep -F"} -: ${GREP="grep"} -: ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} -: ${SED="sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} @@ -387,7 +383,7 @@ case $progpath in ;; *) save_IFS="$IFS" - IFS=: + IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break @@ -771,8 +767,8 @@ func_help () s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ - s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ - s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } @@ -1052,6 +1048,7 @@ opt_finish=false opt_help=false opt_help_all=false opt_silent=: +opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false @@ -1118,6 +1115,10 @@ esac ;; --no-silent|--no-quiet) opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) @@ -2059,7 +2060,7 @@ func_mode_compile () *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ - *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup) + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; @@ -3201,11 +3202,13 @@ func_mode_install () # Set up the ranlib parameters. oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then - func_show_eval "$old_striplib $oldlib" 'exit $?' + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. @@ -3470,7 +3473,7 @@ static const void *lt_preloaded_setup() { # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; @@ -3982,14 +3985,17 @@ func_exec_program_core () # launches target application with the remaining arguments. func_exec_program () { - for lt_wr_arg - do - case \$lt_wr_arg in - --lt-*) ;; - *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; - esac - shift - done + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac func_exec_program_core \${1+\"\$@\"} } @@ -5057,9 +5063,15 @@ void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | - $SED -e 's/\([\\"]\)/\\\1/g' \ - -e 's/^/ fputs ("/' -e 's/$/\\n", f);/' - + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' cat <<"EOF" } EOF @@ -5643,7 +5655,8 @@ func_mode_link () continue ;; - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" @@ -6147,7 +6160,8 @@ func_mode_link () lib= found=no case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" @@ -6831,7 +6845,7 @@ func_mode_link () test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" + add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in @@ -7316,6 +7330,7 @@ func_mode_link () # which has an extra 1 added just for fun # case $version_type in + # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result @@ -7432,7 +7447,7 @@ func_mode_link () versuffix="$major.$revision" ;; - linux) + linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" @@ -8020,6 +8035,11 @@ EOF # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= @@ -8050,7 +8070,7 @@ EOF elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; - *) func_apped perm_rpath " $libdir" ;; + *) func_append perm_rpath " $libdir" ;; esac fi done @@ -8058,11 +8078,7 @@ EOF if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" - if test -n "$hardcode_libdir_flag_spec_ld"; then - eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" - else - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. @@ -9152,6 +9168,8 @@ EOF esac done fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" @@ -9261,7 +9279,8 @@ EOF *.la) func_basename "$deplib" name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" diff --git a/tools/pcre/m4/libtool.m4 b/tools/pcre/m4/libtool.m4 index 2ed159cd..44e0ecff 100644 --- a/tools/pcre/m4/libtool.m4 +++ b/tools/pcre/m4/libtool.m4 @@ -1,8 +1,8 @@ # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -11,8 +11,8 @@ m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. @@ -146,6 +146,8 @@ AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl @@ -637,7 +639,7 @@ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." @@ -801,6 +803,7 @@ AC_DEFUN([LT_LANG], m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], @@ -822,6 +825,31 @@ m4_defun([_LT_LANG], ])# _LT_LANG +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], @@ -852,6 +880,10 @@ AC_PROVIDE_IFELSE([AC_PROG_GCJ], m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) @@ -954,7 +986,13 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -962,6 +1000,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ rm -rf libconftest.dylib* rm -f conftest.* fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no @@ -973,6 +1012,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF @@ -990,7 +1030,9 @@ _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? - if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1035,8 +1077,8 @@ _LT_EOF ]) -# _LT_DARWIN_LINKER_FEATURES -# -------------------------- +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ @@ -1047,6 +1089,8 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi @@ -1330,14 +1374,27 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) CFLAGS="$SAVE_CFLAGS" fi ;; -sparc*-*solaris*) +*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" @@ -1414,13 +1471,13 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in @@ -1600,6 +1657,11 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=196608 ;; + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not @@ -1639,7 +1701,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do @@ -2185,7 +2247,7 @@ need_version=unknown case $host_os in aix3*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH @@ -2194,7 +2256,7 @@ aix3*) ;; aix[[4-9]]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes @@ -2259,7 +2321,7 @@ beos*) ;; bsdi[[45]]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -2398,7 +2460,7 @@ m4_if([$1], [],[ ;; dgux*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' @@ -2406,10 +2468,6 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd1*) - dynamic_linker=no - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. @@ -2417,18 +2475,11 @@ freebsd* | dragonfly*) objformat=`/usr/bin/objformat` else case $host_os in - freebsd[[123]]*) objformat=aout ;; + freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi - # Handle Gentoo/FreeBSD as it was Linux - case $host_vendor in - gentoo) - version_type=linux ;; - *) - version_type=freebsd-$objformat ;; - esac - + version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' @@ -2439,16 +2490,10 @@ freebsd* | dragonfly*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; - linux) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - need_lib_prefix=no - need_version=no - ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in - freebsd2*) + freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) @@ -2468,17 +2513,18 @@ freebsd* | dragonfly*) ;; gnu*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" @@ -2539,7 +2585,7 @@ hpux9* | hpux10* | hpux11*) ;; interix[[3-9]]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' @@ -2555,7 +2601,7 @@ irix5* | irix6* | nonstopux*) nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; @@ -2592,9 +2638,9 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; -# This must be Linux ELF. +# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -2657,7 +2703,7 @@ netbsd*) ;; newsos6) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes @@ -2726,7 +2772,7 @@ rdos*) ;; solaris*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -2751,7 +2797,7 @@ sunos4*) ;; sysv4 | sysv4.3*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -2775,7 +2821,7 @@ sysv4 | sysv4.3*) sysv4*MP*) if test -d /usr/nec ;then - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH @@ -2806,7 +2852,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -2816,7 +2862,7 @@ tpf*) ;; uts4*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -3238,7 +3284,7 @@ irix5* | irix6* | nonstopux*) lt_cv_deplibs_check_method=pass_all ;; -# This must be Linux ELF. +# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; @@ -3658,6 +3704,7 @@ for ac_symprfx in "" "_"; do # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ @@ -4242,7 +4289,9 @@ m4_if([$1], [CXX], [ case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi ;; esac else @@ -4334,18 +4383,33 @@ m4_if([$1], [CXX], [ ;; *) case `$CC -V 2>&1 | sed 5q` in - *Sun\ F* | *Sun*Fortran*) + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; esac ;; esac @@ -4505,7 +4569,9 @@ m4_if([$1], [CXX], [ ;; cygwin* | mingw* | cegcc*) case $cc_basename in - cl*) ;; + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; *) _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'] @@ -4530,7 +4596,6 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported @@ -4781,8 +4846,7 @@ _LT_EOF xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ @@ -5077,6 +5141,7 @@ _LT_EOF # 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(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _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' @@ -5123,10 +5188,6 @@ _LT_EOF _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; - freebsd1*) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little @@ -5139,7 +5200,7 @@ _LT_EOF ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) + freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes @@ -5178,7 +5239,6 @@ _LT_EOF fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes @@ -5620,9 +5680,6 @@ _LT_TAGDECL([], [no_undefined_flag], [1], _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], - [[If ld is used when linking, flag to hardcode $libdir into a binary - during linking. This must work even if $libdir does not exist]]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], @@ -5780,7 +5837,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported @@ -6150,7 +6206,7 @@ if test "$_lt_caught_CXX_error" != yes; then esac ;; - freebsd[[12]]*) + freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no @@ -6911,12 +6967,18 @@ public class foo { } }; _LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary @@ -7113,7 +7175,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no @@ -7246,7 +7307,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no @@ -7433,6 +7493,77 @@ CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler @@ -7502,6 +7633,13 @@ dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], diff --git a/tools/pcre/m4/ltoptions.m4 b/tools/pcre/m4/ltoptions.m4 index 17cfd51c..5d9acd8e 100644 --- a/tools/pcre/m4/ltoptions.m4 +++ b/tools/pcre/m4/ltoptions.m4 @@ -326,9 +326,24 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [pic_mode="$withval"], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) diff --git a/tools/pcre/m4/ltversion.m4 b/tools/pcre/m4/ltversion.m4 index 9c7b5d41..07a8602d 100644 --- a/tools/pcre/m4/ltversion.m4 +++ b/tools/pcre/m4/ltversion.m4 @@ -9,15 +9,15 @@ # @configure_input@ -# serial 3293 ltversion.m4 +# serial 3337 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4]) -m4_define([LT_PACKAGE_REVISION], [1.3293]) +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4' -macro_revision='1.3293' +[macro_version='2.4.2' +macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/tools/pcre/m4/pcre_visibility.m4 b/tools/pcre/m4/pcre_visibility.m4 index 31f5deb9..30aff871 100644 --- a/tools/pcre/m4/pcre_visibility.m4 +++ b/tools/pcre/m4/pcre_visibility.m4 @@ -85,5 +85,5 @@ AC_DEFUN([PCRE_VISIBILITY], AC_SUBST([VISIBILITY_CXXFLAGS]) AC_SUBST([HAVE_VISIBILITY]) AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], - [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) + [Define to 1 if the compiler supports simple visibility declarations.]) ]) diff --git a/tools/pcre/makevp_c.txt b/tools/pcre/makevp_c.txt index f721511e..e5898c51 100644 --- a/tools/pcre/makevp_c.txt +++ b/tools/pcre/makevp_c.txt @@ -7,11 +7,12 @@ pcre_exec.c pcre_fullinfo.c pcre_get.c pcre_globals.c -pcre_info.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_ucd.c diff --git a/tools/pcre/makevp_l.txt b/tools/pcre/makevp_l.txt index 4acb0031..23e19756 100644 --- a/tools/pcre/makevp_l.txt +++ b/tools/pcre/makevp_l.txt @@ -7,11 +7,12 @@ +pcre_fullinfo.obj & +pcre_get.obj & +pcre_globals.obj & -+pcre_info.obj & ++pcre_jit_compile.obj & +pcre_maketables.obj & +pcre_newline.obj & +pcre_ord2utf8.obj & +pcre_refcount.obj & ++pcre_string_utils.obj & +pcre_study.obj & +pcre_tables.obj & +pcre_ucd.obj & diff --git a/tools/pcre/missing b/tools/pcre/missing index 86a8fc31..db98974f 100644 --- a/tools/pcre/missing +++ b/tools/pcre/missing @@ -1,11 +1,10 @@ #! /bin/sh -# Common stub for a few missing GNU programs while installing. +# Common wrapper for a few potentially missing GNU programs. -scriptversion=2012-01-06.13; # UTC +scriptversion=2013-10-28.13; # UTC -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,68 +25,40 @@ scriptversion=2012-01-06.13; # UTC # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "Try '$0 --help' for more information" exit 1 fi -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -msg="missing on your system" - case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - yacc create \`y.tab.[ch]', if possible, from existing .[ch] + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man -Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and -\`g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. Send bug reports to ." exit $? @@ -99,228 +70,141 @@ Send bug reports to ." ;; -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` +# Run the given program, remember its exit status. +"$@"; st=$? -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te*) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff --git a/tools/pcre/pcre.h.generic b/tools/pcre/pcre.h.generic index a6aa4e93..ce4251c8 100644 --- a/tools/pcre/pcre.h.generic +++ b/tools/pcre/pcre.h.generic @@ -5,7 +5,7 @@ /* This is the public header file for the PCRE library, to be #included by applications that call the PCRE functions. - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE_MAJOR 8 -#define PCRE_MINOR 32 +#define PCRE_MINOR 35 #define PCRE_PRERELEASE -#define PCRE_DATE 2012-11-30 +#define PCRE_DATE 2014-04-04 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate @@ -96,11 +96,14 @@ extern "C" { #endif /* Public options. Some are compile-time only, some are run-time only, and some -are both, so we keep them all distinct. However, almost all the bits in the -options word are now used. In the long run, we may have to re-use some of the -compile-time only bits for runtime options, or vice versa. Any of the -compile-time options may be inspected during studying (and therefore JIT -compiling). +are both. Most of the compile-time options are saved with the compiled regex so +that they can be inspected during studying (and therefore JIT compiling). Note +that pcre_study() has its own set of options. Originally, all the options +defined here used distinct bits. However, almost all the bits in a 32-bit word +are now used, so in order to conserve them, option bits that were previously +only recognized at matching time (i.e. by pcre_exec() or pcre_dfa_exec()) may +also be used for compile-time options that affect only compiling and are not +relevant for studying or JIT compiling. Some options for pcre_compile() change its behaviour but do not affect the behaviour of the execution functions. Other options are passed through to the @@ -142,8 +145,15 @@ with J. */ #define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */ #define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */ #define PCRE_PARTIAL 0x00008000 /* E D J ) */ -#define PCRE_DFA_SHORTEST 0x00010000 /* D */ -#define PCRE_DFA_RESTART 0x00020000 /* D */ + +/* This pair use the same bit. */ +#define PCRE_NEVER_UTF 0x00010000 /* C1 ) Overlaid */ +#define PCRE_DFA_SHORTEST 0x00010000 /* D ) Overlaid */ + +/* This pair use the same bit. */ +#define PCRE_NO_AUTO_POSSESS 0x00020000 /* C1 ) Overlaid */ +#define PCRE_DFA_RESTART 0x00020000 /* D ) Overlaid */ + #define PCRE_FIRSTLINE 0x00040000 /* C3 */ #define PCRE_DUPNAMES 0x00080000 /* C1 */ #define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */ @@ -199,6 +209,7 @@ with J. */ #define PCRE_ERROR_DFA_BADRESTART (-30) #define PCRE_ERROR_JIT_BADOPTION (-31) #define PCRE_ERROR_BADLENGTH (-32) +#define PCRE_ERROR_UNSET (-33) /* Specific error codes for UTF-8 validity checks */ @@ -224,7 +235,7 @@ with J. */ #define PCRE_UTF8_ERR19 19 #define PCRE_UTF8_ERR20 20 #define PCRE_UTF8_ERR21 21 -#define PCRE_UTF8_ERR22 22 +#define PCRE_UTF8_ERR22 22 /* Unused (was non-character) */ /* Specific error codes for UTF-16 validity checks */ @@ -232,13 +243,13 @@ with J. */ #define PCRE_UTF16_ERR1 1 #define PCRE_UTF16_ERR2 2 #define PCRE_UTF16_ERR3 3 -#define PCRE_UTF16_ERR4 4 +#define PCRE_UTF16_ERR4 4 /* Unused (was non-character) */ /* Specific error codes for UTF-32 validity checks */ #define PCRE_UTF32_ERR0 0 #define PCRE_UTF32_ERR1 1 -#define PCRE_UTF32_ERR2 2 +#define PCRE_UTF32_ERR2 2 /* Unused (was non-character) */ #define PCRE_UTF32_ERR3 3 /* Request types for pcre_fullinfo() */ @@ -263,10 +274,13 @@ with J. */ #define PCRE_INFO_JIT 16 #define PCRE_INFO_JITSIZE 17 #define PCRE_INFO_MAXLOOKBEHIND 18 -#define PCRE_INFO_FIRSTCHARACTER 19 -#define PCRE_INFO_FIRSTCHARACTERFLAGS 20 +#define PCRE_INFO_FIRSTCHARACTER 19 +#define PCRE_INFO_FIRSTCHARACTERFLAGS 20 #define PCRE_INFO_REQUIREDCHAR 21 -#define PCRE_INFO_REQUIREDCHARFLAGS 22 +#define PCRE_INFO_REQUIREDCHARFLAGS 22 +#define PCRE_INFO_MATCHLIMIT 23 +#define PCRE_INFO_RECURSIONLIMIT 24 +#define PCRE_INFO_MATCH_EMPTY 25 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ @@ -284,6 +298,7 @@ compatible. */ #define PCRE_CONFIG_UTF16 10 #define PCRE_CONFIG_JITTARGET 11 #define PCRE_CONFIG_UTF32 12 +#define PCRE_CONFIG_PARENS_LIMIT 13 /* Request types for pcre_study(). Do not re-arrange, in order to remain compatible. */ @@ -476,36 +491,42 @@ 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 int (*pcre_stack_guard)(void); 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 *); +PCRE_EXP_DECL int (*pcre16_stack_guard)(void); PCRE_EXP_DECL void *(*pcre32_malloc)(size_t); PCRE_EXP_DECL void (*pcre32_free)(void *); PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre32_stack_free)(void *); PCRE_EXP_DECL int (*pcre32_callout)(pcre32_callout_block *); +PCRE_EXP_DECL int (*pcre32_stack_guard)(void); #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 int pcre_stack_guard(void); 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 *); +PCRE_EXP_DECL int pcre16_stack_guard(void); PCRE_EXP_DECL void *pcre32_malloc(size_t); PCRE_EXP_DECL void pcre32_free(void *); PCRE_EXP_DECL void *pcre32_stack_malloc(size_t); PCRE_EXP_DECL void pcre32_stack_free(void *); PCRE_EXP_DECL int pcre32_callout(pcre32_callout_block *); +PCRE_EXP_DECL int pcre32_stack_guard(void); #endif /* VPCOMPAT */ /* User defined callback which provides a stack just before the match starts. */ @@ -645,6 +666,9 @@ PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *, pcre16_jit_callback, void *); PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *, pcre32_jit_callback, void *); +PCRE_EXP_DECL void pcre_jit_free_unused_memory(void); +PCRE_EXP_DECL void pcre16_jit_free_unused_memory(void); +PCRE_EXP_DECL void pcre32_jit_free_unused_memory(void); #ifdef __cplusplus } /* extern "C" */ diff --git a/tools/pcre/pcre.h.in b/tools/pcre/pcre.h.in index 2376c9c3..667a45ed 100644 --- a/tools/pcre/pcre.h.in +++ b/tools/pcre/pcre.h.in @@ -5,7 +5,7 @@ /* This is the public header file for the PCRE library, to be #included by applications that call the PCRE functions. - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -96,11 +96,14 @@ extern "C" { #endif /* Public options. Some are compile-time only, some are run-time only, and some -are both, so we keep them all distinct. However, almost all the bits in the -options word are now used. In the long run, we may have to re-use some of the -compile-time only bits for runtime options, or vice versa. Any of the -compile-time options may be inspected during studying (and therefore JIT -compiling). +are both. Most of the compile-time options are saved with the compiled regex so +that they can be inspected during studying (and therefore JIT compiling). Note +that pcre_study() has its own set of options. Originally, all the options +defined here used distinct bits. However, almost all the bits in a 32-bit word +are now used, so in order to conserve them, option bits that were previously +only recognized at matching time (i.e. by pcre_exec() or pcre_dfa_exec()) may +also be used for compile-time options that affect only compiling and are not +relevant for studying or JIT compiling. Some options for pcre_compile() change its behaviour but do not affect the behaviour of the execution functions. Other options are passed through to the @@ -142,8 +145,15 @@ with J. */ #define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */ #define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */ #define PCRE_PARTIAL 0x00008000 /* E D J ) */ -#define PCRE_DFA_SHORTEST 0x00010000 /* D */ -#define PCRE_DFA_RESTART 0x00020000 /* D */ + +/* This pair use the same bit. */ +#define PCRE_NEVER_UTF 0x00010000 /* C1 ) Overlaid */ +#define PCRE_DFA_SHORTEST 0x00010000 /* D ) Overlaid */ + +/* This pair use the same bit. */ +#define PCRE_NO_AUTO_POSSESS 0x00020000 /* C1 ) Overlaid */ +#define PCRE_DFA_RESTART 0x00020000 /* D ) Overlaid */ + #define PCRE_FIRSTLINE 0x00040000 /* C3 */ #define PCRE_DUPNAMES 0x00080000 /* C1 */ #define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */ @@ -199,6 +209,7 @@ with J. */ #define PCRE_ERROR_DFA_BADRESTART (-30) #define PCRE_ERROR_JIT_BADOPTION (-31) #define PCRE_ERROR_BADLENGTH (-32) +#define PCRE_ERROR_UNSET (-33) /* Specific error codes for UTF-8 validity checks */ @@ -224,7 +235,7 @@ with J. */ #define PCRE_UTF8_ERR19 19 #define PCRE_UTF8_ERR20 20 #define PCRE_UTF8_ERR21 21 -#define PCRE_UTF8_ERR22 22 +#define PCRE_UTF8_ERR22 22 /* Unused (was non-character) */ /* Specific error codes for UTF-16 validity checks */ @@ -232,13 +243,13 @@ with J. */ #define PCRE_UTF16_ERR1 1 #define PCRE_UTF16_ERR2 2 #define PCRE_UTF16_ERR3 3 -#define PCRE_UTF16_ERR4 4 +#define PCRE_UTF16_ERR4 4 /* Unused (was non-character) */ /* Specific error codes for UTF-32 validity checks */ #define PCRE_UTF32_ERR0 0 #define PCRE_UTF32_ERR1 1 -#define PCRE_UTF32_ERR2 2 +#define PCRE_UTF32_ERR2 2 /* Unused (was non-character) */ #define PCRE_UTF32_ERR3 3 /* Request types for pcre_fullinfo() */ @@ -263,10 +274,13 @@ with J. */ #define PCRE_INFO_JIT 16 #define PCRE_INFO_JITSIZE 17 #define PCRE_INFO_MAXLOOKBEHIND 18 -#define PCRE_INFO_FIRSTCHARACTER 19 -#define PCRE_INFO_FIRSTCHARACTERFLAGS 20 +#define PCRE_INFO_FIRSTCHARACTER 19 +#define PCRE_INFO_FIRSTCHARACTERFLAGS 20 #define PCRE_INFO_REQUIREDCHAR 21 -#define PCRE_INFO_REQUIREDCHARFLAGS 22 +#define PCRE_INFO_REQUIREDCHARFLAGS 22 +#define PCRE_INFO_MATCHLIMIT 23 +#define PCRE_INFO_RECURSIONLIMIT 24 +#define PCRE_INFO_MATCH_EMPTY 25 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ @@ -284,6 +298,7 @@ compatible. */ #define PCRE_CONFIG_UTF16 10 #define PCRE_CONFIG_JITTARGET 11 #define PCRE_CONFIG_UTF32 12 +#define PCRE_CONFIG_PARENS_LIMIT 13 /* Request types for pcre_study(). Do not re-arrange, in order to remain compatible. */ @@ -476,36 +491,42 @@ 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 int (*pcre_stack_guard)(void); 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 *); +PCRE_EXP_DECL int (*pcre16_stack_guard)(void); PCRE_EXP_DECL void *(*pcre32_malloc)(size_t); PCRE_EXP_DECL void (*pcre32_free)(void *); PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre32_stack_free)(void *); PCRE_EXP_DECL int (*pcre32_callout)(pcre32_callout_block *); +PCRE_EXP_DECL int (*pcre32_stack_guard)(void); #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 int pcre_stack_guard(void); 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 *); +PCRE_EXP_DECL int pcre16_stack_guard(void); PCRE_EXP_DECL void *pcre32_malloc(size_t); PCRE_EXP_DECL void pcre32_free(void *); PCRE_EXP_DECL void *pcre32_stack_malloc(size_t); PCRE_EXP_DECL void pcre32_stack_free(void *); PCRE_EXP_DECL int pcre32_callout(pcre32_callout_block *); +PCRE_EXP_DECL int pcre32_stack_guard(void); #endif /* VPCOMPAT */ /* User defined callback which provides a stack just before the match starts. */ @@ -645,6 +666,9 @@ PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *, pcre16_jit_callback, void *); PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *, pcre32_jit_callback, void *); +PCRE_EXP_DECL void pcre_jit_free_unused_memory(void); +PCRE_EXP_DECL void pcre16_jit_free_unused_memory(void); +PCRE_EXP_DECL void pcre32_jit_free_unused_memory(void); #ifdef __cplusplus } /* extern "C" */ diff --git a/tools/pcre/pcre16_valid_utf16.c b/tools/pcre/pcre16_valid_utf16.c index c06023a7..09076539 100644 --- a/tools/pcre/pcre16_valid_utf16.c +++ b/tools/pcre/pcre16_valid_utf16.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2013 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -69,7 +69,7 @@ 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 Non-character +PCRE_UTF16_ERR4 Unused (was non-character) Arguments: string points to the string @@ -100,19 +100,10 @@ for (p = string; length-- > 0; p++) if ((c & 0xf800) != 0xd800) { /* Normal UTF-16 code point. Neither high nor low surrogate. */ - - /* Check for non-characters */ - if ((c & 0xfffeu) == 0xfffeu || (c >= 0xfdd0u && c <= 0xfdefu)) - { - *erroroffset = p - string; - return PCRE_UTF16_ERR4; - } } else if ((c & 0x0400) == 0) { - /* High surrogate. */ - - /* Must be a followed by a low surrogate. */ + /* High surrogate. Must be a followed by a low surrogate. */ if (length == 0) { *erroroffset = p - string; @@ -125,16 +116,6 @@ for (p = string; length-- > 0; p++) *erroroffset = p - string; return PCRE_UTF16_ERR2; } - else - { - /* Valid surrogate, but check for non-characters */ - c = (((c & 0x3ffu) << 10) | (*p & 0x3ffu)) + 0x10000u; - if ((c & 0xfffeu) == 0xfffeu) - { - *erroroffset = p - string; - return PCRE_UTF16_ERR4; - } - } } else { diff --git a/tools/pcre/pcre32_valid_utf32.c b/tools/pcre/pcre32_valid_utf32.c index ff0b0c2e..94cda1a2 100644 --- a/tools/pcre/pcre32_valid_utf32.c +++ b/tools/pcre/pcre32_valid_utf32.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2013 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -66,7 +66,7 @@ back in the returned value: PCRE_UTF32_ERR0 No error PCRE_UTF32_ERR1 Surrogate character -PCRE_UTF32_ERR2 Non-character +PCRE_UTF32_ERR2 Unused (was non-character) PCRE_UTF32_ERR3 Character > 0x10ffff Arguments: @@ -98,14 +98,7 @@ for (p = string; length-- > 0; p++) if ((c & 0xfffff800u) != 0xd800u) { /* Normal UTF-32 code point. Neither high nor low surrogate. */ - - /* Check for non-characters */ - if ((c & 0xfffeu) == 0xfffeu || (c >= 0xfdd0u && c <= 0xfdefu)) - { - *erroroffset = p - string; - return PCRE_UTF32_ERR2; - } - else if (c > 0x10ffffu) + if (c > 0x10ffffu) { *erroroffset = p - string; return PCRE_UTF32_ERR3; diff --git a/tools/pcre/pcre_byte_order.c b/tools/pcre/pcre_byte_order.c index 472eb38b..cf5f12b0 100644 --- a/tools/pcre/pcre_byte_order.c +++ b/tools/pcre/pcre_byte_order.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -126,14 +126,15 @@ if (re->magic_number == MAGIC_NUMBER) } if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC; -if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; +if ((swap_uint32(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->flags = swap_uint32(re->flags); +re->limit_match = swap_uint32(re->limit_match); +re->limit_recursion = swap_uint32(re->limit_recursion); + #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 re->first_char = swap_uint16(re->first_char); re->req_char = swap_uint16(re->req_char); @@ -141,15 +142,15 @@ re->req_char = swap_uint16(re->req_char); re->first_char = swap_uint32(re->first_char); re->req_char = swap_uint32(re->req_char); #endif + +re->max_lookbehind = swap_uint16(re->max_lookbehind); +re->top_bracket = swap_uint16(re->top_bracket); +re->top_backref = swap_uint16(re->top_backref); 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; -#ifdef COMPILE_PCRE32 -re->dummy1 = swap_uint16(re->dummy1); -re->dummy2 = swap_uint16(re->dummy2); -#endif if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) { @@ -310,9 +311,9 @@ while(TRUE) ptr++; } /* Control should never reach here in 16/32 bit mode. */ -#endif /* !COMPILE_PCRE8 */ - +#else /* In 8-bit mode, the pattern does not need to be processed. */ return 0; +#endif /* !COMPILE_PCRE8 */ } /* End of pcre_byte_order.c */ diff --git a/tools/pcre/pcre_chartables.c.dist b/tools/pcre/pcre_chartables.c.dist index 2a39e9ff..1e20ec29 100644 --- a/tools/pcre/pcre_chartables.c.dist +++ b/tools/pcre/pcre_chartables.c.dist @@ -163,7 +163,7 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */ */ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ - 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ + 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ diff --git a/tools/pcre/pcre_compile.c b/tools/pcre/pcre_compile.c index 5f0c8ed0..8a5b7233 100644 --- a/tools/pcre/pcre_compile.c +++ b/tools/pcre/pcre_compile.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -115,6 +115,13 @@ kicks in at the same number of forward references in all cases. */ #define COMPILE_WORK_SIZE (2048*LINK_SIZE) #define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE) +/* This value determines the size of the initial vector that is used for +remembering named groups during the pre-compile. It is allocated on the stack, +but if it is too small, it is expanded using malloc(), in a similar way to the +workspace. The value is the number of slots in the list. */ + +#define NAMED_GROUP_LIST_SIZE 20 + /* The overrun tests check for a slightly smaller size so that they detect the overrun before it actually does run off the end of the data block. */ @@ -253,11 +260,25 @@ static const verbitem verbs[] = { static const int verbcount = sizeof(verbs)/sizeof(verbitem); +/* Substitutes for [[:<:]] and [[:>:]], which mean start and end of word in +another regex library. */ + +static const pcre_uchar sub_start_of_word[] = { + CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK, + CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w, CHAR_RIGHT_PARENTHESIS, '\0' }; + +static const pcre_uchar sub_end_of_word[] = { + CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK, + CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w, + CHAR_RIGHT_PARENTHESIS, '\0' }; + + /* Tables of names of POSIX character classes and their lengths. The names are now all in a single string, to reduce the number of relocations when a shared library is dynamically loaded. The list of lengths is terminated by a zero length entry. The first three must be alpha, lower, upper, as this is assumed -for handling case independence. */ +for handling case independence. The indices for graph, print, and punct are +needed, so identify them. */ static const char posix_names[] = STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0 @@ -268,6 +289,11 @@ static const char posix_names[] = static const pcre_uint8 posix_name_lengths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; +#define PC_GRAPH 8 +#define PC_PRINT 9 +#define PC_PUNCT 10 + + /* Table of class bit maps for each POSIX class. Each class is formed from a base map, with an optional addition or removal of another map. Then, for some classes, there is some additional tweaking: for [:blank:] the vertical space @@ -295,9 +321,8 @@ static const int posix_class_maps[] = { cbit_xdigit,-1, 0 /* xdigit */ }; -/* Table of substitutes for \d etc when PCRE_UCP is set. The POSIX class -substitutes must be in the order of the names, defined above, and there are -both positive and negative cases. NULL means no substitute. */ +/* Table of substitutes for \d etc when PCRE_UCP is set. They are replaced by +Unicode property escapes. */ #ifdef SUPPORT_UCP static const pcre_uchar string_PNd[] = { @@ -322,12 +347,18 @@ static const pcre_uchar string_pXwd[] = { static const pcre_uchar *substitutes[] = { string_PNd, /* \D */ string_pNd, /* \d */ - string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */ - string_pXsp, /* \s */ + string_PXsp, /* \S */ /* Xsp is Perl space, but from 8.34, Perl */ + string_pXsp, /* \s */ /* space and POSIX space are the same. */ string_PXwd, /* \W */ string_pXwd /* \w */ }; +/* The POSIX class substitutes must be in the order of the POSIX class names, +defined above, and there are both positive and negative cases. NULL means no +general substitute of a Unicode property escape (\p or \P). However, for some +POSIX classes (e.g. graph, print, punct) a special property code is compiled +directly. */ + static const pcre_uchar string_pL[] = { CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; @@ -375,8 +406,8 @@ static const pcre_uchar *posix_substitutes[] = { NULL, /* graph */ NULL, /* print */ NULL, /* punct */ - string_pXps, /* space */ /* NOTE: Xps is POSIX space */ - string_pXwd, /* word */ + string_pXps, /* space */ /* Xps is POSIX space, but from 8.34 */ + string_pXwd, /* word */ /* Perl and POSIX space are the same */ NULL, /* xdigit */ /* Negated cases */ string_PL, /* ^alpha */ @@ -390,8 +421,8 @@ static const pcre_uchar *posix_substitutes[] = { NULL, /* ^graph */ NULL, /* ^print */ NULL, /* ^punct */ - string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */ - string_PXwd, /* ^word */ + string_PXps, /* ^space */ /* Xps is POSIX space, but from 8.34 */ + string_PXwd, /* ^word */ /* Perl and POSIX space are the same */ NULL /* ^xdigit */ }; #define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *)) @@ -455,7 +486,7 @@ static const char error_texts[] = "POSIX collating elements are not supported\0" "this version of PCRE is compiled without UTF support\0" "spare error\0" /** DEAD **/ - "character value in \\x{...} sequence is too large\0" + "character value in \\x{} or \\o{} is too large\0" /* 35 */ "invalid condition (?(0)\0" "\\C not allowed in lookbehind assertion\0" @@ -487,7 +518,7 @@ static const char error_texts[] = "a numbered reference must not be zero\0" "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0" /* 60 */ - "(*VERB) not recognized\0" + "(*VERB) not recognized or malformed\0" "number is too big\0" "subpattern name expected\0" "digit expected after (?+\0" @@ -508,6 +539,16 @@ static const char error_texts[] = "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0" "character value in \\u.... sequence is too large\0" "invalid UTF-32 string\0" + "setting UTF is disabled by the application\0" + "non-hex character in \\x{} (closing brace missing?)\0" + /* 80 */ + "non-octal character in \\o{} (closing brace missing?)\0" + "missing opening brace after \\o\0" + "parentheses are too deeply nested\0" + "invalid range in character class\0" + "group name must start with a non-digit\0" + /* 85 */ + "parentheses are too deeply nested (stack check)\0" ; /* Table to identify digits and hex digits. This is used when compiling @@ -647,6 +688,183 @@ static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */ #endif +/* This table is used to check whether auto-possessification is possible +between adjacent character-type opcodes. The left-hand (repeated) opcode is +used to select the row, and the right-hand opcode is use to select the column. +A value of 1 means that auto-possessification is OK. For example, the second +value in the first row means that \D+\d can be turned into \D++\d. + +The Unicode property types (\P and \p) have to be present to fill out the table +because of what their opcode values are, but the table values should always be +zero because property types are handled separately in the code. The last four +columns apply to items that cannot be repeated, so there is no need to have +rows for them. Note that OP_DIGIT etc. are generated only when PCRE_UCP is +*not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ + +#define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1) +#define APTCOLS (LAST_AUTOTAB_RIGHT_OP - FIRST_AUTOTAB_OP + 1) + +static const pcre_uint8 autoposstab[APTROWS][APTCOLS] = { +/* \D \d \S \s \W \w . .+ \C \P \p \R \H \h \V \v \X \Z \z $ $M */ + { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \D */ + { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \d */ + { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \S */ + { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \s */ + { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \W */ + { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \w */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* . */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* .+ */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \C */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \P */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \p */ + { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \R */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \H */ + { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \h */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \V */ + { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 }, /* \v */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } /* \X */ +}; + + +/* This table is used to check whether auto-possessification is possible +between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP). The +left-hand (repeated) opcode is used to select the row, and the right-hand +opcode is used to select the column. The values are as follows: + + 0 Always return FALSE (never auto-possessify) + 1 Character groups are distinct (possessify if both are OP_PROP) + 2 Check character categories in the same group (general or particular) + 3 TRUE if the two opcodes are not the same (PROP vs NOTPROP) + + 4 Check left general category vs right particular category + 5 Check right general category vs left particular category + + 6 Left alphanum vs right general category + 7 Left space vs right general category + 8 Left word vs right general category + + 9 Right alphanum vs left general category + 10 Right space vs left general category + 11 Right word vs left general category + + 12 Left alphanum vs right particular category + 13 Left space vs right particular category + 14 Left word vs right particular category + + 15 Right alphanum vs left particular category + 16 Right space vs left particular category + 17 Right word vs left particular category +*/ + +static const pcre_uint8 propposstab[PT_TABSIZE][PT_TABSIZE] = { +/* ANY LAMP GC PC SC ALNUM SPACE PXSPACE WORD CLIST UCNC */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_ANY */ + { 0, 3, 0, 0, 0, 3, 1, 1, 0, 0, 0 }, /* PT_LAMP */ + { 0, 0, 2, 4, 0, 9, 10, 10, 11, 0, 0 }, /* PT_GC */ + { 0, 0, 5, 2, 0, 15, 16, 16, 17, 0, 0 }, /* PT_PC */ + { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, /* PT_SC */ + { 0, 3, 6, 12, 0, 3, 1, 1, 0, 0, 0 }, /* PT_ALNUM */ + { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_SPACE */ + { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_PXSPACE */ + { 0, 0, 8, 14, 0, 0, 1, 1, 3, 0, 0 }, /* PT_WORD */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 } /* PT_UCNC */ +}; + +/* This table is used to check whether auto-possessification is possible +between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP) when one +specifies a general category and the other specifies a particular category. The +row is selected by the general category and the column by the particular +category. The value is 1 if the particular category is not part of the general +category. */ + +static const pcre_uint8 catposstab[7][30] = { +/* Cc Cf Cn Co Cs Ll Lm Lo Lt Lu Mc Me Mn Nd Nl No Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So Zl Zp Zs */ + { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* C */ + { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* L */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* M */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* N */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 }, /* P */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 }, /* S */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 } /* Z */ +}; + +/* This table is used when checking ALNUM, (PX)SPACE, SPACE, and WORD against +a general or particular category. The properties in each row are those +that apply to the character set in question. Duplication means that a little +unnecessary work is done when checking, but this keeps things much simpler +because they can all use the same code. For more details see the comment where +this table is used. + +Note: SPACE and PXSPACE used to be different because Perl excluded VT from +"space", but from Perl 5.18 it's included, so both categories are treated the +same here. */ + +static const pcre_uint8 posspropstab[3][4] = { + { ucp_L, ucp_N, ucp_N, ucp_Nl }, /* ALNUM, 3rd and 4th values redundant */ + { ucp_Z, ucp_Z, ucp_C, ucp_Cc }, /* SPACE and PXSPACE, 2nd value redundant */ + { ucp_L, ucp_N, ucp_P, ucp_Po } /* WORD */ +}; + +/* This table is used when converting repeating opcodes into possessified +versions as a result of an explicit possessive quantifier such as ++. A zero +value means there is no possessified version - in those cases the item in +question must be wrapped in ONCE brackets. The table is truncated at OP_CALLOUT +because all relevant opcodes are less than that. */ + +static const pcre_uint8 opcode_possessify[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 15 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 31 */ + + 0, /* NOTI */ + OP_POSSTAR, 0, /* STAR, MINSTAR */ + OP_POSPLUS, 0, /* PLUS, MINPLUS */ + OP_POSQUERY, 0, /* QUERY, MINQUERY */ + OP_POSUPTO, 0, /* UPTO, MINUPTO */ + 0, /* EXACT */ + 0, 0, 0, 0, /* POS{STAR,PLUS,QUERY,UPTO} */ + + OP_POSSTARI, 0, /* STARI, MINSTARI */ + OP_POSPLUSI, 0, /* PLUSI, MINPLUSI */ + OP_POSQUERYI, 0, /* QUERYI, MINQUERYI */ + OP_POSUPTOI, 0, /* UPTOI, MINUPTOI */ + 0, /* EXACTI */ + 0, 0, 0, 0, /* POS{STARI,PLUSI,QUERYI,UPTOI} */ + + OP_NOTPOSSTAR, 0, /* NOTSTAR, NOTMINSTAR */ + OP_NOTPOSPLUS, 0, /* NOTPLUS, NOTMINPLUS */ + OP_NOTPOSQUERY, 0, /* NOTQUERY, NOTMINQUERY */ + OP_NOTPOSUPTO, 0, /* NOTUPTO, NOTMINUPTO */ + 0, /* NOTEXACT */ + 0, 0, 0, 0, /* NOTPOS{STAR,PLUS,QUERY,UPTO} */ + + OP_NOTPOSSTARI, 0, /* NOTSTARI, NOTMINSTARI */ + OP_NOTPOSPLUSI, 0, /* NOTPLUSI, NOTMINPLUSI */ + OP_NOTPOSQUERYI, 0, /* NOTQUERYI, NOTMINQUERYI */ + OP_NOTPOSUPTOI, 0, /* NOTUPTOI, NOTMINUPTOI */ + 0, /* NOTEXACTI */ + 0, 0, 0, 0, /* NOTPOS{STARI,PLUSI,QUERYI,UPTOI} */ + + OP_TYPEPOSSTAR, 0, /* TYPESTAR, TYPEMINSTAR */ + OP_TYPEPOSPLUS, 0, /* TYPEPLUS, TYPEMINPLUS */ + OP_TYPEPOSQUERY, 0, /* TYPEQUERY, TYPEMINQUERY */ + OP_TYPEPOSUPTO, 0, /* TYPEUPTO, TYPEMINUPTO */ + 0, /* TYPEEXACT */ + 0, 0, 0, 0, /* TYPEPOS{STAR,PLUS,QUERY,UPTO} */ + + OP_CRPOSSTAR, 0, /* CRSTAR, CRMINSTAR */ + OP_CRPOSPLUS, 0, /* CRPLUS, CRMINPLUS */ + OP_CRPOSQUERY, 0, /* CRQUERY, CRMINQUERY */ + OP_CRPOSRANGE, 0, /* CRRANGE, CRMINRANGE */ + 0, 0, 0, 0, /* CRPOS{STAR,PLUS,QUERY,RANGE} */ + + 0, 0, 0, /* CLASS, NCLASS, XCLASS */ + 0, 0, /* REF, REFI */ + 0, 0, /* DNREF, DNREFI */ + 0, 0 /* RECURSE, CALLOUT */ +}; + + /************************************************* * Find an error text * @@ -674,6 +892,7 @@ return s; } + /************************************************* * Expand the workspace * *************************************************/ @@ -751,16 +970,15 @@ return (*p == CHAR_RIGHT_CURLY_BRACKET); *************************************************/ /* This function is called when a \ has been encountered. It either returns a -positive value for a simple escape such as \n, or 0 for a data character -which will be placed in chptr. A backreference to group n is returned as -negative n. When UTF-8 is enabled, a positive value greater than 255 may -be returned in chptr. -On entry,ptr is pointing at the \. On exit, it is on the final character of the -escape sequence. +positive value for a simple escape such as \n, or 0 for a data character which +will be placed in chptr. A backreference to group n is returned as negative n. +When UTF-8 is enabled, a positive value greater than 255 may be returned in +chptr. On entry, ptr is pointing at the \. On exit, it is on the final +character of the escape sequence. Arguments: ptrptr points to the pattern position pointer - chptr points to the data character + chptr points to a returned data character errorcodeptr points to the errorcode variable bracount number of previous extracting brackets options the options bits @@ -797,7 +1015,8 @@ Otherwise further processing may be required. */ #ifndef EBCDIC /* ASCII/UTF-8 coding */ /* Not alphanumeric */ else if (c < CHAR_0 || c > CHAR_z) {} -else if ((i = escapes[c - CHAR_0]) != 0) { if (i > 0) c = (pcre_uint32)i; else escape = -i; } +else if ((i = escapes[c - CHAR_0]) != 0) + { if (i > 0) c = (pcre_uint32)i; else escape = -i; } #else /* EBCDIC coding */ /* Not alphanumeric */ @@ -847,11 +1066,11 @@ else } #if defined COMPILE_PCRE8 - if (c > (utf ? 0x10ffff : 0xff)) + if (c > (utf ? 0x10ffffU : 0xffU)) #elif defined COMPILE_PCRE16 - if (c > (utf ? 0x10ffff : 0xffff)) + if (c > (utf ? 0x10ffffU : 0xffffU)) #elif defined COMPILE_PCRE32 - if (utf && c > 0x10ffff) + if (utf && c > 0x10ffffU) #endif { *errorcodeptr = ERR76; @@ -963,16 +1182,20 @@ else break; /* The handling of escape sequences consisting of a string of digits - starting with one that is not zero is not straightforward. By experiment, - the way Perl works seems to be as follows: + starting with one that is not zero is not straightforward. Perl has changed + over the years. Nowadays \g{} for backreferences and \o{} for octal are + recommended to avoid the ambiguities in the old syntax. Outside a character class, the digits are read as a decimal number. If the - number is less than 10, or if there are that many previous extracting - left brackets, then it is a back reference. Otherwise, up to three octal - digits are read to form an escaped byte. Thus \123 is likely to be octal - 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal - value is greater than 377, the least significant 8 bits are taken. Inside a - character class, \ followed by a digit is always an octal number. */ + number is less than 8 (used to be 10), or if there are that many previous + extracting left brackets, then it is a back reference. Otherwise, up to + three octal digits are read to form an escaped byte. Thus \123 is likely to + be octal 123 (cf \0123, which is octal 012 followed by the literal 3). If + the octal value is greater than 377, the least significant 8 bits are + taken. \8 and \9 are treated as the literal characters 8 and 9. + + Inside a character class, \ followed by a digit is always either a literal + 8 or 9 or an octal number. */ case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: @@ -999,7 +1222,7 @@ else *errorcodeptr = ERR61; break; } - if (s < 10 || s <= bracount) + if (s < 8 || s <= bracount) /* Check for back reference */ { escape = -s; break; @@ -1007,16 +1230,14 @@ else ptr = oldptr; /* Put the pointer back and fall through */ } - /* Handle an octal number following \. If the first digit is 8 or 9, Perl - generates a binary zero byte and treats the digit as a following literal. - Thus we have to pull back the pointer by one. */ + /* Handle a digit following \ when the number is not a back reference. If + the first digit is 8 or 9, Perl used to generate a binary zero byte and + then treat the digit as a following literal. At least by Perl 5.18 this + changed so as not to insert the binary zero. */ - if ((c = *ptr) >= CHAR_8) - { - ptr--; - c = 0; - break; - } + if ((c = *ptr) >= CHAR_8) break; + + /* Fall through with a digit less than 8 */ /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least @@ -1033,15 +1254,50 @@ else #endif break; - /* \x is complicated. \x{ddd} is a character number which can be greater - than 0xff in utf or non-8bit mode, but only if the ddd are hex digits. - If not, { is treated as a data character. */ + /* \o is a relatively new Perl feature, supporting a more general way of + specifying character codes in octal. The only supported form is \o{ddd}. */ + + case CHAR_o: + if (ptr[1] != CHAR_LEFT_CURLY_BRACKET) *errorcodeptr = ERR81; else + { + ptr += 2; + c = 0; + overflow = FALSE; + while (*ptr >= CHAR_0 && *ptr <= CHAR_7) + { + register pcre_uint32 cc = *ptr++; + if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ +#ifdef COMPILE_PCRE32 + if (c >= 0x20000000l) { overflow = TRUE; break; } +#endif + c = (c << 3) + cc - CHAR_0 ; +#if defined COMPILE_PCRE8 + if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; } +#elif defined COMPILE_PCRE16 + if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; } +#elif defined COMPILE_PCRE32 + if (utf && c > 0x10ffffU) { overflow = TRUE; break; } +#endif + } + if (overflow) + { + while (*ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++; + *errorcodeptr = ERR34; + } + else if (*ptr == CHAR_RIGHT_CURLY_BRACKET) + { + if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; + } + else *errorcodeptr = ERR80; + } + break; + + /* \x is complicated. In JavaScript, \x must be followed by two hexadecimal + numbers. Otherwise it is a lowercase x letter. */ case CHAR_x: if ((options & PCRE_JAVASCRIPT_COMPAT) != 0) { - /* In JavaScript, \x must be followed by two hexadecimal numbers. - Otherwise it is a lowercase x letter. */ if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0 && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0) { @@ -1058,73 +1314,86 @@ else #endif } } - break; - } + } /* End JavaScript handling */ - if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) + /* Handle \x in Perl's style. \x{ddd} is a character number which can be + greater than 0xff in utf or non-8bit mode, but only if the ddd are hex + digits. If not, { used to be treated as a data character. However, Perl + seems to read hex digits up to the first non-such, and ignore the rest, so + that, for example \x{zz} matches a binary zero. This seems crazy, so PCRE + now gives an error. */ + + else { - const pcre_uchar *pt = ptr + 2; - - c = 0; - overflow = FALSE; - while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) + if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) { - register pcre_uint32 cc = *pt++; - if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ + ptr += 2; + c = 0; + overflow = FALSE; + while (MAX_255(*ptr) && (digitab[*ptr] & ctype_xdigit) != 0) + { + register pcre_uint32 cc = *ptr++; + if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ #ifdef COMPILE_PCRE32 - if (c >= 0x10000000l) { overflow = TRUE; break; } + if (c >= 0x10000000l) { overflow = TRUE; break; } #endif #ifndef EBCDIC /* ASCII/UTF-8 coding */ - if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ - c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); + if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ + c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); #else /* EBCDIC coding */ - if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ - c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); + if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ + c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); #endif #if defined COMPILE_PCRE8 - if (c > (utf ? 0x10ffff : 0xff)) { overflow = TRUE; break; } + if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; } #elif defined COMPILE_PCRE16 - if (c > (utf ? 0x10ffff : 0xffff)) { overflow = TRUE; break; } + if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; } #elif defined COMPILE_PCRE32 - if (utf && c > 0x10ffff) { overflow = TRUE; break; } + if (utf && c > 0x10ffffU) { overflow = TRUE; break; } #endif - } + } - if (overflow) + if (overflow) + { + while (MAX_255(*ptr) && (digitab[*ptr] & ctype_xdigit) != 0) ptr++; + *errorcodeptr = ERR34; + } + + else if (*ptr == CHAR_RIGHT_CURLY_BRACKET) + { + if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; + } + + /* If the sequence of hex digits does not end with '}', give an error. + We used just to recognize this construct and fall through to the normal + \x handling, but nowadays Perl gives an error, which seems much more + sensible, so we do too. */ + + else *errorcodeptr = ERR79; + } /* End of \x{} processing */ + + /* Read a single-byte hex-defined char (up to two hex digits after \x) */ + + else { - while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++; - *errorcodeptr = ERR34; - } - - if (*pt == CHAR_RIGHT_CURLY_BRACKET) - { - if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; - ptr = pt; - break; - } - - /* If the sequence of hex digits does not end with '}', then we don't - recognize this construct; fall through to the normal \x handling. */ - } - - /* Read just a single-byte hex-defined char */ - - c = 0; - while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0) - { - pcre_uint32 cc; /* Some compilers don't like */ - cc = *(++ptr); /* ++ in initializers */ + c = 0; + while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0) + { + pcre_uint32 cc; /* Some compilers don't like */ + cc = *(++ptr); /* ++ in initializers */ #ifndef EBCDIC /* ASCII/UTF-8 coding */ - if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ - c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); + if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ + c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); #else /* EBCDIC coding */ - if (cc <= CHAR_z) cc += 64; /* Convert to upper case */ - c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); + if (cc <= CHAR_z) cc += 64; /* Convert to upper case */ + c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); #endif - } + } + } /* End of \xdd handling */ + } /* End of Perl-style \x handling */ break; /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped. @@ -1190,6 +1459,8 @@ if ((options & PCRE_UCP) != 0 && escape >= ESC_D && escape <= ESC_w) return escape; } + + #ifdef SUPPORT_UCP /************************************************* * Handle \P and \p * @@ -1287,7 +1558,6 @@ return FALSE; - /************************************************* * Read repeat counts * *************************************************/ @@ -1355,302 +1625,6 @@ return p; -/************************************************* -* Subroutine for finding forward reference * -*************************************************/ - -/* This recursive function is called only from find_parens() below. The -top-level call starts at the beginning of the pattern. All other calls must -start at a parenthesis. It scans along a pattern's text looking for capturing -subpatterns, and counting them. If it finds a named pattern that matches the -name it is given, it returns its number. Alternatively, if the name is NULL, it -returns when it reaches a given numbered subpattern. Recursion is used to keep -track of subpatterns that reset the capturing group numbers - the (?| feature. - -This function was originally called only from the second pass, in which we know -that if (?< or (?' or (?P< is encountered, the name will be correctly -terminated because that is checked in the first pass. There is now one call to -this function in the first pass, to check for a recursive back reference by -name (so that we can make the whole group atomic). In this case, we need check -only up to the current position in the pattern, and that is still OK because -and previous occurrences will have been checked. To make this work, the test -for "end of pattern" is a check against cd->end_pattern in the main loop, -instead of looking for a binary zero. This means that the special first-pass -call can adjust cd->end_pattern temporarily. (Checks for binary zero while -processing items within the loop are OK, because afterwards the main loop will -terminate.) - -Arguments: - ptrptr address of the current character pointer (updated) - cd compile background data - name name to seek, or NULL if seeking a numbered subpattern - lorn name length, or subpattern number if name is NULL - xmode TRUE if we are in /x mode - utf TRUE if we are in UTF-8 / UTF-16 / UTF-32 mode - count pointer to the current capturing subpattern number (updated) - -Returns: the number of the named subpattern, or -1 if not found -*/ - -static int -find_parens_sub(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn, - BOOL xmode, BOOL utf, int *count) -{ -pcre_uchar *ptr = *ptrptr; -int start_count = *count; -int hwm_count = start_count; -BOOL dup_parens = FALSE; - -/* If the first character is a parenthesis, check on the type of group we are -dealing with. The very first call may not start with a parenthesis. */ - -if (ptr[0] == CHAR_LEFT_PARENTHESIS) - { - /* Handle specials such as (*SKIP) or (*UTF8) etc. */ - - if (ptr[1] == CHAR_ASTERISK) ptr += 2; - - /* Handle a normal, unnamed capturing parenthesis. */ - - else if (ptr[1] != CHAR_QUESTION_MARK) - { - *count += 1; - if (name == NULL && *count == lorn) return *count; - ptr++; - } - - /* All cases now have (? at the start. Remember when we are in a group - where the parenthesis numbers are duplicated. */ - - else if (ptr[2] == CHAR_VERTICAL_LINE) - { - ptr += 3; - dup_parens = TRUE; - } - - /* Handle comments; all characters are allowed until a ket is reached. */ - - else if (ptr[2] == CHAR_NUMBER_SIGN) - { - for (ptr += 3; *ptr != CHAR_NULL; ptr++) - if (*ptr == CHAR_RIGHT_PARENTHESIS) break; - goto FAIL_EXIT; - } - - /* Handle a condition. If it is an assertion, just carry on so that it - is processed as normal. If not, skip to the closing parenthesis of the - condition (there can't be any nested parens). */ - - else if (ptr[2] == CHAR_LEFT_PARENTHESIS) - { - ptr += 2; - if (ptr[1] != CHAR_QUESTION_MARK) - { - while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; - if (*ptr != CHAR_NULL) ptr++; - } - } - - /* Start with (? but not a condition. */ - - else - { - ptr += 2; - if (*ptr == CHAR_P) ptr++; /* Allow optional P */ - - /* We have to disambiguate (? for named groups */ - - if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK && - ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE) - { - pcre_uchar term; - const pcre_uchar *thisname; - *count += 1; - if (name == NULL && *count == lorn) return *count; - term = *ptr++; - if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN; - thisname = ptr; - while (*ptr != term) ptr++; - if (name != NULL && lorn == (int)(ptr - thisname) && - STRNCMP_UC_UC(name, thisname, (unsigned int)lorn) == 0) - return *count; - term++; - } - } - } - -/* Past any initial parenthesis handling, scan for parentheses or vertical -bars. Stop if we get to cd->end_pattern. Note that this is important for the -first-pass call when this value is temporarily adjusted to stop at the current -position. So DO NOT change this to a test for binary zero. */ - -for (; ptr < cd->end_pattern; ptr++) - { - /* Skip over backslashed characters and also entire \Q...\E */ - - if (*ptr == CHAR_BACKSLASH) - { - if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT; - if (*ptr == CHAR_Q) for (;;) - { - while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {}; - if (*ptr == CHAR_NULL) goto FAIL_EXIT; - if (*(++ptr) == CHAR_E) break; - } - continue; - } - - /* Skip over character classes; this logic must be similar to the way they - are handled for real. If the first character is '^', skip it. Also, if the - first few characters (either before or after ^) are \Q\E or \E we skip them - too. This makes for compatibility with Perl. Note the use of STR macros to - encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */ - - if (*ptr == CHAR_LEFT_SQUARE_BRACKET) - { - BOOL negate_class = FALSE; - for (;;) - { - if (ptr[1] == CHAR_BACKSLASH) - { - if (ptr[2] == CHAR_E) - ptr+= 2; - else if (STRNCMP_UC_C8(ptr + 2, - STR_Q STR_BACKSLASH STR_E, 3) == 0) - ptr += 4; - else - break; - } - else if (!negate_class && ptr[1] == CHAR_CIRCUMFLEX_ACCENT) - { - negate_class = TRUE; - ptr++; - } - else break; - } - - /* If the next character is ']', it is a data character that must be - skipped, except in JavaScript compatibility mode. */ - - if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET && - (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0) - ptr++; - - while (*(++ptr) != CHAR_RIGHT_SQUARE_BRACKET) - { - if (*ptr == CHAR_NULL) return -1; - if (*ptr == CHAR_BACKSLASH) - { - if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT; - if (*ptr == CHAR_Q) for (;;) - { - while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {}; - if (*ptr == CHAR_NULL) goto FAIL_EXIT; - if (*(++ptr) == CHAR_E) break; - } - continue; - } - } - continue; - } - - /* Skip comments in /x mode */ - - if (xmode && *ptr == CHAR_NUMBER_SIGN) - { - ptr++; - while (*ptr != CHAR_NULL) - { - if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } - ptr++; -#ifdef SUPPORT_UTF - if (utf) FORWARDCHAR(ptr); -#endif - } - if (*ptr == CHAR_NULL) goto FAIL_EXIT; - continue; - } - - /* Check for the special metacharacters */ - - if (*ptr == CHAR_LEFT_PARENTHESIS) - { - int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count); - if (rc > 0) return rc; - if (*ptr == CHAR_NULL) goto FAIL_EXIT; - } - - else if (*ptr == CHAR_RIGHT_PARENTHESIS) - { - if (dup_parens && *count < hwm_count) *count = hwm_count; - goto FAIL_EXIT; - } - - else if (*ptr == CHAR_VERTICAL_LINE && dup_parens) - { - if (*count > hwm_count) hwm_count = *count; - *count = start_count; - } - } - -FAIL_EXIT: -*ptrptr = ptr; -return -1; -} - - - - -/************************************************* -* Find forward referenced subpattern * -*************************************************/ - -/* This function scans along a pattern's text looking for capturing -subpatterns, and counting them. If it finds a named pattern that matches the -name it is given, it returns its number. Alternatively, if the name is NULL, it -returns when it reaches a given numbered subpattern. This is used for forward -references to subpatterns. We used to be able to start this scan from the -current compiling point, using the current count value from cd->bracount, and -do it all in a single loop, but the addition of the possibility of duplicate -subpattern numbers means that we have to scan from the very start, in order to -take account of such duplicates, and to use a recursive function to keep track -of the different types of group. - -Arguments: - cd compile background data - name name to seek, or NULL if seeking a numbered subpattern - lorn name length, or subpattern number if name is NULL - xmode TRUE if we are in /x mode - utf TRUE if we are in UTF-8 / UTF-16 / UTF-32 mode - -Returns: the number of the found subpattern, or -1 if not found -*/ - -static int -find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode, - BOOL utf) -{ -pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern; -int count = 0; -int rc; - -/* If the pattern does not start with an opening parenthesis, the first call -to find_parens_sub() will scan right to the end (if necessary). However, if it -does start with a parenthesis, find_parens_sub() will return when it hits the -matching closing parens. That is why we have to have a loop. */ - -for (;;) - { - rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count); - if (rc > 0 || *ptr++ == CHAR_NULL) break; - } - -return rc; -} - - - - /************************************************* * Find first significant op code * *************************************************/ @@ -1690,9 +1664,9 @@ for (;;) case OP_CALLOUT: case OP_CREF: - case OP_NCREF: + case OP_DNCREF: case OP_RREF: - case OP_NRREF: + case OP_DNRREF: case OP_DEF: code += PRIV(OP_lengths)[*code]; break; @@ -1706,7 +1680,6 @@ for (;;) - /************************************************* * Find the fixed length of a branch * *************************************************/ @@ -1830,13 +1803,13 @@ for (;;) case OP_COMMIT: case OP_CREF: case OP_DEF: + case OP_DNCREF: + case OP_DNRREF: case OP_DOLL: case OP_DOLLM: case OP_EOD: case OP_EODN: case OP_FAIL: - case OP_NCREF: - case OP_NRREF: case OP_NOT_WORD_BOUNDARY: case OP_PRUNE: case OP_REVERSE: @@ -1931,16 +1904,20 @@ for (;;) switch (*cc) { - case OP_CRPLUS: - case OP_CRMINPLUS: case OP_CRSTAR: case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: return -1; case OP_CRRANGE: case OP_CRMINRANGE: + case OP_CRPOSRANGE: if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1; branchlength += (int)GET2(cc,1); cc += 1 + 2 * IMM2_SIZE; @@ -2009,6 +1986,8 @@ for (;;) case OP_QUERYI: case OP_REF: case OP_REFI: + case OP_DNREF: + case OP_DNREFI: case OP_SBRA: case OP_SBRAPOS: case OP_SCBRA: @@ -2045,7 +2024,6 @@ for (;;) - /************************************************* * Scan compiled regex for specific bracket * *************************************************/ @@ -2129,9 +2107,6 @@ for (;;) case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: - code += code[1]; - break; - case OP_THEN_ARG: code += code[1]; break; @@ -2249,9 +2224,6 @@ for (;;) case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: - code += code[1]; - break; - case OP_THEN_ARG: code += code[1]; break; @@ -2353,15 +2325,23 @@ Arguments: endcode points to where to stop utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode cd contains pointers to tables etc. + recurses chain of recurse_check to catch mutual recursion Returns: TRUE if what is matched could be empty */ +typedef struct recurse_check { + struct recurse_check *prev; + const pcre_uchar *group; +} recurse_check; + static BOOL could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode, - BOOL utf, compile_data *cd) + BOOL utf, compile_data *cd, recurse_check *recurses) { register pcre_uchar c; +recurse_check this_recurse; + for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); code < endcode; code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE)) @@ -2389,25 +2369,50 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); if (c == OP_RECURSE) { - const pcre_uchar *scode; + const pcre_uchar *scode = cd->start_code + GET(code, 1); BOOL empty_branch; - /* Test for forward reference */ + /* Test for forward reference or uncompleted reference. This is disabled + when called to scan a completed pattern by setting cd->start_workspace to + NULL. */ - for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE) - if ((int)GET(scode, 0) == (int)(code + 1 - cd->start_code)) return TRUE; + if (cd->start_workspace != NULL) + { + const pcre_uchar *tcode; + for (tcode = cd->start_workspace; tcode < cd->hwm; tcode += LINK_SIZE) + if ((int)GET(tcode, 0) == (int)(code + 1 - cd->start_code)) return TRUE; + if (GET(scode, 1) == 0) return TRUE; /* Unclosed */ + } - /* Not a forward reference, test for completed backward reference */ + /* If we are scanning a completed pattern, there are no forward references + and all groups are complete. We need to detect whether this is a recursive + call, as otherwise there will be an infinite loop. If it is a recursion, + just skip over it. Simple recursions are easily detected. For mutual + recursions we keep a chain on the stack. */ + + else + { + recurse_check *r = recurses; + const pcre_uchar *endgroup = scode; + + do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT); + if (code >= scode && code <= endgroup) continue; /* Simple recursion */ + + for (r = recurses; r != NULL; r = r->prev) + if (r->group == scode) break; + if (r != NULL) continue; /* Mutual recursion */ + } + + /* Completed reference; scan the referenced group, remembering it on the + stack chain to detect mutual recursions. */ empty_branch = FALSE; - scode = cd->start_code + GET(code, 1); - if (GET(scode, 1) == 0) return TRUE; /* Unclosed */ - - /* Completed backwards reference */ + this_recurse.prev = recurses; + this_recurse.group = scode; do { - if (could_be_empty_branch(scode, endcode, utf, cd)) + if (could_be_empty_branch(scode, endcode, utf, cd, &this_recurse)) { empty_branch = TRUE; break; @@ -2463,7 +2468,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); empty_branch = FALSE; do { - if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd)) + if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd, NULL)) empty_branch = TRUE; code += GET(code, 1); } @@ -2505,15 +2510,19 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSQUERY: break; default: /* Non-repeat => class must match */ case OP_CRPLUS: /* These repeats aren't empty */ case OP_CRMINPLUS: + case OP_CRPOSPLUS: return FALSE; case OP_CRRANGE: case OP_CRMINRANGE: + case OP_CRPOSRANGE: if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */ break; } @@ -2521,34 +2530,57 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); /* Opcodes that must match a character */ + case OP_ANY: + case OP_ALLANY: + case OP_ANYBYTE: + case OP_PROP: case OP_NOTPROP: + case OP_ANYNL: + + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: case OP_EXTUNI: + case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: case OP_WHITESPACE: case OP_NOT_WORDCHAR: case OP_WORDCHAR: - case OP_ANY: - case OP_ALLANY: - case OP_ANYBYTE: + case OP_CHAR: case OP_CHARI: case OP_NOT: case OP_NOTI: + case OP_PLUS: + case OP_PLUSI: case OP_MINPLUS: - case OP_POSPLUS: - case OP_EXACT: + case OP_MINPLUSI: + case OP_NOTPLUS: + case OP_NOTPLUSI: case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + + case OP_POSPLUS: + case OP_POSPLUSI: case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + + case OP_EXACT: + case OP_EXACTI: case OP_NOTEXACT: + case OP_NOTEXACTI: + case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEPOSPLUS: case OP_TYPEEXACT: + return FALSE; /* These are going to continue, as they may be empty, but we have to @@ -2582,30 +2614,58 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); return TRUE; /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO, - MINUPTO, and POSUPTO may be followed by a multibyte character */ + MINUPTO, and POSUPTO and their caseless and negative versions may be + followed by a multibyte character. */ #if defined SUPPORT_UTF && !defined COMPILE_PCRE32 case OP_STAR: case OP_STARI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_MINSTAR: case OP_MINSTARI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_POSSTAR: case OP_POSSTARI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_QUERY: case OP_QUERYI: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_MINQUERY: case OP_MINQUERYI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_POSQUERY: case OP_POSQUERYI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]); break; case OP_UPTO: case OP_UPTOI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_MINUPTO: case OP_MINUPTOI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_POSUPTO: case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]); break; #endif @@ -2616,9 +2676,6 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: - code += code[1]; - break; - case OP_THEN_ARG: code += code[1]; break; @@ -2662,7 +2719,7 @@ could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode, { while (bcptr != NULL && bcptr->current_branch >= code) { - if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd)) + if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd, NULL)) return FALSE; bcptr = bcptr->outer; } @@ -2671,6 +2728,1089 @@ return TRUE; +/************************************************* +* Base opcode of repeated opcodes * +*************************************************/ + +/* Returns the base opcode for repeated single character type opcodes. If the +opcode is not a repeated character type, it returns with the original value. + +Arguments: c opcode +Returns: base opcode for the type +*/ + +static pcre_uchar +get_repeat_base(pcre_uchar c) +{ +return (c > OP_TYPEPOSUPTO)? c : + (c >= OP_TYPESTAR)? OP_TYPESTAR : + (c >= OP_NOTSTARI)? OP_NOTSTARI : + (c >= OP_NOTSTAR)? OP_NOTSTAR : + (c >= OP_STARI)? OP_STARI : + OP_STAR; +} + + + +#ifdef SUPPORT_UCP +/************************************************* +* Check a character and a property * +*************************************************/ + +/* This function is called by check_auto_possessive() when a property item +is adjacent to a fixed character. + +Arguments: + c the character + ptype the property type + pdata the data for the type + negated TRUE if it's a negated property (\P or \p{^) + +Returns: TRUE if auto-possessifying is OK +*/ + +static BOOL +check_char_prop(pcre_uint32 c, unsigned int ptype, unsigned int pdata, + BOOL negated) +{ +const pcre_uint32 *p; +const ucd_record *prop = GET_UCD(c); + +switch(ptype) + { + case PT_LAMP: + return (prop->chartype == ucp_Lu || + prop->chartype == ucp_Ll || + prop->chartype == ucp_Lt) == negated; + + case PT_GC: + return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated; + + case PT_PC: + return (pdata == prop->chartype) == negated; + + case PT_SC: + return (pdata == prop->script) == negated; + + /* These are specials */ + + case PT_ALNUM: + return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated; + + /* Perl space used to exclude VT, but from Perl 5.18 it is included, which + means that Perl space and POSIX space are now identical. PCRE was changed + at release 8.34. */ + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + return negated; + + default: + return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated; + } + break; /* Control never reaches here */ + + case PT_WORD: + return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || + c == CHAR_UNDERSCORE) == negated; + + case PT_CLIST: + p = PRIV(ucd_caseless_sets) + prop->caseset; + for (;;) + { + if (c < *p) return !negated; + if (c == *p++) return negated; + } + break; /* Control never reaches here */ + } + +return FALSE; +} +#endif /* SUPPORT_UCP */ + + + +/************************************************* +* Fill the character property list * +*************************************************/ + +/* Checks whether the code points to an opcode that can take part in auto- +possessification, and if so, fills a list with its properties. + +Arguments: + code points to start of expression + utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode + fcc points to case-flipping table + list points to output list + list[0] will be filled with the opcode + list[1] will be non-zero if this opcode + can match an empty character string + list[2..7] depends on the opcode + +Returns: points to the start of the next opcode if *code is accepted + NULL if *code is not accepted +*/ + +static const pcre_uchar * +get_chr_property_list(const pcre_uchar *code, BOOL utf, + const pcre_uint8 *fcc, pcre_uint32 *list) +{ +pcre_uchar c = *code; +pcre_uchar base; +const pcre_uchar *end; +pcre_uint32 chr; + +#ifdef SUPPORT_UCP +pcre_uint32 *clist_dest; +const pcre_uint32 *clist_src; +#else +utf = utf; /* Suppress "unused parameter" compiler warning */ +#endif + +list[0] = c; +list[1] = FALSE; +code++; + +if (c >= OP_STAR && c <= OP_TYPEPOSUPTO) + { + base = get_repeat_base(c); + c -= (base - OP_STAR); + + if (c == OP_UPTO || c == OP_MINUPTO || c == OP_EXACT || c == OP_POSUPTO) + code += IMM2_SIZE; + + list[1] = (c != OP_PLUS && c != OP_MINPLUS && c != OP_EXACT && c != OP_POSPLUS); + + switch(base) + { + case OP_STAR: + list[0] = OP_CHAR; + break; + + case OP_STARI: + list[0] = OP_CHARI; + break; + + case OP_NOTSTAR: + list[0] = OP_NOT; + break; + + case OP_NOTSTARI: + list[0] = OP_NOTI; + break; + + case OP_TYPESTAR: + list[0] = *code; + code++; + break; + } + c = list[0]; + } + +switch(c) + { + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_ANYNL: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_EXTUNI: + case OP_EODN: + case OP_EOD: + case OP_DOLL: + case OP_DOLLM: + return code; + + case OP_CHAR: + case OP_NOT: + GETCHARINCTEST(chr, code); + list[2] = chr; + list[3] = NOTACHAR; + return code; + + case OP_CHARI: + case OP_NOTI: + list[0] = (c == OP_CHARI) ? OP_CHAR : OP_NOT; + GETCHARINCTEST(chr, code); + list[2] = chr; + +#ifdef SUPPORT_UCP + if (chr < 128 || (chr < 256 && !utf)) + list[3] = fcc[chr]; + else + list[3] = UCD_OTHERCASE(chr); +#elif defined SUPPORT_UTF || !defined COMPILE_PCRE8 + list[3] = (chr < 256) ? fcc[chr] : chr; +#else + list[3] = fcc[chr]; +#endif + + /* The othercase might be the same value. */ + + if (chr == list[3]) + list[3] = NOTACHAR; + else + list[4] = NOTACHAR; + return code; + +#ifdef SUPPORT_UCP + case OP_PROP: + case OP_NOTPROP: + if (code[0] != PT_CLIST) + { + list[2] = code[0]; + list[3] = code[1]; + return code + 2; + } + + /* Convert only if we have enough space. */ + + clist_src = PRIV(ucd_caseless_sets) + code[1]; + clist_dest = list + 2; + code += 2; + + do { + if (clist_dest >= list + 8) + { + /* Early return if there is not enough space. This should never + happen, since all clists are shorter than 5 character now. */ + list[2] = code[0]; + list[3] = code[1]; + return code; + } + *clist_dest++ = *clist_src; + } + while(*clist_src++ != NOTACHAR); + + /* All characters are stored. The terminating NOTACHAR + is copied form the clist itself. */ + + list[0] = (c == OP_PROP) ? OP_CHAR : OP_NOT; + return code; +#endif + + case OP_NCLASS: + case OP_CLASS: +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + if (c == OP_XCLASS) + end = code + GET(code, 0) - 1; + else +#endif + end = code + 32 / sizeof(pcre_uchar); + + switch(*end) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSQUERY: + list[1] = TRUE; + end++; + break; + + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRPOSPLUS: + end++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + list[1] = (GET2(end, 1) == 0); + end += 1 + 2 * IMM2_SIZE; + break; + } + list[2] = end - code; + return end; + } +return NULL; /* Opcode not accepted */ +} + + + +/************************************************* +* Scan further character sets for match * +*************************************************/ + +/* Checks whether the base and the current opcode have a common character, in +which case the base cannot be possessified. + +Arguments: + code points to the byte code + utf TRUE in UTF-8 / UTF-16 / UTF-32 mode + cd static compile data + base_list the data list of the base opcode + +Returns: TRUE if the auto-possessification is possible +*/ + +static BOOL +compare_opcodes(const pcre_uchar *code, BOOL utf, const compile_data *cd, + const pcre_uint32 *base_list, const pcre_uchar *base_end) +{ +pcre_uchar c; +pcre_uint32 list[8]; +const pcre_uint32 *chr_ptr; +const pcre_uint32 *ochr_ptr; +const pcre_uint32 *list_ptr; +const pcre_uchar *next_code; +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 +const pcre_uchar *xclass_flags; +#endif +const pcre_uint8 *class_bitset; +const pcre_uint8 *set1, *set2, *set_end; +pcre_uint32 chr; +BOOL accepted, invert_bits; + +/* Note: the base_list[1] contains whether the current opcode has greedy +(represented by a non-zero value) quantifier. This is a different from +other character type lists, which stores here that the character iterator +matches to an empty string (also represented by a non-zero value). */ + +for(;;) + { + /* All operations move the code pointer forward. + Therefore infinite recursions are not possible. */ + + c = *code; + + /* Skip over callouts */ + + if (c == OP_CALLOUT) + { + code += PRIV(OP_lengths)[c]; + continue; + } + + if (c == OP_ALT) + { + do code += GET(code, 1); while (*code == OP_ALT); + c = *code; + } + + switch(c) + { + case OP_END: + case OP_KETRPOS: + /* TRUE only in greedy case. The non-greedy case could be replaced by + an OP_EXACT, but it is probably not worth it. (And note that OP_EXACT + uses more memory, which we cannot get at this stage.) */ + + return base_list[1] != 0; + + case OP_KET: + /* If the bracket is capturing, and referenced by an OP_RECURSE, or + it is an atomic sub-pattern (assert, once, etc.) the non-greedy case + cannot be converted to a possessive form. */ + + if (base_list[1] == 0) return FALSE; + + switch(*(code - GET(code, 1))) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + /* Atomic sub-patterns and assertions can always auto-possessify their + last iterator. */ + return TRUE; + } + + code += PRIV(OP_lengths)[c]; + continue; + + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_CBRA: + next_code = code + GET(code, 1); + code += PRIV(OP_lengths)[c]; + + while (*next_code == OP_ALT) + { + if (!compare_opcodes(code, utf, cd, base_list, base_end)) return FALSE; + code = next_code + 1 + LINK_SIZE; + next_code += GET(next_code, 1); + } + continue; + + case OP_BRAZERO: + case OP_BRAMINZERO: + + next_code = code + 1; + if (*next_code != OP_BRA && *next_code != OP_CBRA + && *next_code != OP_ONCE && *next_code != OP_ONCE_NC) return FALSE; + + do next_code += GET(next_code, 1); while (*next_code == OP_ALT); + + /* The bracket content will be checked by the + OP_BRA/OP_CBRA case above. */ + next_code += 1 + LINK_SIZE; + if (!compare_opcodes(next_code, utf, cd, base_list, base_end)) + return FALSE; + + code += PRIV(OP_lengths)[c]; + continue; + } + + /* Check for a supported opcode, and load its properties. */ + + code = get_chr_property_list(code, utf, cd->fcc, list); + if (code == NULL) return FALSE; /* Unsupported */ + + /* If either opcode is a small character list, set pointers for comparing + characters from that list with another list, or with a property. */ + + if (base_list[0] == OP_CHAR) + { + chr_ptr = base_list + 2; + list_ptr = list; + } + else if (list[0] == OP_CHAR) + { + chr_ptr = list + 2; + list_ptr = base_list; + } + + /* Character bitsets can also be compared to certain opcodes. */ + + else if (base_list[0] == OP_CLASS || list[0] == OP_CLASS +#ifdef COMPILE_PCRE8 + /* In 8 bit, non-UTF mode, OP_CLASS and OP_NCLASS are the same. */ + || (!utf && (base_list[0] == OP_NCLASS || list[0] == OP_NCLASS)) +#endif + ) + { +#ifdef COMPILE_PCRE8 + if (base_list[0] == OP_CLASS || (!utf && base_list[0] == OP_NCLASS)) +#else + if (base_list[0] == OP_CLASS) +#endif + { + set1 = (pcre_uint8 *)(base_end - base_list[2]); + list_ptr = list; + } + else + { + set1 = (pcre_uint8 *)(code - list[2]); + list_ptr = base_list; + } + + invert_bits = FALSE; + switch(list_ptr[0]) + { + case OP_CLASS: + case OP_NCLASS: + set2 = (pcre_uint8 *) + ((list_ptr == list ? code : base_end) - list_ptr[2]); + break; + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + xclass_flags = (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE; + if ((*xclass_flags & XCL_HASPROP) != 0) return FALSE; + if ((*xclass_flags & XCL_MAP) == 0) + { + /* No bits are set for characters < 256. */ + if (list[1] == 0) return TRUE; + /* Might be an empty repeat. */ + continue; + } + set2 = (pcre_uint8 *)(xclass_flags + 1); + break; +#endif + + case OP_NOT_DIGIT: + invert_bits = TRUE; + /* Fall through */ + case OP_DIGIT: + set2 = (pcre_uint8 *)(cd->cbits + cbit_digit); + break; + + case OP_NOT_WHITESPACE: + invert_bits = TRUE; + /* Fall through */ + case OP_WHITESPACE: + set2 = (pcre_uint8 *)(cd->cbits + cbit_space); + break; + + case OP_NOT_WORDCHAR: + invert_bits = TRUE; + /* Fall through */ + case OP_WORDCHAR: + set2 = (pcre_uint8 *)(cd->cbits + cbit_word); + break; + + default: + return FALSE; + } + + /* Because the sets are unaligned, we need + to perform byte comparison here. */ + set_end = set1 + 32; + if (invert_bits) + { + do + { + if ((*set1++ & ~(*set2++)) != 0) return FALSE; + } + while (set1 < set_end); + } + else + { + do + { + if ((*set1++ & *set2++) != 0) return FALSE; + } + while (set1 < set_end); + } + + if (list[1] == 0) return TRUE; + /* Might be an empty repeat. */ + continue; + } + + /* Some property combinations also acceptable. Unicode property opcodes are + processed specially; the rest can be handled with a lookup table. */ + + else + { + pcre_uint32 leftop, rightop; + + leftop = base_list[0]; + rightop = list[0]; + +#ifdef SUPPORT_UCP + accepted = FALSE; /* Always set in non-unicode case. */ + if (leftop == OP_PROP || leftop == OP_NOTPROP) + { + if (rightop == OP_EOD) + accepted = TRUE; + else if (rightop == OP_PROP || rightop == OP_NOTPROP) + { + int n; + const pcre_uint8 *p; + BOOL same = leftop == rightop; + BOOL lisprop = leftop == OP_PROP; + BOOL risprop = rightop == OP_PROP; + BOOL bothprop = lisprop && risprop; + + /* There's a table that specifies how each combination is to be + processed: + 0 Always return FALSE (never auto-possessify) + 1 Character groups are distinct (possessify if both are OP_PROP) + 2 Check character categories in the same group (general or particular) + 3 Return TRUE if the two opcodes are not the same + ... see comments below + */ + + n = propposstab[base_list[2]][list[2]]; + switch(n) + { + case 0: break; + case 1: accepted = bothprop; break; + case 2: accepted = (base_list[3] == list[3]) != same; break; + case 3: accepted = !same; break; + + case 4: /* Left general category, right particular category */ + accepted = risprop && catposstab[base_list[3]][list[3]] == same; + break; + + case 5: /* Right general category, left particular category */ + accepted = lisprop && catposstab[list[3]][base_list[3]] == same; + break; + + /* This code is logically tricky. Think hard before fiddling with it. + The posspropstab table has four entries per row. Each row relates to + one of PCRE's special properties such as ALNUM or SPACE or WORD. + Only WORD actually needs all four entries, but using repeats for the + others means they can all use the same code below. + + The first two entries in each row are Unicode general categories, and + apply always, because all the characters they include are part of the + PCRE character set. The third and fourth entries are a general and a + particular category, respectively, that include one or more relevant + characters. One or the other is used, depending on whether the check + is for a general or a particular category. However, in both cases the + category contains more characters than the specials that are defined + for the property being tested against. Therefore, it cannot be used + in a NOTPROP case. + + Example: the row for WORD contains ucp_L, ucp_N, ucp_P, ucp_Po. + Underscore is covered by ucp_P or ucp_Po. */ + + case 6: /* Left alphanum vs right general category */ + case 7: /* Left space vs right general category */ + case 8: /* Left word vs right general category */ + p = posspropstab[n-6]; + accepted = risprop && lisprop == + (list[3] != p[0] && + list[3] != p[1] && + (list[3] != p[2] || !lisprop)); + break; + + case 9: /* Right alphanum vs left general category */ + case 10: /* Right space vs left general category */ + case 11: /* Right word vs left general category */ + p = posspropstab[n-9]; + accepted = lisprop && risprop == + (base_list[3] != p[0] && + base_list[3] != p[1] && + (base_list[3] != p[2] || !risprop)); + break; + + case 12: /* Left alphanum vs right particular category */ + case 13: /* Left space vs right particular category */ + case 14: /* Left word vs right particular category */ + p = posspropstab[n-12]; + accepted = risprop && lisprop == + (catposstab[p[0]][list[3]] && + catposstab[p[1]][list[3]] && + (list[3] != p[3] || !lisprop)); + break; + + case 15: /* Right alphanum vs left particular category */ + case 16: /* Right space vs left particular category */ + case 17: /* Right word vs left particular category */ + p = posspropstab[n-15]; + accepted = lisprop && risprop == + (catposstab[p[0]][base_list[3]] && + catposstab[p[1]][base_list[3]] && + (base_list[3] != p[3] || !risprop)); + break; + } + } + } + + else +#endif /* SUPPORT_UCP */ + + accepted = leftop >= FIRST_AUTOTAB_OP && leftop <= LAST_AUTOTAB_LEFT_OP && + rightop >= FIRST_AUTOTAB_OP && rightop <= LAST_AUTOTAB_RIGHT_OP && + autoposstab[leftop - FIRST_AUTOTAB_OP][rightop - FIRST_AUTOTAB_OP]; + + if (!accepted) + return FALSE; + + if (list[1] == 0) return TRUE; + /* Might be an empty repeat. */ + continue; + } + + /* Control reaches here only if one of the items is a small character list. + All characters are checked against the other side. */ + + do + { + chr = *chr_ptr; + + switch(list_ptr[0]) + { + case OP_CHAR: + ochr_ptr = list_ptr + 2; + do + { + if (chr == *ochr_ptr) return FALSE; + ochr_ptr++; + } + while(*ochr_ptr != NOTACHAR); + break; + + case OP_NOT: + ochr_ptr = list_ptr + 2; + do + { + if (chr == *ochr_ptr) + break; + ochr_ptr++; + } + while(*ochr_ptr != NOTACHAR); + if (*ochr_ptr == NOTACHAR) return FALSE; /* Not found */ + break; + + /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* + set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ + + case OP_DIGIT: + if (chr < 256 && (cd->ctypes[chr] & ctype_digit) != 0) return FALSE; + break; + + case OP_NOT_DIGIT: + if (chr > 255 || (cd->ctypes[chr] & ctype_digit) == 0) return FALSE; + break; + + case OP_WHITESPACE: + if (chr < 256 && (cd->ctypes[chr] & ctype_space) != 0) return FALSE; + break; + + case OP_NOT_WHITESPACE: + if (chr > 255 || (cd->ctypes[chr] & ctype_space) == 0) return FALSE; + break; + + case OP_WORDCHAR: + if (chr < 255 && (cd->ctypes[chr] & ctype_word) != 0) return FALSE; + break; + + case OP_NOT_WORDCHAR: + if (chr > 255 || (cd->ctypes[chr] & ctype_word) == 0) return FALSE; + break; + + case OP_HSPACE: + switch(chr) + { + HSPACE_CASES: return FALSE; + default: break; + } + break; + + case OP_NOT_HSPACE: + switch(chr) + { + HSPACE_CASES: break; + default: return FALSE; + } + break; + + case OP_ANYNL: + case OP_VSPACE: + switch(chr) + { + VSPACE_CASES: return FALSE; + default: break; + } + break; + + case OP_NOT_VSPACE: + switch(chr) + { + VSPACE_CASES: break; + default: return FALSE; + } + break; + + case OP_DOLL: + case OP_EODN: + switch (chr) + { + case CHAR_CR: + case CHAR_LF: + case CHAR_VT: + case CHAR_FF: + case CHAR_NEL: +#ifndef EBCDIC + case 0x2028: + case 0x2029: +#endif /* Not EBCDIC */ + return FALSE; + } + break; + + case OP_EOD: /* Can always possessify before \z */ + break; + +#ifdef SUPPORT_UCP + case OP_PROP: + case OP_NOTPROP: + if (!check_char_prop(chr, list_ptr[2], list_ptr[3], + list_ptr[0] == OP_NOTPROP)) + return FALSE; + break; +#endif + + case OP_NCLASS: + if (chr > 255) return FALSE; + /* Fall through */ + + case OP_CLASS: + if (chr > 255) break; + class_bitset = (pcre_uint8 *) + ((list_ptr == list ? code : base_end) - list_ptr[2]); + if ((class_bitset[chr >> 3] & (1 << (chr & 7))) != 0) return FALSE; + break; + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) - + list_ptr[2] + LINK_SIZE, utf)) return FALSE; + break; +#endif + + default: + return FALSE; + } + + chr_ptr++; + } + while(*chr_ptr != NOTACHAR); + + /* At least one character must be matched from this opcode. */ + + if (list[1] == 0) return TRUE; + } + +/* Control never reaches here. There used to be a fail-save return FALSE; here, +but some compilers complain about an unreachable statement. */ + +} + + + +/************************************************* +* Scan compiled regex for auto-possession * +*************************************************/ + +/* Replaces single character iterations with their possessive alternatives +if appropriate. This function modifies the compiled opcode! + +Arguments: + code points to start of the byte code + utf TRUE in UTF-8 / UTF-16 / UTF-32 mode + cd static compile data + +Returns: nothing +*/ + +static void +auto_possessify(pcre_uchar *code, BOOL utf, const compile_data *cd) +{ +register pcre_uchar c; +const pcre_uchar *end; +pcre_uchar *repeat_opcode; +pcre_uint32 list[8]; + +for (;;) + { + c = *code; + + if (c >= OP_STAR && c <= OP_TYPEPOSUPTO) + { + c -= get_repeat_base(c) - OP_STAR; + end = (c <= OP_MINUPTO) ? + get_chr_property_list(code, utf, cd->fcc, list) : NULL; + list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO; + + if (end != NULL && compare_opcodes(end, utf, cd, list, end)) + { + switch(c) + { + case OP_STAR: + *code += OP_POSSTAR - OP_STAR; + break; + + case OP_MINSTAR: + *code += OP_POSSTAR - OP_MINSTAR; + break; + + case OP_PLUS: + *code += OP_POSPLUS - OP_PLUS; + break; + + case OP_MINPLUS: + *code += OP_POSPLUS - OP_MINPLUS; + break; + + case OP_QUERY: + *code += OP_POSQUERY - OP_QUERY; + break; + + case OP_MINQUERY: + *code += OP_POSQUERY - OP_MINQUERY; + break; + + case OP_UPTO: + *code += OP_POSUPTO - OP_UPTO; + break; + + case OP_MINUPTO: + *code += OP_POSUPTO - OP_MINUPTO; + break; + } + } + c = *code; + } + else if (c == OP_CLASS || c == OP_NCLASS || c == OP_XCLASS) + { +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + if (c == OP_XCLASS) + repeat_opcode = code + GET(code, 1); + else +#endif + repeat_opcode = code + 1 + (32 / sizeof(pcre_uchar)); + + c = *repeat_opcode; + if (c >= OP_CRSTAR && c <= OP_CRMINRANGE) + { + /* end must not be NULL. */ + end = get_chr_property_list(code, utf, cd->fcc, list); + + list[1] = (c & 1) == 0; + + if (compare_opcodes(end, utf, cd, list, end)) + { + switch (c) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + *repeat_opcode = OP_CRPOSSTAR; + break; + + case OP_CRPLUS: + case OP_CRMINPLUS: + *repeat_opcode = OP_CRPOSPLUS; + break; + + case OP_CRQUERY: + case OP_CRMINQUERY: + *repeat_opcode = OP_CRPOSQUERY; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + *repeat_opcode = OP_CRPOSRANGE; + break; + } + } + } + c = *code; + } + + switch(c) + { + case OP_END: + return; + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; + break; + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSUPTO: + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + code += 2; + break; + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + code += GET(code, 1); + break; +#endif + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + code += code[1]; + break; + } + + /* Add in the fixed length from the table */ + + code += PRIV(OP_lengths)[c]; + + /* In UTF-8 mode, opcodes that are followed by a character may be followed by + a multi-byte character. The length in the table is a minimum, so we have to + arrange to skip the extra bytes. */ + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (utf) switch(c) + { + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); + break; + } +#else + (void)(utf); /* Keep compiler happy by referencing function argument */ +#endif + } +} + + + /************************************************* * Check for POSIX class syntax * *************************************************/ @@ -2692,7 +3832,7 @@ class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code below handles the special case of \], but does not try to do any other escape processing. This makes it different from Perl for cases such as [:l\ower:] where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize -"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does, +"l\ower". This is a lesser evil than not diagnosing bad classes when Perl does, I think. A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not. @@ -2941,12 +4081,16 @@ for (c = *cptr; c <= d; c++) if (c > d) return -1; /* Reached end of range */ +/* Found a character that has a single other case. Search for the end of the +range, which is either the end of the input range, or a character that has zero +or more than one other cases. */ + *ocptr = othercase; next = othercase + 1; for (++c; c <= d; c++) { - if (UCD_OTHERCASE(c) != next) break; + if ((co = UCD_CASESET(c)) != 0 || UCD_OTHERCASE(c) != next) break; next++; } @@ -2954,475 +4098,10 @@ for (++c; c <= d; c++) *cptr = c; /* Rest of input range */ return 0; } - - - -/************************************************* -* Check a character and a property * -*************************************************/ - -/* This function is called by check_auto_possessive() when a property item -is adjacent to a fixed character. - -Arguments: - c the character - ptype the property type - pdata the data for the type - negated TRUE if it's a negated property (\P or \p{^) - -Returns: TRUE if auto-possessifying is OK -*/ - -static BOOL -check_char_prop(pcre_uint32 c, unsigned int ptype, unsigned int pdata, BOOL negated) -{ -#ifdef SUPPORT_UCP -const pcre_uint32 *p; -#endif - -const ucd_record *prop = GET_UCD(c); - -switch(ptype) - { - case PT_LAMP: - return (prop->chartype == ucp_Lu || - prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt) == negated; - - case PT_GC: - return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated; - - case PT_PC: - return (pdata == prop->chartype) == negated; - - case PT_SC: - return (pdata == prop->script) == negated; - - /* These are specials */ - - case PT_ALNUM: - return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated; - - case PT_SPACE: /* Perl space */ - return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) - == negated; - - case PT_PXSPACE: /* POSIX space */ - return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || - c == CHAR_FF || c == CHAR_CR) - == negated; - - case PT_WORD: - return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE) == negated; - -#ifdef SUPPORT_UCP - case PT_CLIST: - p = PRIV(ucd_caseless_sets) + prop->caseset; - for (;;) - { - if (c < *p) return !negated; - if (c == *p++) return negated; - } - break; /* Control never reaches here */ -#endif - } - -return FALSE; -} #endif /* SUPPORT_UCP */ -/************************************************* -* Check if auto-possessifying is possible * -*************************************************/ - -/* This function is called for unlimited repeats of certain items, to see -whether the next thing could possibly match the repeated item. If not, it makes -sense to automatically possessify the repeated item. - -Arguments: - previous pointer to the repeated opcode - utf TRUE in UTF-8 / UTF-16 / UTF-32 mode - ptr next character in pattern - options options bits - cd contains pointers to tables etc. - -Returns: TRUE if possessifying is wanted -*/ - -static BOOL -check_auto_possessive(const pcre_uchar *previous, BOOL utf, - const pcre_uchar *ptr, int options, compile_data *cd) -{ -pcre_uint32 c = NOTACHAR; -pcre_uint32 next; -int escape; -pcre_uchar op_code = *previous++; - -/* Skip whitespace and comments in extended mode */ - -if ((options & PCRE_EXTENDED) != 0) - { - for (;;) - { - while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++; - if (*ptr == CHAR_NUMBER_SIGN) - { - ptr++; - while (*ptr != CHAR_NULL) - { - if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } - ptr++; -#ifdef SUPPORT_UTF - if (utf) FORWARDCHAR(ptr); -#endif - } - } - else break; - } - } - -/* If the next item is one that we can handle, get its value. A non-negative -value is a character, a negative value is an escape value. */ - -if (*ptr == CHAR_BACKSLASH) - { - int temperrorcode = 0; - escape = check_escape(&ptr, &next, &temperrorcode, cd->bracount, options, FALSE); - if (temperrorcode != 0) return FALSE; - ptr++; /* Point after the escape sequence */ - } -else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0) - { - escape = 0; -#ifdef SUPPORT_UTF - if (utf) { GETCHARINC(next, ptr); } else -#endif - next = *ptr++; - } -else return FALSE; - -/* Skip whitespace and comments in extended mode */ - -if ((options & PCRE_EXTENDED) != 0) - { - for (;;) - { - while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++; - if (*ptr == CHAR_NUMBER_SIGN) - { - ptr++; - while (*ptr != CHAR_NULL) - { - if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } - ptr++; -#ifdef SUPPORT_UTF - if (utf) FORWARDCHAR(ptr); -#endif - } - } - else break; - } - } - -/* If the next thing is itself optional, we have to give up. */ - -if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || - STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) - return FALSE; - -/* If the previous item is a character, get its value. */ - -if (op_code == OP_CHAR || op_code == OP_CHARI || - op_code == OP_NOT || op_code == OP_NOTI) - { -#ifdef SUPPORT_UTF - GETCHARTEST(c, previous); -#else - c = *previous; -#endif - } - -/* Now compare the next item with the previous opcode. First, handle cases when -the next item is a character. */ - -if (escape == 0) - { - /* For a caseless UTF match, the next character may have more than one other - case, which maps to the special PT_CLIST property. Check this first. */ - -#ifdef SUPPORT_UCP - if (utf && c != NOTACHAR && (options & PCRE_CASELESS) != 0) - { - unsigned int ocs = UCD_CASESET(next); - if (ocs > 0) return check_char_prop(c, PT_CLIST, ocs, op_code >= OP_NOT); - } -#endif - - switch(op_code) - { - case OP_CHAR: - return c != next; - - /* For CHARI (caseless character) we must check the other case. If we have - Unicode property support, we can use it to test the other case of - high-valued characters. We know that next can have only one other case, - because multi-other-case characters are dealt with above. */ - - case OP_CHARI: - if (c == next) return FALSE; -#ifdef SUPPORT_UTF - if (utf) - { - pcre_uint32 othercase; - if (next < 128) othercase = cd->fcc[next]; else -#ifdef SUPPORT_UCP - othercase = UCD_OTHERCASE(next); -#else - othercase = NOTACHAR; -#endif - return c != othercase; - } - else -#endif /* SUPPORT_UTF */ - return (c != TABLE_GET(next, cd->fcc, next)); /* Not UTF */ - - case OP_NOT: - return c == next; - - case OP_NOTI: - if (c == next) return TRUE; -#ifdef SUPPORT_UTF - if (utf) - { - pcre_uint32 othercase; - if (next < 128) othercase = cd->fcc[next]; else -#ifdef SUPPORT_UCP - othercase = UCD_OTHERCASE(next); -#else - othercase = NOTACHAR; -#endif - return c == othercase; - } - else -#endif /* SUPPORT_UTF */ - return (c == TABLE_GET(next, cd->fcc, next)); /* Not UTF */ - - /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set. - When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ - - case OP_DIGIT: - return next > 255 || (cd->ctypes[next] & ctype_digit) == 0; - - case OP_NOT_DIGIT: - return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0; - - case OP_WHITESPACE: - return next > 255 || (cd->ctypes[next] & ctype_space) == 0; - - case OP_NOT_WHITESPACE: - return next <= 255 && (cd->ctypes[next] & ctype_space) != 0; - - case OP_WORDCHAR: - return next > 255 || (cd->ctypes[next] & ctype_word) == 0; - - case OP_NOT_WORDCHAR: - return next <= 255 && (cd->ctypes[next] & ctype_word) != 0; - - case OP_HSPACE: - case OP_NOT_HSPACE: - switch(next) - { - HSPACE_CASES: - return op_code == OP_NOT_HSPACE; - - default: - return op_code != OP_NOT_HSPACE; - } - - case OP_ANYNL: - case OP_VSPACE: - case OP_NOT_VSPACE: - switch(next) - { - VSPACE_CASES: - return op_code == OP_NOT_VSPACE; - - default: - return op_code != OP_NOT_VSPACE; - } - -#ifdef SUPPORT_UCP - case OP_PROP: - return check_char_prop(next, previous[0], previous[1], FALSE); - - case OP_NOTPROP: - return check_char_prop(next, previous[0], previous[1], TRUE); -#endif - - default: - return FALSE; - } - } - -/* Handle the case when the next item is \d, \s, etc. Note that when PCRE_UCP -is set, \d turns into ESC_du rather than ESC_d, etc., so ESC_d etc. are -generated only when PCRE_UCP is *not* set, that is, when only ASCII -characteristics are recognized. Similarly, the opcodes OP_DIGIT etc. are -replaced by OP_PROP codes when PCRE_UCP is set. */ - -switch(op_code) - { - case OP_CHAR: - case OP_CHARI: - switch(escape) - { - case ESC_d: - return c > 255 || (cd->ctypes[c] & ctype_digit) == 0; - - case ESC_D: - return c <= 255 && (cd->ctypes[c] & ctype_digit) != 0; - - case ESC_s: - return c > 255 || (cd->ctypes[c] & ctype_space) == 0; - - case ESC_S: - return c <= 255 && (cd->ctypes[c] & ctype_space) != 0; - - case ESC_w: - return c > 255 || (cd->ctypes[c] & ctype_word) == 0; - - case ESC_W: - return c <= 255 && (cd->ctypes[c] & ctype_word) != 0; - - case ESC_h: - case ESC_H: - switch(c) - { - HSPACE_CASES: - return escape != ESC_h; - - default: - return escape == ESC_h; - } - - case ESC_v: - case ESC_V: - switch(c) - { - VSPACE_CASES: - return escape != ESC_v; - - default: - return escape == ESC_v; - } - - /* When PCRE_UCP is set, these values get generated for \d etc. Find - their substitutions and process them. The result will always be either - ESC_p or ESC_P. Then fall through to process those values. */ - -#ifdef SUPPORT_UCP - case ESC_du: - case ESC_DU: - case ESC_wu: - case ESC_WU: - case ESC_su: - case ESC_SU: - { - int temperrorcode = 0; - ptr = substitutes[escape - ESC_DU]; - escape = check_escape(&ptr, &next, &temperrorcode, 0, options, FALSE); - if (temperrorcode != 0) return FALSE; - ptr++; /* For compatibility */ - } - /* Fall through */ - - case ESC_p: - case ESC_P: - { - unsigned int ptype = 0, pdata = 0; - int errorcodeptr; - BOOL negated; - - ptr--; /* Make ptr point at the p or P */ - if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcodeptr)) - return FALSE; - ptr++; /* Point past the final curly ket */ - - /* If the property item is optional, we have to give up. (When generated - from \d etc by PCRE_UCP, this test will have been applied much earlier, - to the original \d etc. At this point, ptr will point to a zero byte. */ - - if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || - STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) - return FALSE; - - /* Do the property check. */ - - return check_char_prop(c, ptype, pdata, (escape == ESC_P) != negated); - } -#endif - - default: - return FALSE; - } - - /* In principle, support for Unicode properties should be integrated here as - well. It means re-organizing the above code so as to get hold of the property - values before switching on the op-code. However, I wonder how many patterns - combine ASCII \d etc with Unicode properties? (Note that if PCRE_UCP is set, - these op-codes are never generated.) */ - - case OP_DIGIT: - return escape == ESC_D || escape == ESC_s || escape == ESC_W || - escape == ESC_h || escape == ESC_v || escape == ESC_R; - - case OP_NOT_DIGIT: - return escape == ESC_d; - - case OP_WHITESPACE: - return escape == ESC_S || escape == ESC_d || escape == ESC_w; - - case OP_NOT_WHITESPACE: - return escape == ESC_s || escape == ESC_h || escape == ESC_v || escape == ESC_R; - - case OP_HSPACE: - return escape == ESC_S || escape == ESC_H || escape == ESC_d || - escape == ESC_w || escape == ESC_v || escape == ESC_R; - - case OP_NOT_HSPACE: - return escape == ESC_h; - - /* Can't have \S in here because VT matches \S (Perl anomaly) */ - case OP_ANYNL: - case OP_VSPACE: - return escape == ESC_V || escape == ESC_d || escape == ESC_w; - - case OP_NOT_VSPACE: - return escape == ESC_v || escape == ESC_R; - - case OP_WORDCHAR: - return escape == ESC_W || escape == ESC_s || escape == ESC_h || - escape == ESC_v || escape == ESC_R; - - case OP_NOT_WORDCHAR: - return escape == ESC_w || escape == ESC_d; - - default: - return FALSE; - } - -/* Control does not reach here */ -} - - - /************************************************* * Add a character or range to a class * *************************************************/ @@ -3449,6 +4128,7 @@ add_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr, int options, compile_data *cd, pcre_uint32 start, pcre_uint32 end) { pcre_uint32 c; +pcre_uint32 classbits_end = (end <= 0xff ? end : 0xff); int n8 = 0; /* If caseless matching is required, scan the range and process alternate @@ -3492,7 +4172,7 @@ if ((options & PCRE_CASELESS) != 0) /* Not UTF-mode, or no UCP */ - for (c = start; c <= end && c < 256; c++) + for (c = start; c <= classbits_end; c++) { SETBIT(classbits, cd->fcc[c]); n8++; @@ -3517,22 +4197,21 @@ in all cases. */ #endif /* COMPILE_PCRE[8|16] */ -/* If all characters are less than 256, use the bit map. Otherwise use extra -data. */ +/* Use the bitmap for characters < 256. Otherwise use extra data.*/ -if (end < 0x100) +for (c = start; c <= classbits_end; c++) { - for (c = start; c <= end; c++) - { - n8++; - SETBIT(classbits, c); - } + /* Regardless of start, c will always be <= 255. */ + SETBIT(classbits, c); + n8++; } -else +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 +if (start <= 0xff) start = 0xff + 1; + +if (end >= start) { pcre_uchar *uchardata = *uchardptr; - #ifdef SUPPORT_UTF if ((options & PCRE_UTF8) != 0) /* All UTFs use the same flag bit */ { @@ -3572,6 +4251,7 @@ else *uchardptr = uchardata; /* Updata extra data pointer */ } +#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ return n8; /* Number of 8-bit characters */ } @@ -3672,22 +4352,22 @@ to find out the amount of memory needed, as well as during the real compile phase. The value of lengthptr distinguishes the two phases. Arguments: - optionsptr pointer to the option bits - codeptr points to the pointer to the current code point - ptrptr points to the current pattern pointer - errorcodeptr points to error code variable - firstcharptr place to put the first required character + optionsptr pointer to the option bits + codeptr points to the pointer to the current code point + ptrptr points to the current pattern pointer + errorcodeptr points to error code variable + firstcharptr place to put the first required character firstcharflagsptr place to put the first character flags, or a negative number - reqcharptr place to put the last required character - reqcharflagsptr place to put the last required character flags, or a negative number - bcptr points to current branch chain - cond_depth conditional nesting depth - cd contains pointers to tables etc. - lengthptr NULL during the real compile phase - points to length accumulator during pre-compile phase + reqcharptr place to put the last required character + reqcharflagsptr place to put the last required character flags, or a negative number + bcptr points to current branch chain + cond_depth conditional nesting depth + cd contains pointers to tables etc. + lengthptr NULL during the real compile phase + points to length accumulator during pre-compile phase -Returns: TRUE on success - FALSE, with *errorcodeptr set non-zero on error +Returns: TRUE on success + FALSE, with *errorcodeptr set non-zero on error */ static BOOL @@ -3793,6 +4473,9 @@ for (;; ptr++) BOOL reset_bracount; int class_has_8bitchar; int class_one_char; +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + BOOL xclass_has_prop; +#endif int newoptions; int recno; int refsign; @@ -3910,16 +4593,45 @@ for (;; ptr++) } goto NORMAL_CHAR; } + /* Control does not reach here. */ } - /* Fill in length of a previous callout, except when the next thing is - a quantifier. */ + /* In extended mode, skip white space and comments. We need a loop in order + to check for more white space and more comments after a comment. */ + + if ((options & PCRE_EXTENDED) != 0) + { + for (;;) + { + while (MAX_255(c) && (cd->ctypes[c] & ctype_space) != 0) c = *(++ptr); + if (c != CHAR_NUMBER_SIGN) break; + ptr++; + while (*ptr != CHAR_NULL) + { + if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */ + { /* IS_NEWLINE sets cd->nllen. */ + ptr += cd->nllen; + break; + } + ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); +#endif + } + c = *ptr; /* Either NULL or the char after a newline */ + } + } + + /* See if the next thing is a quantifier. */ is_quantifier = c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK || (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1)); - if (!is_quantifier && previous_callout != NULL && + /* Fill in length of a previous callout, except when the next thing is a + quantifier or when processing a property substitution string in UCP mode. */ + + if (!is_quantifier && previous_callout != NULL && nestptr == NULL && after_manual_callout-- <= 0) { if (lengthptr == NULL) /* Don't attempt in pre-compile phase */ @@ -3927,41 +4639,21 @@ for (;; ptr++) previous_callout = NULL; } - /* In extended mode, skip white space and comments. */ + /* Create auto callout, except for quantifiers, or while processing property + strings that are substituted for \w etc in UCP mode. */ - if ((options & PCRE_EXTENDED) != 0) - { - if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue; - if (c == CHAR_NUMBER_SIGN) - { - ptr++; - while (*ptr != CHAR_NULL) - { - if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } - ptr++; -#ifdef SUPPORT_UTF - if (utf) FORWARDCHAR(ptr); -#endif - } - if (*ptr != CHAR_NULL) continue; - - /* Else fall through to handle end of string */ - c = 0; - } - } - - /* No auto callout for quantifiers. */ - - if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier) + if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier && nestptr == NULL) { previous_callout = code; code = auto_callout(code, ptr, cd); } + /* Process the next pattern item. */ + switch(c) { /* ===================================================================*/ - case 0: /* The branch terminates at string end */ + case CHAR_NULL: /* The branch terminates at string end */ case CHAR_VERTICAL_LINE: /* or | or ) */ case CHAR_RIGHT_PARENTHESIS: *firstcharptr = firstchar; @@ -4039,7 +4731,29 @@ for (;; ptr++) } goto NORMAL_CHAR; + /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is + used for "start of word" and "end of word". As these are otherwise illegal + sequences, we don't break anything by recognizing them. They are replaced + by \b(?=\w) and \b(?<=\w) respectively. Sequences like [a[:<:]] are + erroneous and are handled by the normal code below. */ + case CHAR_LEFT_SQUARE_BRACKET: + if (STRNCMP_UC_C8(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0) + { + nestptr = ptr + 7; + ptr = sub_start_of_word - 1; + continue; + } + + if (STRNCMP_UC_C8(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0) + { + nestptr = ptr + 7; + ptr = sub_end_of_word - 1; + continue; + } + + /* Handle a real character class. */ + previous = code; /* PCRE supports POSIX class stuff inside a class. Perl gives an error if @@ -4096,13 +4810,26 @@ for (;; ptr++) should_flip_negation = FALSE; + /* Extended class (xclass) will be used when characters > 255 + might match. */ + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + xclass = FALSE; + class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */ + class_uchardata_base = class_uchardata; /* Save the start */ +#endif + /* 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_one_char will be 1 if the class contains just one - character. */ + character; xclass_has_prop will be TRUE if unicode property checks + are present in the class. */ class_has_8bitchar = 0; class_one_char = 0; +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + xclass_has_prop = FALSE; +#endif /* Initialize the 32-char bit map to all zeros. We build the map in a temporary bit of memory, in case the class contains fewer than two @@ -4111,12 +4838,6 @@ for (;; ptr++) memset(classbits, 0, 32 * sizeof(pcre_uint8)); -#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 - xclass = FALSE; - class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */ - class_uchardata_base = class_uchardata; /* Save the start */ -#endif - /* Process characters until ] is reached. By writing this as a "do" it means that an initial ] is taken as a data character. At the start of the loop, c contains the first byte of the character. */ @@ -4204,24 +4925,59 @@ for (;; ptr++) posix_class = 0; /* When PCRE_UCP is set, some of the POSIX classes are converted to - different escape sequences that use Unicode properties. */ + different escape sequences that use Unicode properties \p or \P. Others + that are not available via \p or \P generate XCL_PROP/XCL_NOTPROP + directly. */ #ifdef SUPPORT_UCP if ((options & PCRE_UCP) != 0) { + unsigned int ptype = 0; int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0); + + /* The posix_substitutes table specifies which POSIX classes can be + converted to \p or \P items. */ + if (posix_substitutes[pc] != NULL) { nestptr = tempptr + 1; ptr = posix_substitutes[pc] - 1; continue; } + + /* There are three other classes that generate special property calls + that are recognized only in an XCLASS. */ + + else switch(posix_class) + { + case PC_GRAPH: + ptype = PT_PXGRAPH; + /* Fall through */ + case PC_PRINT: + if (ptype == 0) ptype = PT_PXPRINT; + /* Fall through */ + case PC_PUNCT: + if (ptype == 0) ptype = PT_PXPUNCT; + *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; + *class_uchardata++ = ptype; + *class_uchardata++ = 0; + xclass_has_prop = TRUE; + ptr = tempptr + 1; + continue; + + /* For all other POSIX classes, no special action is taken in UCP + mode. Fall through to the non_UCP case. */ + + default: + break; + } } #endif - /* In the non-UCP case, we build the bit map for the POSIX class in a - chunk of local store because we may be adding and subtracting from it, - and we don't want to subtract bits that may be in the main map already. - At the end we or the result into the bit map that is being built. */ + /* In the non-UCP case, or when UCP makes no difference, we build the + bit map for the POSIX class in a chunk of local store because we may be + adding and subtracting from it, and we don't want to subtract bits that + may be in the main map already. At the end we or the result into the + bit map that is being built. */ posix_class *= 3; @@ -4277,14 +5033,12 @@ for (;; ptr++) if (c == CHAR_BACKSLASH) { - escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, TRUE); - + escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, + TRUE); if (*errorcodeptr != 0) goto FAILED; - - if (escape == 0) - c = ec; + if (escape == 0) c = ec; else if (escape == ESC_b) c = CHAR_BS; /* \b is backspace in a class */ - else if (escape == ESC_N) /* \N is not supported in a class */ + else if (escape == ESC_N) /* \N is not supported in a class */ { *errorcodeptr = ERR71; goto FAILED; @@ -4340,21 +5094,20 @@ for (;; ptr++) for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word]; continue; - /* Perl 5.004 onwards omits VT from \s, but we must preserve it - if it was previously set by something earlier in the character - class. Luckily, the value of CHAR_VT is 0x0b in both ASCII and - EBCDIC, so we lazily just adjust the appropriate bit. */ + /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl + 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was + previously set by something earlier in the character class. + Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so + we could just adjust the appropriate bit. From PCRE 8.34 we no + longer treat \s and \S specially. */ case ESC_s: - classbits[0] |= cbits[cbit_space]; - classbits[1] |= cbits[cbit_space+1] & ~0x08; - for (c = 2; c < 32; c++) classbits[c] |= cbits[c+cbit_space]; + for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_space]; continue; case ESC_S: should_flip_negation = TRUE; for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space]; - classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */ continue; /* The rest apply in both UCP and non-UCP cases. */ @@ -4391,6 +5144,7 @@ for (;; ptr++) XCL_PROP : XCL_NOTPROP; *class_uchardata++ = ptype; *class_uchardata++ = pdata; + xclass_has_prop = TRUE; class_has_8bitchar--; /* Undo! */ continue; } @@ -4476,26 +5230,43 @@ for (;; ptr++) #endif d = *ptr; /* Not UTF-8 mode */ - /* The second part of a range can be a single-character escape, but - not any of the other escapes. Perl 5.6 treats a hyphen as a literal - in such circumstances. */ + /* The second part of a range can be a single-character escape + sequence, but not any of the other escapes. Perl treats a hyphen as a + literal in such circumstances. However, in Perl's warning mode, a + warning is given, so PCRE now faults it as it is almost certainly a + mistake on the user's part. */ - if (!inescq && d == CHAR_BACKSLASH) + if (!inescq) { - int descape; - descape = check_escape(&ptr, &d, errorcodeptr, cd->bracount, options, TRUE); - if (*errorcodeptr != 0) goto FAILED; - - /* \b is backspace; any other special means the '-' was literal. */ - - if (descape != 0) + if (d == CHAR_BACKSLASH) { - if (descape == ESC_b) d = CHAR_BS; else + int descape; + descape = check_escape(&ptr, &d, errorcodeptr, cd->bracount, options, TRUE); + if (*errorcodeptr != 0) goto FAILED; + + /* 0 means a character was put into d; \b is backspace; any other + special causes an error. */ + + if (descape != 0) { - ptr = oldptr; - goto CLASS_SINGLE_CHARACTER; /* A few lines below */ + if (descape == ESC_b) d = CHAR_BS; else + { + *errorcodeptr = ERR83; + goto FAILED; + } } } + + /* A hyphen followed by a POSIX class is treated in the same way. */ + + else if (d == CHAR_LEFT_SQUARE_BRACKET && + (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || + ptr[1] == CHAR_EQUALS_SIGN) && + check_posix_syntax(ptr, &tempptr)) + { + *errorcodeptr = ERR83; + goto FAILED; + } } /* Check that the two values are in the correct order. Optimize @@ -4668,6 +5439,7 @@ for (;; ptr++) *code++ = OP_XCLASS; code += LINK_SIZE; *code = negate_class? XCL_NOT:0; + if (xclass_has_prop) *code |= XCL_HASPROP; /* 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. */ @@ -4677,6 +5449,8 @@ for (;; ptr++) *code++ |= XCL_MAP; memmove(code + (32 / sizeof(pcre_uchar)), code, IN_UCHARS(class_uchardata - code)); + if (negate_class && !xclass_has_prop) + for (c = 0; c < 32; c++) classbits[c] = ~classbits[c]; memcpy(code, classbits, 32); code = class_uchardata + (32 / sizeof(pcre_uchar)); } @@ -4759,6 +5533,34 @@ for (;; ptr++) tempcode = previous; + /* Before checking for a possessive quantifier, we must skip over + whitespace and comments in extended mode because Perl allows white space at + this point. */ + + if ((options & PCRE_EXTENDED) != 0) + { + const pcre_uchar *p = ptr + 1; + for (;;) + { + while (MAX_255(*p) && (cd->ctypes[*p] & ctype_space) != 0) p++; + if (*p != CHAR_NUMBER_SIGN) break; + p++; + while (*p != CHAR_NULL) + { + if (IS_NEWLINE(p)) /* For non-fixed-length newline cases, */ + { /* IS_NEWLINE sets cd->nllen. */ + p += cd->nllen; + break; + } + p++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(p); +#endif + } /* Loop for comment characters */ + } /* Loop for multiple comments */ + ptr = p - 1; /* Character before the next significant one. */ + } + /* If the next character is '+', we have a possessive quantifier. This implies greediness, whatever the setting of the PCRE_UNGREEDY option. If the next character is '?' this is a minimizing repeat, by default, @@ -4853,19 +5655,6 @@ for (;; ptr++) } } - /* If the repetition is unlimited, it pays to see if the next thing on - the line is something that cannot possibly match this character. If so, - automatically possessifying this item gains some performance in the case - where the match fails. */ - - if (!possessive_quantifier && - repeat_max < 0 && - check_auto_possessive(previous, utf, ptr + 1, options, cd)) - { - repeat_type = 0; /* Force greedy */ - possessive_quantifier = TRUE; - } - goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */ } @@ -4883,14 +5672,6 @@ for (;; ptr++) op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */ c = *previous; - if (!possessive_quantifier && - repeat_max < 0 && - check_auto_possessive(previous, utf, ptr + 1, options, cd)) - { - repeat_type = 0; /* Force greedy */ - possessive_quantifier = TRUE; - } - OUTPUT_SINGLE_REPEAT: if (*previous == OP_PROP || *previous == OP_NOTPROP) { @@ -4907,16 +5688,6 @@ for (;; ptr++) if (repeat_max == 0) goto END_REPEAT; - /*--------------------------------------------------------------------*/ - /* This code is obsolete from release 8.00; the restriction was finally - removed: */ - - /* All real repeats make it impossible to handle partial matching (maybe - one day we will be able to remove this restriction). */ - - /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */ - /*--------------------------------------------------------------------*/ - /* Combine the op_type with the repeat_type */ repeat_type += op_type; @@ -5049,13 +5820,12 @@ for (;; ptr++) /* If previous was a character class or a back reference, we put the repeat stuff after it, but just skip the item if the repeat was {0,0}. */ - else if (*previous == OP_CLASS || - *previous == OP_NCLASS || + else if (*previous == OP_CLASS || *previous == OP_NCLASS || #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 *previous == OP_XCLASS || #endif - *previous == OP_REF || - *previous == OP_REFI) + *previous == OP_REF || *previous == OP_REFI || + *previous == OP_DNREF || *previous == OP_DNREFI) { if (repeat_max == 0) { @@ -5063,16 +5833,6 @@ for (;; ptr++) goto END_REPEAT; } - /*--------------------------------------------------------------------*/ - /* This code is obsolete from release 8.00; the restriction was finally - removed: */ - - /* All real repeats make it impossible to handle partial matching (maybe - one day we will be able to remove this restriction). */ - - /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */ - /*--------------------------------------------------------------------*/ - if (repeat_min == 0 && repeat_max == -1) *code++ = OP_CRSTAR + repeat_type; else if (repeat_min == 1 && repeat_max == -1) @@ -5093,8 +5853,9 @@ for (;; ptr++) opcodes such as BRA and CBRA, as this is the place where they get converted into the more special varieties such as BRAPOS and SBRA. A test for >= OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK, - ASSERTBACK_NOT, ONCE, BRA, CBRA, and COND. Originally, PCRE did not allow - repetition of assertions, but now it does, for Perl compatibility. */ + ASSERTBACK_NOT, ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND. + Originally, PCRE did not allow repetition of assertions, but now it does, + for Perl compatibility. */ else if (*previous >= OP_ASSERT && *previous <= OP_COND) { @@ -5112,7 +5873,7 @@ for (;; ptr++) /* There is no sense in actually repeating assertions. The only potential use of repetition is in cases when the assertion is optional. Therefore, if the minimum is greater than zero, just ignore the repeat. If the - maximum is not not zero or one, set it to 1. */ + maximum is not zero or one, set it to 1. */ if (*previous < OP_ONCE) /* Assertion */ { @@ -5415,7 +6176,7 @@ for (;; ptr++) pcre_uchar *scode = bracode; do { - if (could_be_empty_branch(scode, ketcode, utf, cd)) + if (could_be_empty_branch(scode, ketcode, utf, cd, NULL)) { *bracode += OP_SBRA - OP_BRA; break; @@ -5485,43 +6246,105 @@ for (;; ptr++) goto FAILED; } - /* If the character following a repeat is '+', or if certain optimization - tests above succeeded, possessive_quantifier is TRUE. For some opcodes, - there are special alternative opcodes for this case. For anything else, we - wrap the entire repeated item inside OP_ONCE brackets. Logically, the '+' - notation is just syntactic sugar, taken from Sun's Java package, but the - special opcodes can optimize it. + /* If the character following a repeat is '+', possessive_quantifier is + TRUE. For some opcodes, there are special alternative opcodes for this + case. For anything else, we wrap the entire repeated item inside OP_ONCE + brackets. Logically, the '+' notation is just syntactic sugar, taken from + Sun's Java package, but the special opcodes can optimize it. Some (but not all) possessively repeated subpatterns have already been completely handled in the code just above. For them, possessive_quantifier - is always FALSE at this stage. - - Note that the repeated item starts at tempcode, not at previous, which - might be the first part of a string whose (former) last char we repeated. - - Possessifying an 'exact' quantifier has no effect, so we can ignore it. But - an 'upto' may follow. We skip over an 'exact' item, and then test the - length of what remains before proceeding. */ + is always FALSE at this stage. Note that the repeated item starts at + tempcode, not at previous, which might be the first part of a string whose + (former) last char we repeated. */ if (possessive_quantifier) { int len; - if (*tempcode == OP_TYPEEXACT) + /* Possessifying an EXACT quantifier has no effect, so we can ignore it. + However, QUERY, STAR, or UPTO may follow (for quantifiers such as {5,6}, + {5,}, or {5,10}). We skip over an EXACT item; if the length of what + remains is greater than zero, there's a further opcode that can be + handled. If not, do nothing, leaving the EXACT alone. */ + + switch(*tempcode) + { + case OP_TYPEEXACT: tempcode += PRIV(OP_lengths)[*tempcode] + ((tempcode[1 + IMM2_SIZE] == OP_PROP || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); + break; - else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT) - { + /* CHAR opcodes are used for exacts whose count is 1. */ + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: tempcode += PRIV(OP_lengths)[*tempcode]; #ifdef SUPPORT_UTF if (utf && HAS_EXTRALEN(tempcode[-1])) tempcode += GET_EXTRALEN(tempcode[-1]); +#endif + break; + + /* For the class opcodes, the repeat operator appears at the end; + adjust tempcode to point to it. */ + + case OP_CLASS: + case OP_NCLASS: + tempcode += 1 + 32/sizeof(pcre_uchar); + break; + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + tempcode += GET(tempcode, 1); + break; #endif } + /* If tempcode is equal to code (which points to the end of the repeated + item), it means we have skipped an EXACT item but there is no following + QUERY, STAR, or UPTO; the value of len will be 0, and we do nothing. In + all other cases, tempcode will be pointing to the repeat opcode, and will + be less than code, so the value of len will be greater than 0. */ + len = (int)(code - tempcode); + if (len > 0) + { + unsigned int repcode = *tempcode; + + /* There is a table for possessifying opcodes, all of which are less + than OP_CALLOUT. A zero entry means there is no possessified version. + */ + + if (repcode < OP_CALLOUT && opcode_possessify[repcode] > 0) + *tempcode = opcode_possessify[repcode]; + + /* For opcode without a special possessified version, wrap the item in + ONCE brackets. Because we are moving code along, we must ensure that any + pending recursive references are updated. */ + + else + { + *code = OP_END; + adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm); + memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len)); + code += 1 + LINK_SIZE; + len += 1 + LINK_SIZE; + tempcode[0] = OP_ONCE; + *code++ = OP_KET; + PUTINC(code, 0, len); + PUT(tempcode, 1, len); + } + } + +#ifdef NEVER if (len > 0) switch (*tempcode) { case OP_STAR: *tempcode = OP_POSSTAR; break; @@ -5549,6 +6372,11 @@ for (;; ptr++) case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break; case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break; + case OP_CRSTAR: *tempcode = OP_CRPOSSTAR; break; + case OP_CRPLUS: *tempcode = OP_CRPOSPLUS; break; + case OP_CRQUERY: *tempcode = OP_CRPOSQUERY; break; + case OP_CRRANGE: *tempcode = OP_CRPOSRANGE; break; + /* Because we are moving code along, we must ensure that any pending recursive references are updated. */ @@ -5564,6 +6392,7 @@ for (;; ptr++) PUT(tempcode, 1, len); break; } +#endif } /* In all case we no longer have a previous item. We also set the @@ -5749,38 +6578,56 @@ for (;; ptr++) /* ------------------------------------------------------------ */ case CHAR_LEFT_PARENTHESIS: bravalue = OP_COND; /* Conditional group */ + tempptr = ptr; /* A condition can be an assertion, a number (referring to a numbered - group), a name (referring to a named group), or 'R', referring to - recursion. R and R&name are also permitted for recursion tests. + group's having been set), a name (referring to a named group), or 'R', + referring to recursion. R and R&name are also permitted for + recursion tests. - There are several syntaxes for testing a named group: (?(name)) is used - by Python; Perl 5.10 onwards uses (?() or (?('name')). + There are ways of testing a named group: (?(name)) is used by Python; + Perl 5.10 onwards uses (?() or (?('name')). - There are two unfortunate ambiguities, caused by history. (a) 'R' can - be the recursive thing or the name 'R' (and similarly for 'R' followed - by digits), and (b) a number could be a name that consists of digits. - In both cases, we look for a name first; if not found, we try the other - cases. */ + There is one unfortunate ambiguity, caused by history. 'R' can be the + recursive thing or the name 'R' (and similarly for 'R' followed by + digits). We look for a name first; if not found, we try the other case. + + For compatibility with auto-callouts, we allow a callout to be + specified before a condition that is an assertion. First, check for the + syntax of a callout; if found, adjust the temporary pointer that is + used to check for an assertion condition. That's all that is needed! */ + + if (ptr[1] == CHAR_QUESTION_MARK && ptr[2] == CHAR_C) + { + for (i = 3;; i++) if (!IS_DIGIT(ptr[i])) break; + if (ptr[i] == CHAR_RIGHT_PARENTHESIS) + tempptr += i + 1; + } /* For conditions that are assertions, check the syntax, and then exit the switch. This will take control down to where bracketed groups, including assertions, are processed. */ - if (ptr[1] == CHAR_QUESTION_MARK && (ptr[2] == CHAR_EQUALS_SIGN || - ptr[2] == CHAR_EXCLAMATION_MARK || ptr[2] == CHAR_LESS_THAN_SIGN)) + if (tempptr[1] == CHAR_QUESTION_MARK && + (tempptr[2] == CHAR_EQUALS_SIGN || + tempptr[2] == CHAR_EXCLAMATION_MARK || + tempptr[2] == CHAR_LESS_THAN_SIGN)) break; - /* Most other conditions use OP_CREF (a couple change to OP_RREF - below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */ + /* Other conditions use OP_CREF/OP_DNCREF/OP_RREF/OP_DNRREF, and all + need to skip at least 1+IMM2_SIZE bytes at the start of the group. */ code[1+LINK_SIZE] = OP_CREF; skipbytes = 1+IMM2_SIZE; - refsign = -1; + refsign = -1; /* => not a number */ + namelen = -1; /* => not a name; must set to avoid warning */ + name = NULL; /* Always set to avoid warning */ + recno = 0; /* Always set to avoid warning */ /* Check for a test for recursion in a named group. */ - if (ptr[1] == CHAR_R && ptr[2] == CHAR_AMPERSAND) + ptr++; + if (*ptr == CHAR_R && ptr[1] == CHAR_AMPERSAND) { terminator = -1; ptr += 2; @@ -5788,14 +6635,15 @@ for (;; ptr++) } /* Check for a test for a named group's having been set, using the Perl - syntax (?() or (?('name') */ + syntax (?() or (?('name'), and also allow for the original PCRE + syntax of (?(name) or for (?(+n), (?(-n), and just (?(n). */ - else if (ptr[1] == CHAR_LESS_THAN_SIGN) + else if (*ptr == CHAR_LESS_THAN_SIGN) { terminator = CHAR_GREATER_THAN_SIGN; ptr++; } - else if (ptr[1] == CHAR_APOSTROPHE) + else if (*ptr == CHAR_APOSTROPHE) { terminator = CHAR_APOSTROPHE; ptr++; @@ -5803,35 +6651,54 @@ for (;; ptr++) else { terminator = CHAR_NULL; - if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr); + if (*ptr == CHAR_MINUS || *ptr == CHAR_PLUS) refsign = *ptr++; + else if (IS_DIGIT(*ptr)) refsign = 0; } - /* We now expect to read a name; any thing else is an error */ + /* Handle a number */ - if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0) + if (refsign >= 0) { - ptr += 1; /* To get the right offset */ - *errorcodeptr = ERR28; - goto FAILED; + while (IS_DIGIT(*ptr)) + { + recno = recno * 10 + (int)(*ptr - CHAR_0); + ptr++; + } } - /* Read the name, but also get it as a number if it's all digits */ + /* Otherwise we expect to read a name; anything else is an error. When + a name is one of a number of duplicates, a different opcode is used and + it needs more memory. Unfortunately we cannot tell whether a name is a + duplicate in the first pass, so we have to allow for more memory. */ - recno = 0; - name = ++ptr; - while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) + else { - if (recno >= 0) - recno = (IS_DIGIT(*ptr))? recno * 10 + (int)(*ptr - CHAR_0) : -1; - ptr++; + if (IS_DIGIT(*ptr)) + { + *errorcodeptr = ERR84; + goto FAILED; + } + if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_word) == 0) + { + *errorcodeptr = ERR28; /* Assertion expected */ + goto FAILED; + } + name = ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) + { + ptr++; + } + namelen = (int)(ptr - name); + if (lengthptr != NULL) *lengthptr += IMM2_SIZE; } - namelen = (int)(ptr - name); + + /* Check the terminator */ if ((terminator > 0 && *ptr++ != (pcre_uchar)terminator) || *ptr++ != CHAR_RIGHT_PARENTHESIS) { - ptr--; /* Error offset */ - *errorcodeptr = ERR26; + ptr--; /* Error offset */ + *errorcodeptr = ERR26; /* Malformed number or name */ goto FAILED; } @@ -5840,18 +6707,18 @@ for (;; ptr++) if (lengthptr != NULL) break; /* In the real compile we do the work of looking for the actual - reference. If the string started with "+" or "-" we require the rest to - be digits, in which case recno will be set. */ + reference. If refsign is not negative, it means we have a number in + recno. */ - if (refsign > 0) + if (refsign >= 0) { if (recno <= 0) { - *errorcodeptr = ERR58; + *errorcodeptr = ERR35; goto FAILED; } - recno = (refsign == CHAR_MINUS)? - cd->bracount - recno + 1 : recno +cd->bracount; + if (refsign != 0) recno = (refsign == CHAR_MINUS)? + cd->bracount - recno + 1 : recno + cd->bracount; if (recno <= 0 || recno > cd->final_bracount) { *errorcodeptr = ERR15; @@ -5861,11 +6728,7 @@ for (;; ptr++) break; } - /* Otherwise (did not start with "+" or "-"), start by looking for the - name. If we find a name, add one to the opcode to change OP_CREF or - OP_RREF into OP_NCREF or OP_NRREF. These behave exactly the same, - except they record that the reference was originally to a name. The - information is used to check duplicate names. */ + /* Otherwise look for the name. */ slot = cd->name_table; for (i = 0; i < cd->names_found; i++) @@ -5874,29 +6737,40 @@ for (;; ptr++) slot += cd->name_entry_size; } - /* Found a previous named subpattern */ + /* Found the named subpattern. If the name is duplicated, add one to + the opcode to change CREF/RREF into DNCREF/DNRREF and insert + appropriate data values. Otherwise, just insert the unique subpattern + number. */ if (i < cd->names_found) { - recno = GET2(slot, 0); - PUT2(code, 2+LINK_SIZE, recno); - code[1+LINK_SIZE]++; - } - - /* Search the pattern for a forward reference */ - - else if ((i = find_parens(cd, name, namelen, - (options & PCRE_EXTENDED) != 0, utf)) > 0) - { - PUT2(code, 2+LINK_SIZE, i); - code[1+LINK_SIZE]++; + int offset = i++; + int count = 1; + recno = GET2(slot, 0); /* Number from first found */ + for (; i < cd->names_found; i++) + { + slot += cd->name_entry_size; + if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) != 0) break; + count++; + } + if (count > 1) + { + PUT2(code, 2+LINK_SIZE, offset); + PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count); + skipbytes += IMM2_SIZE; + code[1+LINK_SIZE]++; + } + else /* Not a duplicated name */ + { + PUT2(code, 2+LINK_SIZE, recno); + } } /* If terminator == CHAR_NULL it means that the name followed directly after the opening parenthesis [e.g. (?(abc)...] and in this case there are some further alternatives to try. For the cases where terminator != - 0 [things like (?(... or (?('name')... or (?(R&name)... ] we have - now checked all the possibilities, so give an error. */ + CHAR_NULL [things like (?(... or (?('name')... or (?(R&name)... ] + we have now checked all the possibilities, so give an error. */ else if (terminator != CHAR_NULL) { @@ -5933,19 +6807,11 @@ for (;; ptr++) skipbytes = 1; } - /* Check for the "name" actually being a subpattern number. We are - in the second pass here, so final_bracount is set. */ - - else if (recno > 0 && recno <= cd->final_bracount) - { - PUT2(code, 2+LINK_SIZE, recno); - } - - /* Either an unidentified subpattern, or a reference to (?(0) */ + /* Reference to an unidentified subpattern. */ else { - *errorcodeptr = (recno == 0)? ERR35: ERR15; + *errorcodeptr = ERR15; goto FAILED; } break; @@ -5958,11 +6824,18 @@ for (;; ptr++) ptr++; break; + /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird + thing to do, but Perl allows all assertions to be quantified, and when + they contain capturing parentheses there may be a potential use for + this feature. Not that that applies to a quantified (?!) but we allow + it for uniformity. */ /* ------------------------------------------------------------ */ case CHAR_EXCLAMATION_MARK: /* Negative lookahead */ ptr++; - if (*ptr == CHAR_RIGHT_PARENTHESIS) /* Optimize (?!) */ + if (*ptr == CHAR_RIGHT_PARENTHESIS && ptr[1] != CHAR_ASTERISK && + ptr[1] != CHAR_PLUS && ptr[1] != CHAR_QUESTION_MARK && + (ptr[1] != CHAR_LEFT_CURLY_BRACKET || !is_counted_repeat(ptr+2))) { *code++ = OP_FAIL; previous = NULL; @@ -6055,124 +6928,110 @@ for (;; ptr++) /* ------------------------------------------------------------ */ DEFINE_NAME: /* Come here from (?< handling */ case CHAR_APOSTROPHE: + terminator = (*ptr == CHAR_LESS_THAN_SIGN)? + CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; + name = ++ptr; + if (IS_DIGIT(*ptr)) { - terminator = (*ptr == CHAR_LESS_THAN_SIGN)? - CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; - name = ++ptr; + *errorcodeptr = ERR84; /* Group name must start with non-digit */ + goto FAILED; + } + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++; + namelen = (int)(ptr - name); - while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++; - namelen = (int)(ptr - name); + /* In the pre-compile phase, do a syntax check, remember the longest + name, and then remember the group in a vector, expanding it if + necessary. Duplicates for the same number are skipped; other duplicates + are checked for validity. In the actual compile, there is nothing to + do. */ - /* In the pre-compile phase, just do a syntax check. */ + if (lengthptr != NULL) + { + named_group *ng; + pcre_uint32 number = cd->bracount + 1; - if (lengthptr != NULL) + if (*ptr != (pcre_uchar)terminator) { - if (*ptr != (pcre_uchar)terminator) + *errorcodeptr = ERR42; + goto FAILED; + } + + if (cd->names_found >= MAX_NAME_COUNT) + { + *errorcodeptr = ERR49; + goto FAILED; + } + + if (namelen + IMM2_SIZE + 1 > cd->name_entry_size) + { + cd->name_entry_size = namelen + IMM2_SIZE + 1; + if (namelen > MAX_NAME_SIZE) { - *errorcodeptr = ERR42; + *errorcodeptr = ERR48; goto FAILED; } - if (cd->names_found >= MAX_NAME_COUNT) - { - *errorcodeptr = ERR49; - goto FAILED; - } - if (namelen + IMM2_SIZE + 1 > cd->name_entry_size) - { - cd->name_entry_size = namelen + IMM2_SIZE + 1; - if (namelen > MAX_NAME_SIZE) - { - *errorcodeptr = ERR48; - goto FAILED; - } - } } - /* In the real compile, create the entry in the table, maintaining - alphabetical order. Duplicate names for different numbers are - permitted only if PCRE_DUPNAMES is set. Duplicate names for the same - number are always OK. (An existing number can be re-used if (?| - appears in the pattern.) In either event, a duplicate name results in - a duplicate entry in the table, even if the number is the same. This - is because the number of names, and hence the table size, is computed - in the pre-compile, and it affects various numbers and pointers which - would all have to be modified, and the compiled code moved down, if - duplicates with the same number were omitted from the table. This - doesn't seem worth the hassle. However, *different* names for the - same number are not permitted. */ + /* Scan the list to check for duplicates. For duplicate names, if the + number is the same, break the loop, which causes the name to be + discarded; otherwise, if DUPNAMES is not set, give an error. + If it is set, allow the name with a different number, but continue + scanning in case this is a duplicate with the same number. For + non-duplicate names, give an error if the number is duplicated. */ - else + ng = cd->named_groups; + for (i = 0; i < cd->names_found; i++, ng++) { - BOOL dupname = FALSE; - slot = cd->name_table; - - for (i = 0; i < cd->names_found; i++) + if (namelen == ng->length && + STRNCMP_UC_UC(name, ng->name, namelen) == 0) { - int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen)); - if (crc == 0) + if (ng->number == number) break; + if ((options & PCRE_DUPNAMES) == 0) { - if (slot[IMM2_SIZE+namelen] == 0) - { - if (GET2(slot, 0) != cd->bracount + 1 && - (options & PCRE_DUPNAMES) == 0) - { - *errorcodeptr = ERR43; - goto FAILED; - } - else dupname = TRUE; - } - else crc = -1; /* Current name is a substring */ + *errorcodeptr = ERR43; + goto FAILED; + } + cd->dupnames = TRUE; /* Duplicate names exist */ + } + else if (ng->number == number) + { + *errorcodeptr = ERR65; + goto FAILED; + } + } + + if (i >= cd->names_found) /* Not a duplicate with same number */ + { + /* Increase the list size if necessary */ + + if (cd->names_found >= cd->named_group_list_size) + { + int newsize = cd->named_group_list_size * 2; + named_group *newspace = (PUBL(malloc)) + (newsize * sizeof(named_group)); + + if (newspace == NULL) + { + *errorcodeptr = ERR21; + goto FAILED; } - /* Make space in the table and break the loop for an earlier - name. For a duplicate or later name, carry on. We do this for - duplicates so that in the simple case (when ?(| is not used) they - are in order of their numbers. */ - - if (crc < 0) - { - memmove(slot + cd->name_entry_size, slot, - IN_UCHARS((cd->names_found - i) * cd->name_entry_size)); - break; - } - - /* Continue the loop for a later or duplicate name */ - - slot += cd->name_entry_size; + memcpy(newspace, cd->named_groups, + cd->named_group_list_size * sizeof(named_group)); + if (cd->named_group_list_size > NAMED_GROUP_LIST_SIZE) + (PUBL(free))((void *)cd->named_groups); + cd->named_groups = newspace; + cd->named_group_list_size = newsize; } - /* For non-duplicate names, check for a duplicate number before - adding the new name. */ - - if (!dupname) - { - pcre_uchar *cslot = cd->name_table; - for (i = 0; i < cd->names_found; i++) - { - if (cslot != slot) - { - if (GET2(cslot, 0) == cd->bracount + 1) - { - *errorcodeptr = ERR65; - goto FAILED; - } - } - else i--; - cslot += cd->name_entry_size; - } - } - - PUT2(slot, 0, cd->bracount + 1); - memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen)); - slot[IMM2_SIZE + namelen] = 0; + cd->named_groups[cd->names_found].name = name; + cd->named_groups[cd->names_found].length = namelen; + cd->named_groups[cd->names_found].number = number; + cd->names_found++; } } - /* In both pre-compile and compile, count the number of names we've - encountered. */ - - cd->names_found++; - ptr++; /* Move past > or ' */ + ptr++; /* Move past > or ' in both passes. */ goto NUMBERED_GROUP; @@ -6190,6 +7049,11 @@ for (;; ptr++) NAMED_REF_OR_RECURSE: name = ++ptr; + if (IS_DIGIT(*ptr)) + { + *errorcodeptr = ERR84; /* Group name must start with non-digit */ + goto FAILED; + } while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++; namelen = (int)(ptr - name); @@ -6202,7 +7066,7 @@ for (;; ptr++) if (lengthptr != NULL) { - const pcre_uchar *temp; + named_group *ng; if (namelen == 0) { @@ -6220,27 +7084,29 @@ for (;; ptr++) goto FAILED; } - /* The name table does not exist in the first pass, so we cannot - do a simple search as in the code below. Instead, we have to scan the - pattern to find the number. It is important that we scan it only as - far as we have got because the syntax of named subpatterns has not - been checked for the rest of the pattern, and find_parens() assumes - correct syntax. In any case, it's a waste of resources to scan - further. We stop the scan at the current point by temporarily - adjusting the value of cd->endpattern. */ + /* The name table does not exist in the first pass; instead we must + scan the list of names encountered so far in order to get the + number. If the name is not found, set the value to 0 for a forward + reference. */ - temp = cd->end_pattern; - cd->end_pattern = ptr; - recno = find_parens(cd, name, namelen, - (options & PCRE_EXTENDED) != 0, utf); - cd->end_pattern = temp; - if (recno < 0) recno = 0; /* Forward ref; set dummy number */ + ng = cd->named_groups; + for (i = 0; i < cd->names_found; i++, ng++) + { + if (namelen == ng->length && + STRNCMP_UC_UC(name, ng->name, namelen) == 0) + break; + } + recno = (i < cd->names_found)? ng->number : 0; + + /* Count named back references. */ + + if (!is_recurse) cd->namedrefcount++; } - /* In the real compile, seek the name in the table. We check the name + /* In the real compile, search the name table. We check the name first, and then check that we have reached the end of the name in the - table. That way, if the name that is longer than any in the table, - the comparison will fail without reading beyond the table entry. */ + table. That way, if the name is longer than any in the table, the + comparison will fail without reading beyond the table entry. */ else { @@ -6253,24 +7119,76 @@ for (;; ptr++) slot += cd->name_entry_size; } - if (i < cd->names_found) /* Back reference */ + if (i < cd->names_found) { recno = GET2(slot, 0); } - else if ((recno = /* Forward back reference */ - find_parens(cd, name, namelen, - (options & PCRE_EXTENDED) != 0, utf)) <= 0) + else { *errorcodeptr = ERR15; goto FAILED; } } - /* In both phases, we can now go to the code than handles numerical - recursion or backreferences. */ + /* In both phases, for recursions, we can now go to the code than + handles numerical recursion. */ if (is_recurse) goto HANDLE_RECURSION; - else goto HANDLE_REFERENCE; + + /* In the second pass we must see if the name is duplicated. If so, we + generate a different opcode. */ + + if (lengthptr == NULL && cd->dupnames) + { + int count = 1; + unsigned int index = i; + pcre_uchar *cslot = slot + cd->name_entry_size; + + for (i++; i < cd->names_found; i++) + { + if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break; + count++; + cslot += cd->name_entry_size; + } + + if (count > 1) + { + if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + previous = code; + *code++ = ((options & PCRE_CASELESS) != 0)? OP_DNREFI : OP_DNREF; + PUT2INC(code, 0, index); + PUT2INC(code, 0, count); + + /* Process each potentially referenced group. */ + + for (; slot < cslot; slot += cd->name_entry_size) + { + open_capitem *oc; + recno = GET2(slot, 0); + cd->backref_map |= (recno < 32)? (1 << recno) : 1; + if (recno > cd->top_backref) cd->top_backref = recno; + + /* Check to see if this back reference is recursive, that it, it + is inside the group that it references. A flag is set so that the + group can be made atomic. */ + + for (oc = cd->open_caps; oc != NULL; oc = oc->next) + { + if (oc->number == recno) + { + oc->flag = TRUE; + break; + } + } + } + + continue; /* End of back ref handling */ + } + } + + /* First pass, or a non-duplicated name. */ + + goto HANDLE_REFERENCE; /* ------------------------------------------------------------ */ @@ -6369,8 +7287,7 @@ for (;; ptr++) if (called == NULL) { - if (find_parens(cd, NULL, recno, - (options & PCRE_EXTENDED) != 0, utf) < 0) + if (recno > cd->final_bracount) { *errorcodeptr = ERR15; goto FAILED; @@ -6529,10 +7446,19 @@ for (;; ptr++) skipbytes = IMM2_SIZE; } - /* Process nested bracketed regex. Assertions used not to be repeatable, - but this was changed for Perl compatibility, so all kinds can now be - repeated. We copy code into a non-register variable (tempcode) in order to - be able to pass its address because some compilers complain otherwise. */ + /* Process nested bracketed regex. First check for parentheses nested too + deeply. */ + + if ((cd->parens_depth += 1) > PARENS_NEST_LIMIT) + { + *errorcodeptr = ERR82; + goto FAILED; + } + + /* Assertions used not to be repeatable, but this was changed for Perl + compatibility, so all kinds can now be repeated. We copy code into a + non-register variable (tempcode) in order to be able to pass its address + because some compilers complain otherwise. */ previous = code; /* For handling repetition */ *code = bravalue; @@ -6563,6 +7489,8 @@ for (;; ptr++) )) goto FAILED; + cd->parens_depth -= 1; + /* If this was an atomic group and there are no capturing groups within it, generate OP_ONCE_NC instead of OP_ONCE. */ @@ -6738,10 +7666,9 @@ for (;; ptr++) case CHAR_BACKSLASH: tempptr = ptr; escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, FALSE); - if (*errorcodeptr != 0) goto FAILED; - if (escape == 0) + if (escape == 0) /* The escape coded a single character */ c = ec; else { @@ -6778,44 +7705,31 @@ for (;; ptr++) if (escape == ESC_g) { const pcre_uchar *p; + pcre_uint32 cf; + save_hwm = cd->hwm; /* Normally this is set when '(' is read */ terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; /* These two statements stop the compiler for warning about possibly unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In - fact, because we actually check for a number below, the paths that + fact, because we do the check for a number below, the paths that would actually be in error are never taken. */ skipbytes = 0; reset_bracount = FALSE; - /* Test for a name */ + /* If it's not a signed or unsigned number, treat it as a name. */ - if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS) + cf = ptr[1]; + if (cf != CHAR_PLUS && cf != CHAR_MINUS && !IS_DIGIT(cf)) { - BOOL is_a_number = TRUE; - for (p = ptr + 1; *p != CHAR_NULL && *p != (pcre_uchar)terminator; p++) - { - if (!MAX_255(*p)) { is_a_number = FALSE; break; } - if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE; - if ((cd->ctypes[*p] & ctype_word) == 0) break; - } - if (*p != (pcre_uchar)terminator) - { - *errorcodeptr = ERR57; - break; - } - if (is_a_number) - { - ptr++; - goto HANDLE_NUMERICAL_RECURSION; - } is_recurse = TRUE; goto NAMED_REF_OR_RECURSE; } - /* Test a signed number in angle brackets or quotes. */ + /* Signed or unsigned number (cf = ptr[1]) is known to be plus or minus + or a digit. */ p = ptr + 2; while (IS_DIGIT(*p)) p++; @@ -6855,7 +7769,10 @@ for (;; ptr++) open_capitem *oc; recno = -escape; - HANDLE_REFERENCE: /* Come here from named backref handling */ + /* Come here from named backref handling when the reference is to a + single group (i.e. not to a duplicated name. */ + + HANDLE_REFERENCE: if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; previous = code; *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF; @@ -6907,11 +7824,12 @@ for (;; ptr++) can obtain the OP value by negating the escape value in the default situation when PCRE_UCP is not set. When it *is* set, we substitute Unicode property tests. Note that \b and \B do a one-character - lookbehind. */ + lookbehind, and \A also behaves as if it does. */ else { - if ((escape == ESC_b || escape == ESC_B) && cd->max_lookbehind == 0) + if ((escape == ESC_b || escape == ESC_B || escape == ESC_A) && + cd->max_lookbehind == 0) cd->max_lookbehind = 1; #ifdef SUPPORT_UCP if (escape >= ESC_DU && escape <= ESC_wu) @@ -6951,8 +7869,8 @@ for (;; ptr++) /* ===================================================================*/ /* Handle a literal character. It is guaranteed not to be whitespace or # - when the extended flag is set. If we are in UTF-8 mode, it may be a - multi-byte literal character. */ + when the extended flag is set. If we are in a UTF mode, it may be a + multi-unit literal character. */ default: NORMAL_CHAR: @@ -6983,7 +7901,8 @@ for (;; ptr++) *code++ = OP_PROP; *code++ = PT_CLIST; *code++ = c; - if (firstcharflags == REQ_UNSET) firstcharflags = zerofirstcharflags = REQ_NONE; + if (firstcharflags == REQ_UNSET) + firstcharflags = zerofirstcharflags = REQ_NONE; break; } } @@ -7072,24 +7991,24 @@ out the amount of memory needed, as well as during the real compile phase. The value of lengthptr distinguishes the two phases. Arguments: - options option bits, including any changes for this subpattern - codeptr -> the address of the current code pointer - ptrptr -> the address of the current pattern pointer - errorcodeptr -> pointer to error code variable - lookbehind TRUE if this is a lookbehind assertion - reset_bracount TRUE to reset the count for each branch - skipbytes skip this many bytes at start (for brackets and OP_COND) - cond_depth depth of nesting for conditional subpatterns - firstcharptr place to put the first required character + options option bits, including any changes for this subpattern + codeptr -> the address of the current code pointer + ptrptr -> the address of the current pattern pointer + errorcodeptr -> pointer to error code variable + lookbehind TRUE if this is a lookbehind assertion + reset_bracount TRUE to reset the count for each branch + skipbytes skip this many bytes at start (for brackets and OP_COND) + cond_depth depth of nesting for conditional subpatterns + firstcharptr place to put the first required character firstcharflagsptr place to put the first character flags, or a negative number - reqcharptr place to put the last required character - reqcharflagsptr place to put the last required character flags, or a negative number - bcptr pointer to the chain of currently open branches - cd points to the data block with tables pointers etc. - lengthptr NULL during the real compile phase - points to length accumulator during pre-compile phase + reqcharptr place to put the last required character + reqcharflagsptr place to put the last required character flags, or a negative number + bcptr pointer to the chain of currently open branches + cd points to the data block with tables pointers etc. + lengthptr NULL during the real compile phase + points to length accumulator during pre-compile phase -Returns: TRUE on success +Returns: TRUE on success */ static BOOL @@ -7116,6 +8035,16 @@ unsigned int orig_bracount; unsigned int max_bracount; branch_chain bc; +/* If set, call the external function that checks for stack availability. */ + +if (PUBL(stack_guard) != NULL && PUBL(stack_guard)()) + { + *errorcodeptr= ERR85; + return FALSE; + } + +/* Miscellaneous initialization */ + bc.outer = bcptr; bc.current_branch = code; @@ -7540,9 +8469,9 @@ do { switch (*scode) { case OP_CREF: - case OP_NCREF: + case OP_DNCREF: case OP_RREF: - case OP_NRREF: + case OP_DNRREF: case OP_DEF: return FALSE; @@ -7626,13 +8555,14 @@ return TRUE; discarded, because they can cause conflicts with actual literals that follow. However, if we end up without a first char setting for an unanchored pattern, it is worth scanning the regex to see if there is an initial asserted first -char. If all branches start with the same asserted char, or with a bracket all -of whose alternatives start with the same asserted char (recurse ad lib), then -we return that char, otherwise -1. +char. If all branches start with the same asserted char, or with a +non-conditional bracket all of whose alternatives start with the same asserted +char (recurse ad lib), then we return that char, with the flags set to zero or +REQ_CASELESS; otherwise return zero with REQ_NONE in the flags. Arguments: code points to start of expression (the bracket) - flags points to the first char flags, or to REQ_NONE + flags points to the first char flags, or to REQ_NONE inassert TRUE if in an assertion Returns: the fixed first char, or 0 with REQ_NONE in flags @@ -7669,7 +8599,6 @@ do { case OP_ASSERT: case OP_ONCE: case OP_ONCE_NC: - case OP_COND: d = find_firstassertedchar(scode, &dflags, op == OP_ASSERT); if (dflags < 0) return 0; @@ -7713,6 +8642,61 @@ return c; +/************************************************* +* Add an entry to the name/number table * +*************************************************/ + +/* This function is called between compiling passes to add an entry to the +name/number table, maintaining alphabetical order. Checking for permitted +and forbidden duplicates has already been done. + +Arguments: + cd the compile data block + name the name to add + length the length of the name + groupno the group number + +Returns: nothing +*/ + +static void +add_name(compile_data *cd, const pcre_uchar *name, int length, + unsigned int groupno) +{ +int i; +pcre_uchar *slot = cd->name_table; + +for (i = 0; i < cd->names_found; i++) + { + int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(length)); + if (crc == 0 && slot[IMM2_SIZE+length] != 0) + crc = -1; /* Current name is a substring */ + + /* Make space in the table and break the loop for an earlier name. For a + duplicate or later name, carry on. We do this for duplicates so that in the + simple case (when ?(| is not used) they are in order of their numbers. In all + cases they are in the order in which they appear in the pattern. */ + + if (crc < 0) + { + memmove(slot + cd->name_entry_size, slot, + IN_UCHARS((cd->names_found - i) * cd->name_entry_size)); + break; + } + + /* Continue the loop for a later or duplicate name */ + + slot += cd->name_entry_size; + } + +PUT2(slot, 0, groupno); +memcpy(slot + IMM2_SIZE, name, IN_UCHARS(length)); +slot[IMM2_SIZE + length] = 0; +cd->names_found++; +} + + + /************************************************* * Compile a Regular Expression * *************************************************/ @@ -7775,12 +8759,15 @@ pcre32_compile2(PCRE_SPTR32 pattern, int options, int *errorcodeptr, { REAL_PCRE *re; int length = 1; /* For final END opcode */ -pcre_uint32 firstchar, reqchar; pcre_int32 firstcharflags, reqcharflags; +pcre_uint32 firstchar, reqchar; +pcre_uint32 limit_match = PCRE_UINT32_MAX; +pcre_uint32 limit_recursion = PCRE_UINT32_MAX; int newline; int errorcode = 0; int skipatstart = 0; BOOL utf; +BOOL never_utf = FALSE; size_t size; pcre_uchar *code; const pcre_uchar *codestart; @@ -7797,6 +8784,11 @@ new memory is obtained from malloc(). */ pcre_uchar cworkspace[COMPILE_WORK_SIZE]; +/* This vector is used for remembering name groups during the pre-compile. In a +similar way to cworkspace, it can be expanded using malloc() if necessary. */ + +named_group named_groups[NAMED_GROUP_LIST_SIZE]; + /* Set this early so that early errors get offset 0. */ ptr = (const pcre_uchar *)pattern; @@ -7840,9 +8832,15 @@ if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0) goto PCRE_EARLY_ERROR_RETURN; } +/* If PCRE_NEVER_UTF is set, remember it. */ + +if ((options & PCRE_NEVER_UTF) != 0) never_utf = TRUE; + /* Check for global one-time settings at the start of the pattern, and remember the offset for later. */ +cd->external_flags = 0; /* Initialize here for LIMIT_MATCH/RECURSION */ + while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS && ptr[skipatstart+1] == CHAR_ASTERISK) { @@ -7870,9 +8868,49 @@ PCRE_UTF8 == PCRE_UTF16 == PCRE_UTF32. */ { skipatstart += 6; options |= PCRE_UTF8; continue; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0) { skipatstart += 6; options |= PCRE_UCP; continue; } + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_AUTO_POSSESS_RIGHTPAR, 16) == 0) + { skipatstart += 18; options |= PCRE_NO_AUTO_POSSESS; continue; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0) { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; } + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LIMIT_MATCH_EQ, 12) == 0) + { + pcre_uint32 c = 0; + int p = skipatstart + 14; + while (isdigit(ptr[p])) + { + if (c > PCRE_UINT32_MAX / 10 - 1) break; /* Integer overflow */ + c = c*10 + ptr[p++] - CHAR_0; + } + if (ptr[p++] != CHAR_RIGHT_PARENTHESIS) break; + if (c < limit_match) + { + limit_match = c; + cd->external_flags |= PCRE_MLSET; + } + skipatstart = p; + continue; + } + + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LIMIT_RECURSION_EQ, 16) == 0) + { + pcre_uint32 c = 0; + int p = skipatstart + 18; + while (isdigit(ptr[p])) + { + if (c > PCRE_UINT32_MAX / 10 - 1) break; /* Integer overflow check */ + c = c*10 + ptr[p++] - CHAR_0; + } + if (ptr[p++] != CHAR_RIGHT_PARENTHESIS) break; + if (c < limit_recursion) + { + limit_recursion = c; + cd->external_flags |= PCRE_RLSET; + } + skipatstart = p; + continue; + } + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0) { skipatstart += 5; newnl = PCRE_NEWLINE_CR; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0) @@ -7898,6 +8936,11 @@ PCRE_UTF8 == PCRE_UTF16 == PCRE_UTF32. */ /* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */ utf = (options & PCRE_UTF8) != 0; +if (utf && never_utf) + { + errorcode = ERR78; + goto PCRE_EARLY_ERROR_RETURN2; + } /* Can't support UTF unless PCRE has been compiled to include the code. The return of an error code from PRIV(valid_utf)() is a new feature, introduced in @@ -8010,17 +9053,21 @@ cd->bracount = cd->final_bracount = 0; cd->names_found = 0; cd->name_entry_size = 0; cd->name_table = NULL; +cd->dupnames = FALSE; +cd->namedrefcount = 0; cd->start_code = cworkspace; cd->hwm = cworkspace; cd->start_workspace = cworkspace; cd->workspace_size = COMPILE_WORK_SIZE; +cd->named_groups = named_groups; +cd->named_group_list_size = NAMED_GROUP_LIST_SIZE; cd->start_pattern = (const pcre_uchar *)pattern; cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern)); cd->req_varyopt = 0; +cd->parens_depth = 0; cd->assert_depth = 0; cd->max_lookbehind = 0; cd->external_options = options; -cd->external_flags = 0; cd->open_caps = NULL; /* Now do the pre-compile. On error, errorcode will be set non-zero, so we @@ -8032,6 +9079,7 @@ outside can help speed up starting point checks. */ ptr += skipatstart; code = cworkspace; *code = OP_BRA; + (void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0, &firstchar, &firstcharflags, &reqchar, &reqcharflags, NULL, cd, &length); @@ -8046,14 +9094,23 @@ if (length > MAX_PATTERN_SIZE) goto PCRE_EARLY_ERROR_RETURN; } -/* Compute the size of data block needed and get it, either from malloc or -externally provided function. Integer overflow should no longer be possible -because nowadays we limit the maximum value of cd->names_found and -cd->name_entry_size. */ +/* If there are groups with duplicate names and there are also references by +name, we must allow for the possibility of named references to duplicated +groups. These require an extra data item each. */ + +if (cd->dupnames && cd->namedrefcount > 0) + length += cd->namedrefcount * IMM2_SIZE * sizeof(pcre_uchar); + +/* Compute the size of the data block for storing the compiled pattern. Integer +overflow should no longer be possible because nowadays we limit the maximum +value of cd->names_found and cd->name_entry_size. */ + +size = sizeof(REAL_PCRE) + + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar); + +/* Get the memory. */ -size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar); re = (REAL_PCRE *)(PUBL(malloc))(size); - if (re == NULL) { errorcode = ERR21; @@ -8070,6 +9127,8 @@ re->magic_number = MAGIC_NUMBER; re->size = (int)size; re->options = cd->external_options; re->flags = cd->external_flags; +re->limit_match = limit_match; +re->limit_recursion = limit_recursion; re->first_char = 0; re->req_char = 0; re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar); @@ -8079,7 +9138,9 @@ re->ref_count = 0; re->tables = (tables == PRIV(default_tables))? NULL : tables; re->nullpad = NULL; #ifdef COMPILE_PCRE32 -re->dummy1 = re->dummy2 = 0; +re->dummy = 0; +#else +re->dummy1 = re->dummy2 = re->dummy3 = 0; #endif /* The starting points of the name/number translation table and of the code are @@ -8090,10 +9151,10 @@ field; this time it's used for remembering forward references to subpatterns. */ cd->final_bracount = cd->bracount; /* Save for checking forward references */ +cd->parens_depth = 0; cd->assert_depth = 0; cd->bracount = 0; cd->max_lookbehind = 0; -cd->names_found = 0; cd->name_table = (pcre_uchar *)re + re->name_table_offset; codestart = cd->name_table + re->name_entry_size * re->name_count; cd->start_code = codestart; @@ -8104,6 +9165,20 @@ cd->had_pruneorskip = FALSE; cd->check_lookbehind = FALSE; cd->open_caps = NULL; +/* If any named groups were found, create the name/number table from the list +created in the first pass. */ + +if (cd->names_found > 0) + { + int i = cd->names_found; + named_group *ng = cd->named_groups; + cd->names_found = 0; + for (; i > 0; i--, ng++) + add_name(cd, ng->name, ng->length, ng->number); + if (cd->named_group_list_size > NAMED_GROUP_LIST_SIZE) + (PUBL(free))((void *)cd->named_groups); + } + /* Set up a starting, non-extracting bracket, then compile the expression. On error, errorcode will be set non-zero, so we don't need to look at the result of the function here. */ @@ -8139,7 +9214,7 @@ if (code - codestart > length) errorcode = ERR23; #ifdef SUPPORT_VALGRIND /* If the estimated length exceeds the really used length, mark the extra -allocated memory as unadressable, so that any out-of-bound reads can be +allocated memory as unaddressable, so that any out-of-bound reads can be detected. */ VALGRIND_MAKE_MEM_NOACCESS(code, (length - (code - codestart)) * sizeof(pcre_uchar)); #endif @@ -8167,16 +9242,24 @@ if (cd->hwm > cd->start_workspace) } } -/* If the workspace had to be expanded, free the new memory. */ +/* If the workspace had to be expanded, free the new memory. Set the pointer to +NULL to indicate that forward references have been filled in. */ if (cd->workspace_size > COMPILE_WORK_SIZE) (PUBL(free))((void *)cd->start_workspace); +cd->start_workspace = NULL; /* Give an error if there's back reference to a non-existent capturing subpattern. */ if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15; +/* Unless disabled, check whether single character iterators can be +auto-possessified. The function overwrites the appropriate opcode values. */ + +if ((options & PCRE_NO_AUTO_POSSESS) == 0) + auto_possessify((pcre_uchar *)codestart, utf, cd); + /* If there were any lookbehind assertions that contained OP_RECURSE (recursions or subroutine calls), a flag is set for them to be checked here, because they may contain forward references. Actual recursions cannot be fixed @@ -8374,6 +9457,20 @@ if (code - codestart > length) } #endif /* PCRE_DEBUG */ +/* Check for a pattern than can match an empty string, so that this information +can be provided to applications. */ + +do + { + if (could_be_empty_branch(codestart, code, utf, cd, NULL)) + { + re->flags |= PCRE_MATCH_EMPTY; + break; + } + codestart += GET(codestart, 1); + } +while (*codestart == OP_ALT); + #if defined COMPILE_PCRE8 return (pcre *)re; #elif defined COMPILE_PCRE16 @@ -8384,3 +9481,4 @@ return (pcre32 *)re; } /* End of pcre_compile.c */ + diff --git a/tools/pcre/pcre_config.c b/tools/pcre/pcre_config.c index 3d5689f6..1cbdd9c9 100644 --- a/tools/pcre/pcre_config.c +++ b/tools/pcre/pcre_config.c @@ -161,6 +161,10 @@ switch (what) *((int *)where) = POSIX_MALLOC_THRESHOLD; break; + case PCRE_CONFIG_PARENS_LIMIT: + *((unsigned long int *)where) = PARENS_NEST_LIMIT; + break; + case PCRE_CONFIG_MATCH_LIMIT: *((unsigned long int *)where) = MATCH_LIMIT; break; diff --git a/tools/pcre/pcre_dfa_exec.c b/tools/pcre/pcre_dfa_exec.c index 91fb730b..fb0c7e80 100644 --- a/tools/pcre/pcre_dfa_exec.c +++ b/tools/pcre/pcre_dfa_exec.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language (but see below for why this module is different). Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -120,7 +120,7 @@ static const pcre_uint8 coptable[] = { 0, 0, /* \P, \p */ 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */ 0, /* \X */ - 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */ + 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */ 1, /* Char */ 1, /* Chari */ 1, /* not */ @@ -151,11 +151,14 @@ static const pcre_uint8 coptable[] = { /* Character class & ref repeats */ 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */ 0, 0, /* CRRANGE, CRMINRANGE */ + 0, 0, 0, 0, /* Possessive *+, ++, ?+, CRPOSRANGE */ 0, /* CLASS */ 0, /* NCLASS */ 0, /* XCLASS - variable length */ 0, /* REF */ 0, /* REFI */ + 0, /* DNREF */ + 0, /* DNREFI */ 0, /* RECURSE */ 0, /* CALLOUT */ 0, /* Alt */ @@ -171,8 +174,8 @@ static const pcre_uint8 coptable[] = { 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, 0, /* CREF, DNCREF */ + 0, 0, /* RREF, DNRREF */ 0, /* DEF */ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ @@ -194,7 +197,7 @@ static const pcre_uint8 poptable[] = { 1, 1, /* \P, \p */ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ 1, /* \X */ - 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */ + 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */ 1, /* Char */ 1, /* Chari */ 1, /* not */ @@ -220,11 +223,14 @@ static const pcre_uint8 poptable[] = { /* Character class & ref repeats */ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ 1, 1, /* CRRANGE, CRMINRANGE */ + 1, 1, 1, 1, /* Possessive *+, ++, ?+, CRPOSRANGE */ 1, /* CLASS */ 1, /* NCLASS */ 1, /* XCLASS - variable length */ 0, /* REF */ 0, /* REFI */ + 0, /* DNREF */ + 0, /* DNREFI */ 0, /* RECURSE */ 0, /* CALLOUT */ 0, /* Alt */ @@ -240,8 +246,8 @@ static const pcre_uint8 poptable[] = { 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, 0, /* CREF, DNCREF */ + 0, 0, /* RREF, DNRREF */ 0, /* DEF */ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ @@ -636,7 +642,7 @@ for (;;) const pcre_uchar *code; int state_offset = current_state->offset; int codevalue, rrc; - unsigned int count; + int count; #ifdef PCRE_DEBUG printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset); @@ -1094,15 +1100,23 @@ for (;;) PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; - case PT_SPACE: /* Perl space */ - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; - break; + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + case PT_SPACE: /* Perl space */ case PT_PXSPACE: /* POSIX space */ - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || - c == CHAR_FF || c == CHAR_CR; + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; + break; + } break; case PT_WORD: @@ -1120,6 +1134,12 @@ for (;;) } break; + case PT_UCNC: + OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000; + break; + /* Should never occur, but keep compilers from grumbling. */ default: @@ -1249,7 +1269,7 @@ for (;;) (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { - if (++count >= GET2(code, 1)) + if (++count >= (int)GET2(code, 1)) { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); } else { ADD_NEW(state_offset, count); } @@ -1283,7 +1303,7 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - if (++count >= GET2(code, 1)) + if (++count >= (int)GET2(code, 1)) { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } @@ -1338,15 +1358,23 @@ for (;;) PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; - case PT_SPACE: /* Perl space */ - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; - break; + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + case PT_SPACE: /* Perl space */ case PT_PXSPACE: /* POSIX space */ - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || - c == CHAR_FF || c == CHAR_CR; + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; + break; + } break; case PT_WORD: @@ -1364,6 +1392,12 @@ for (;;) } break; + case PT_UCNC: + OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000; + break; + /* Should never occur, but keep compilers from grumbling. */ default: @@ -1439,7 +1473,7 @@ for (;;) goto ANYNL01; case CHAR_CR: - if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1; + if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1; /* Fall through */ ANYNL01: @@ -1576,15 +1610,23 @@ for (;;) PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; - case PT_SPACE: /* Perl space */ - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; - break; + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + case PT_SPACE: /* Perl space */ case PT_PXSPACE: /* POSIX space */ - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || - c == CHAR_FF || c == CHAR_CR; + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; + break; + } break; case PT_WORD: @@ -1602,6 +1644,12 @@ for (;;) } break; + case PT_UCNC: + OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000; + break; + /* Should never occur, but keep compilers from grumbling. */ default: @@ -1694,7 +1742,7 @@ for (;;) goto ANYNL02; case CHAR_CR: - if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1; + if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1; /* Fall through */ ANYNL02: @@ -1705,7 +1753,7 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - ADD_NEW_DATA(-(state_offset + count), 0, ncount); + ADD_NEW_DATA(-(state_offset + (int)count), 0, ncount); break; default: @@ -1749,7 +1797,7 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - ADD_NEW_DATA(-(state_offset + count), 0, 0); + ADD_NEW_DATA(-(state_offset + (int)count), 0, 0); } } break; @@ -1790,7 +1838,7 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - ADD_NEW_DATA(-(state_offset + count), 0, 0); + ADD_NEW_DATA(-(state_offset + (int)count), 0, 0); } } break; @@ -1839,15 +1887,23 @@ for (;;) PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; - case PT_SPACE: /* Perl space */ - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; - break; + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + case PT_SPACE: /* Perl space */ case PT_PXSPACE: /* POSIX space */ - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || - c == CHAR_FF || c == CHAR_CR; + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + OK = TRUE; + break; + + default: + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z; + break; + } break; case PT_WORD: @@ -1865,6 +1921,12 @@ for (;;) } break; + case PT_UCNC: + OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000; + break; + /* Should never occur, but keep compilers from grumbling. */ default: @@ -1879,7 +1941,7 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - if (++count >= GET2(code, 1)) + if (++count >= (int)GET2(code, 1)) { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); } else { ADD_NEW(state_offset, count); } @@ -1918,7 +1980,7 @@ for (;;) } if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) reset_could_continue = TRUE; - if (++count >= GET2(code, 1)) + if (++count >= (int)GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } else { ADD_NEW_DATA(-state_offset, count, ncount); } @@ -1950,7 +2012,7 @@ for (;;) goto ANYNL03; case CHAR_CR: - if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1; + if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1; /* Fall through */ ANYNL03: @@ -1960,7 +2022,7 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - if (++count >= GET2(code, 1)) + if (++count >= (int)GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } else { ADD_NEW_DATA(-state_offset, count, ncount); } @@ -2000,7 +2062,7 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - if (++count >= GET2(code, 1)) + if (++count >= (int)GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } else { ADD_NEW_DATA(-state_offset, count, 0); } @@ -2037,7 +2099,7 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - if (++count >= GET2(code, 1)) + if (++count >= (int)GET2(code, 1)) { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } else { ADD_NEW_DATA(-state_offset, count, 0); } @@ -2148,7 +2210,7 @@ for (;;) if ((md->moptions & PCRE_PARTIAL_HARD) != 0) reset_could_continue = TRUE; } - else if (RAWUCHARTEST(ptr + 1) == CHAR_LF) + else if (UCHAR21TEST(ptr + 1) == CHAR_LF) { ADD_NEW_DATA(-(state_offset + 1), 0, 1); } @@ -2407,7 +2469,7 @@ for (;;) } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { - if (++count >= GET2(code, 1)) + if (++count >= (int)GET2(code, 1)) { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } @@ -2456,7 +2518,7 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - if (++count >= GET2(code, 1)) + if (++count >= (int)GET2(code, 1)) { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } @@ -2509,31 +2571,65 @@ for (;;) { case OP_CRSTAR: case OP_CRMINSTAR: + case OP_CRPOSSTAR: ADD_ACTIVE(next_state_offset + 1, 0); - if (isinclass) { ADD_NEW(state_offset, 0); } + if (isinclass) + { + if (*ecode == OP_CRPOSSTAR) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(state_offset, 0); + } break; case OP_CRPLUS: case OP_CRMINPLUS: + case OP_CRPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); } - if (isinclass) { count++; ADD_NEW(state_offset, count); } + if (isinclass) + { + if (count > 0 && *ecode == OP_CRPOSPLUS) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + count++; + ADD_NEW(state_offset, count); + } break; case OP_CRQUERY: case OP_CRMINQUERY: + case OP_CRPOSQUERY: ADD_ACTIVE(next_state_offset + 1, 0); - if (isinclass) { ADD_NEW(next_state_offset + 1, 0); } + if (isinclass) + { + if (*ecode == OP_CRPOSQUERY) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } + ADD_NEW(next_state_offset + 1, 0); + } break; case OP_CRRANGE: case OP_CRMINRANGE: + case OP_CRPOSRANGE: count = current_state->count; /* Already matched */ - if (count >= GET2(ecode, 1)) + if (count >= (int)GET2(ecode, 1)) { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } if (isinclass) { - unsigned int max = GET2(ecode, 1 + IMM2_SIZE); + int max = (int)GET2(ecode, 1 + IMM2_SIZE); + if (*ecode == OP_CRPOSRANGE) + { + active_count--; /* Remove non-match possibility */ + next_active_state--; + } if (++count >= max && max != 0) /* Max 0 => no limit */ { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } else @@ -2633,9 +2729,11 @@ for (;;) condcode = code[LINK_SIZE+1]; - /* Back reference conditions are not supported */ + /* Back reference conditions and duplicate named recursion conditions + are not supported */ - if (condcode == OP_CREF || condcode == OP_NCREF) + if (condcode == OP_CREF || condcode == OP_DNCREF || + condcode == OP_DNRREF) return PCRE_ERROR_DFA_UCOND; /* The DEFINE condition is always false */ @@ -2647,7 +2745,7 @@ for (;;) which means "test if in any recursion". We can't test for specifically recursed groups. */ - else if (condcode == OP_RREF || condcode == OP_NRREF) + else if (condcode == OP_RREF) { int value = GET2(code, LINK_SIZE + 2); if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND; @@ -3023,15 +3121,7 @@ for (;;) ptr > md->start_used_ptr) /* Inspected non-empty string */ ) ) - { - if (offsetcount >= 2) - { - offsets[0] = (int)(md->start_used_ptr - start_subject); - offsets[1] = (int)(end_subject - start_subject); - } match_count = PCRE_ERROR_PARTIAL; - } - DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n" "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count, rlevel*2-2, SP)); @@ -3376,7 +3466,7 @@ for (;;) if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0) { - /* Advance to a known first char. */ + /* Advance to a known first pcre_uchar (i.e. data item) */ if (has_first_char) { @@ -3384,12 +3474,12 @@ for (;;) { pcre_uchar csc; while (current_subject < end_subject && - (csc = RAWUCHARTEST(current_subject)) != first_char && csc != first_char2) + (csc = UCHAR21TEST(current_subject)) != first_char && csc != first_char2) current_subject++; } else while (current_subject < end_subject && - RAWUCHARTEST(current_subject) != first_char) + UCHAR21TEST(current_subject) != first_char) current_subject++; } @@ -3419,36 +3509,26 @@ for (;;) ANYCRLF, and we are now at a LF, advance the match position by one more character. */ - if (RAWUCHARTEST(current_subject - 1) == CHAR_CR && + if (UCHAR21TEST(current_subject - 1) == CHAR_CR && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) && current_subject < end_subject && - RAWUCHARTEST(current_subject) == CHAR_NL) + UCHAR21TEST(current_subject) == CHAR_NL) current_subject++; } } - /* Or to a non-unique first char after study */ + /* Advance to a non-unique first pcre_uchar after study */ else if (start_bits != NULL) { while (current_subject < end_subject) { - register pcre_uint32 c = RAWUCHARTEST(current_subject); + register pcre_uint32 c = UCHAR21TEST(current_subject); #ifndef COMPILE_PCRE8 if (c > 255) c = 255; #endif - if ((start_bits[c/8] & (1 << (c&7))) == 0) - { - 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; + if ((start_bits[c/8] & (1 << (c&7))) != 0) break; + current_subject++; } } } @@ -3467,19 +3547,20 @@ for (;;) /* 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 pattern. Although the value is, strictly, in characters, we treat it as - bytes to avoid spending too much time in this optimization. */ + in pcre_uchar units to avoid spending too much time in this optimization. + */ if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 && (pcre_uint32)(end_subject - current_subject) < study->minlength) return PCRE_ERROR_NOMATCH; - /* 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 - code for cased/caseless versions makes it go faster, as does using an - autoincrement and backing off on a match. + /* If req_char is set, we know that that pcre_uchar must appear in the + subject for the match to succeed. If the first pcre_uchar 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 code for cased/caseless versions makes it go faster, as does + using an autoincrement and backing off on a match. HOWEVER: when the subject string is very, very long, searching to its end can take a long time, and give bad performance on quite ordinary @@ -3499,7 +3580,7 @@ for (;;) { while (p < end_subject) { - register pcre_uint32 pp = RAWUCHARINCTEST(p); + register pcre_uint32 pp = UCHAR21INCTEST(p); if (pp == req_char || pp == req_char2) { p--; break; } } } @@ -3507,18 +3588,18 @@ for (;;) { while (p < end_subject) { - if (RAWUCHARINCTEST(p) == req_char) { p--; break; } + if (UCHAR21INCTEST(p) == req_char) { p--; break; } } } - /* If we can't find the required character, break the matching loop, + /* If we can't find the required pcre_uchar, break the matching loop, which will cause a return or PCRE_ERROR_NOMATCH. */ if (p >= end_subject) break; - /* If we have found the required character, save the point where we + /* If we have found the required pcre_uchar, save the point where we found it, so that we don't search again next time round the loop if - the start hasn't passed this character yet. */ + the start hasn't passed this point yet. */ req_char_ptr = p; } @@ -3545,7 +3626,17 @@ for (;;) /* Anything other than "no match" means we are done, always; otherwise, carry on only if not anchored. */ - if (rc != PCRE_ERROR_NOMATCH || anchored) return rc; + if (rc != PCRE_ERROR_NOMATCH || anchored) + { + if (rc == PCRE_ERROR_PARTIAL && offsetcount >= 2) + { + offsets[0] = (int)(md->start_used_ptr - (PCRE_PUCHAR)subject); + offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject); + if (offsetcount > 2) + offsets[2] = (int)(current_subject - (PCRE_PUCHAR)subject); + } + return rc; + } /* Advance to the next subject character unless we are at the end of a line and firstline is set. */ @@ -3565,9 +3656,9 @@ for (;;) 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. */ - if (RAWUCHARTEST(current_subject - 1) == CHAR_CR && + if (UCHAR21TEST(current_subject - 1) == CHAR_CR && current_subject < end_subject && - RAWUCHARTEST(current_subject) == CHAR_NL && + UCHAR21TEST(current_subject) == CHAR_NL && (re->flags & PCRE_HASCRORLF) == 0 && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF || diff --git a/tools/pcre/pcre_exec.c b/tools/pcre/pcre_exec.c index 05d0e52d..5dec9923 100644 --- a/tools/pcre/pcre_exec.c +++ b/tools/pcre/pcre_exec.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -56,6 +56,20 @@ possible. There are also some static supporting functions. */ #undef min #undef max +/* The md->capture_last field uses the lower 16 bits for the last captured +substring (which can never be greater than 65535) and a bit in the top half +to mean "capture vector overflowed". This odd way of doing things was +implemented when it was realized that preserving and restoring the overflow bit +whenever the last capture number was saved/restored made for a neater +interface, and doing it this way saved on (a) another variable, which would +have increased the stack frame size (a big NO-NO in PCRE) and (b) another +separate set of save/restore instructions. The following defines are used in +implementing this. */ + +#define CAPLMASK 0x0000ffff /* The bits used for last_capture */ +#define OVFLMASK 0xffff0000 /* The bits used for the overflow flag */ +#define OVFLBIT 0x00010000 /* The bit that is set for overflow */ + /* Values for setting in md->match_function_type to indicate two special types of call to match(). We do it this way to save on using another stack variable, as stack usage is to be discouraged. */ @@ -73,13 +87,17 @@ defined PCRE_ERROR_xxx codes, which are all negative. */ negative to avoid the external error codes. */ #define MATCH_ACCEPT (-999) -#define MATCH_COMMIT (-998) -#define MATCH_KETRPOS (-997) -#define MATCH_ONCE (-996) +#define MATCH_KETRPOS (-998) +#define MATCH_ONCE (-997) +/* The next 5 must be kept together and in sequence so that a test that checks +for any one of them can use a range. */ +#define MATCH_COMMIT (-996) #define MATCH_PRUNE (-995) #define MATCH_SKIP (-994) #define MATCH_SKIP_ARG (-993) #define MATCH_THEN (-992) +#define MATCH_BACKTRACK_MAX MATCH_THEN +#define MATCH_BACKTRACK_MIN MATCH_COMMIT /* Maximum number of ints of offset to save on the stack for recursive calls. If the offset vector is bigger, malloc is used. This should be a multiple of 3, @@ -89,8 +107,8 @@ because the offset vector is always a multiple of 3 long. */ /* Min and max values for the common repeats; for the maxima, 0 => infinity */ -static const char rep_min[] = { 0, 0, 1, 1, 0, 0 }; -static const char rep_max[] = { 0, 0, 0, 0, 1, 1 }; +static const char rep_min[] = { 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, }; +static const char rep_max[] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, }; #ifdef PCRE_DEBUG /************************************************* @@ -116,7 +134,7 @@ pcre_uint32 c; BOOL utf = md->utf; if (is_subject && length > md->end_subject - p) length = md->end_subject - p; while (length-- > 0) - if (isprint(c = RAWUCHARINCTEST(p))) printf("%c", (char)c); else printf("\\x{%02x}", c); + if (isprint(c = UCHAR21INCTEST(p))) printf("%c", (char)c); else printf("\\x{%02x}", c); } #endif @@ -149,7 +167,7 @@ match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md, { PCRE_PUCHAR eptr_start = eptr; register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset]; -#ifdef SUPPORT_UTF +#if defined SUPPORT_UTF && defined SUPPORT_UCP BOOL utf = md->utf; #endif @@ -177,8 +195,7 @@ ASCII characters. */ if (caseless) { -#ifdef SUPPORT_UTF -#ifdef SUPPORT_UCP +#if defined SUPPORT_UTF && defined SUPPORT_UCP if (utf) { /* Match characters up to the end of the reference. NOTE: the number of @@ -211,7 +228,6 @@ if (caseless) } } else -#endif #endif /* The same code works when not in UTF-8 mode and in UTF-8 mode when there @@ -219,10 +235,10 @@ if (caseless) { while (length-- > 0) { - pcre_uchar cc, cp; + pcre_uint32 cc, cp; if (eptr >= md->end_subject) return -2; /* Partial match */ - cc = RAWUCHARTEST(eptr); - cp = RAWUCHARTEST(p); + cc = UCHAR21TEST(eptr); + cp = UCHAR21TEST(p); if (TABLE_GET(cp, md->lcc, cp) != TABLE_GET(cc, md->lcc, cc)) return -1; p++; eptr++; @@ -238,7 +254,7 @@ else while (length-- > 0) { if (eptr >= md->end_subject) return -2; /* Partial match */ - if (RAWUCHARINCTEST(p) != RAWUCHARINCTEST(eptr)) return -1; + if (UCHAR21INCTEST(p) != UCHAR21INCTEST(eptr)) return -1; } } @@ -416,10 +432,10 @@ typedef struct heapframe { int Xlength; int Xmax; int Xmin; - int Xnumber; + unsigned int Xnumber; int Xoffset; - int Xop; - int Xsave_capture_last; + unsigned int Xop; + pcre_int32 Xsave_capture_last; int Xsave_offset1, Xsave_offset2, Xsave_offset3; int Xstacksave[REC_STACK_SAVE_MAX]; @@ -634,8 +650,8 @@ int max; int min; unsigned int number; int offset; -pcre_uchar op; -int save_capture_last; +unsigned int op; +pcre_int32 save_capture_last; int save_offset1, save_offset2, save_offset3; int stacksave[REC_STACK_SAVE_MAX]; @@ -763,23 +779,16 @@ for (;;) case OP_FAIL: RRETURN(MATCH_NOMATCH); - /* COMMIT overrides PRUNE, SKIP, and THEN */ - case OP_COMMIT: RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM52); - if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && - rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG && - rrc != MATCH_THEN) - RRETURN(rrc); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); RRETURN(MATCH_COMMIT); - /* PRUNE overrides THEN */ - case OP_PRUNE: RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM51); - if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); RRETURN(MATCH_PRUNE); case OP_PRUNE_ARG: @@ -789,38 +798,39 @@ for (;;) eptrb, RM56); if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && md->mark == NULL) md->mark = ecode + 2; - if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); RRETURN(MATCH_PRUNE); - /* SKIP overrides PRUNE and THEN */ - case OP_SKIP: RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM53); - if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) - RRETURN(rrc); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->start_match_ptr = eptr; /* Pass back current position */ RRETURN(MATCH_SKIP); /* Note that, for Perl compatibility, SKIP with an argument does NOT set - nomatch_mark. There is a flag that disables this opcode when re-matching a - pattern that ended with a SKIP for which there was not a matching MARK. */ + nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was + not a matching mark, we have to re-run the match, ignoring the SKIP_ARG + that failed and any that precede it (either they also failed, or were not + triggered). To do this, we maintain a count of executed SKIP_ARGs. If a + SKIP_ARG gets to top level, the match is re-run with md->ignore_skip_arg + set to the count of the one that failed. */ case OP_SKIP_ARG: - if (md->ignore_skip_arg) + md->skip_arg_count++; + if (md->skip_arg_count <= md->ignore_skip_arg) { ecode += PRIV(OP_lengths)[*ecode] + ecode[1]; break; } RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, eptrb, RM57); - if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) - RRETURN(rrc); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); /* Pass back the current skip name by overloading md->start_match_ptr and returning the special MATCH_SKIP_ARG return code. This will either be caught by a matching MARK, or get to the top, where it causes a rematch - with the md->ignore_skip_arg flag set. */ + with md->ignore_skip_arg set to the value of md->skip_arg_count. */ md->start_match_ptr = ecode + 2; RRETURN(MATCH_SKIP_ARG); @@ -1066,6 +1076,7 @@ for (;;) /* In all other cases, we have to make another call to match(). */ save_mark = md->mark; + save_capture_last = md->capture_last; RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, RM2); @@ -1097,6 +1108,7 @@ for (;;) ecode += GET(ecode, 1); md->mark = save_mark; if (*ecode != OP_ALT) break; + md->capture_last = save_capture_last; } RRETURN(MATCH_NOMATCH); @@ -1159,6 +1171,7 @@ for (;;) ecode = md->start_code + code_offset; save_capture_last = md->capture_last; matched_once = TRUE; + mstart = md->start_match_ptr; /* In case \K changed it */ continue; } @@ -1218,6 +1231,7 @@ for (;;) POSSESSIVE_NON_CAPTURE: matched_once = FALSE; code_offset = (int)(ecode - md->start_code); + save_capture_last = md->capture_last; for (;;) { @@ -1230,6 +1244,7 @@ for (;;) eptr = md->end_match_ptr; ecode = md->start_code + code_offset; matched_once = TRUE; + mstart = md->start_match_ptr; /* In case \K reset it */ continue; } @@ -1247,6 +1262,7 @@ for (;;) if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += GET(ecode, 1); if (*ecode != OP_ALT) break; + md->capture_last = save_capture_last; } if (matched_once || allow_zero) @@ -1258,25 +1274,32 @@ for (;;) /* Control never reaches here. */ - /* Conditional group: compilation checked that there are no more than - two branches. If the condition is false, skipping the first branch takes us - past the end if there is only one branch, but that's OK because that is - exactly what going to the ket would do. */ + /* Conditional group: compilation checked that there are no more than two + branches. If the condition is false, skipping the first branch takes us + past the end of the item if there is only one branch, but that's exactly + what we want. */ case OP_COND: case OP_SCOND: - codelink = GET(ecode, 1); + + /* The variable codelink will be added to ecode when the condition is + false, to get to the second branch. Setting it to the offset to the ALT + or KET, then incrementing ecode achieves this effect. We now have ecode + pointing to the condition or callout. */ + + codelink = GET(ecode, 1); /* Offset to the second branch */ + ecode += 1 + LINK_SIZE; /* From this opcode */ /* Because of the way auto-callout works during compile, a callout item is inserted between OP_COND and an assertion condition. */ - if (ecode[LINK_SIZE+1] == OP_CALLOUT) + if (*ecode == OP_CALLOUT) { if (PUBL(callout) != NULL) { PUBL(callout_block) cb; cb.version = 2; /* Version 1 of the callout block */ - cb.callout_number = ecode[LINK_SIZE+2]; + cb.callout_number = ecode[1]; cb.offset_vector = md->offset_vector; #if defined COMPILE_PCRE8 cb.subject = (PCRE_SPTR)md->start_subject; @@ -1288,215 +1311,130 @@ for (;;) cb.subject_length = (int)(md->end_subject - md->start_subject); cb.start_match = (int)(mstart - md->start_subject); cb.current_position = (int)(eptr - md->start_subject); - cb.pattern_position = GET(ecode, LINK_SIZE + 3); - cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE); + cb.pattern_position = GET(ecode, 2); + cb.next_item_length = GET(ecode, 2 + LINK_SIZE); cb.capture_top = offset_top/2; - cb.capture_last = md->capture_last; + cb.capture_last = md->capture_last & CAPLMASK; + /* Internal change requires this for API compatibility. */ + if (cb.capture_last == 0) cb.capture_last = -1; cb.callout_data = md->callout_data; cb.mark = md->nomatch_mark; if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } + + /* Advance ecode past the callout, so it now points to the condition. We + must adjust codelink so that the value of ecode+codelink is unchanged. */ + ecode += PRIV(OP_lengths)[OP_CALLOUT]; + codelink -= PRIV(OP_lengths)[OP_CALLOUT]; } - condcode = ecode[LINK_SIZE+1]; + /* Test the various possible conditions */ - /* Now see what the actual condition is */ - - if (condcode == OP_RREF || condcode == OP_NRREF) /* Recursion test */ + condition = FALSE; + switch(condcode = *ecode) { - if (md->recursive == NULL) /* Not recursing => FALSE */ + case OP_RREF: /* Numbered group recursion test */ + if (md->recursive != NULL) /* Not recursing => FALSE */ { - condition = FALSE; - ecode += GET(ecode, 1); - } - else - { - unsigned int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/ + unsigned int recno = GET2(ecode, 1); /* Recursion group number*/ condition = (recno == RREF_ANY || recno == md->recursive->group_num); - - /* 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) - { - pcre_uchar *slotA = md->name_table; - for (i = 0; i < md->name_count; i++) - { - if (GET2(slotA, 0) == recno) break; - slotA += md->name_entry_size; - } - - /* Found a name for the number - there can be only one; duplicate - names for different numbers are allowed, but not vice versa. First - scan down for duplicates. */ - - if (i < md->name_count) - { - pcre_uchar *slotB = slotA; - while (slotB > md->name_table) - { - slotB -= md->name_entry_size; - if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) - { - condition = GET2(slotB, 0) == md->recursive->group_num; - if (condition) break; - } - else break; - } - - /* Scan up for duplicates */ - - if (!condition) - { - slotB = slotA; - for (i++; i < md->name_count; i++) - { - slotB += md->name_entry_size; - if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) - { - condition = GET2(slotB, 0) == md->recursive->group_num; - if (condition) break; - } - else break; - } - } - } - } - - /* Chose branch according to the condition */ - - ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); } - } + break; - else if (condcode == OP_CREF || condcode == OP_NCREF) /* Group used test */ - { - offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */ - condition = offset < offset_top && md->offset_vector[offset] >= 0; - - /* If the numbered capture is unset, but the reference was by name, - scan the table to see if the name refers to any other numbers, and test - them. The condition is true if any one is set. This is tediously similar - to the code above, but not close enough to try to amalgamate. */ - - if (!condition && condcode == OP_NCREF) + case OP_DNRREF: /* Duplicate named group recursion test */ + if (md->recursive != NULL) { - unsigned int refno = offset >> 1; - pcre_uchar *slotA = md->name_table; - - for (i = 0; i < md->name_count; i++) + int count = GET2(ecode, 1 + IMM2_SIZE); + pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size; + while (count-- > 0) { - if (GET2(slotA, 0) == refno) break; - slotA += md->name_entry_size; - } - - /* Found a name for the number - there can be only one; duplicate names - for different numbers are allowed, but not vice versa. First scan down - for duplicates. */ - - if (i < md->name_count) - { - pcre_uchar *slotB = slotA; - while (slotB > md->name_table) - { - slotB -= md->name_entry_size; - if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) - { - offset = GET2(slotB, 0) << 1; - condition = offset < offset_top && - md->offset_vector[offset] >= 0; - if (condition) break; - } - else break; - } - - /* Scan up for duplicates */ - - if (!condition) - { - slotB = slotA; - for (i++; i < md->name_count; i++) - { - slotB += md->name_entry_size; - if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) - { - offset = GET2(slotB, 0) << 1; - condition = offset < offset_top && - md->offset_vector[offset] >= 0; - if (condition) break; - } - else break; - } - } + unsigned int recno = GET2(slot, 0); + condition = recno == md->recursive->group_num; + if (condition) break; + slot += md->name_entry_size; } } + break; - /* Chose branch according to the condition */ + case OP_CREF: /* Numbered group used test */ + offset = GET2(ecode, 1) << 1; /* Doubled ref number */ + condition = offset < offset_top && md->offset_vector[offset] >= 0; + break; - ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); - } + case OP_DNCREF: /* Duplicate named group used test */ + { + int count = GET2(ecode, 1 + IMM2_SIZE); + pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size; + while (count-- > 0) + { + offset = GET2(slot, 0) << 1; + condition = offset < offset_top && md->offset_vector[offset] >= 0; + if (condition) break; + slot += md->name_entry_size; + } + } + break; - else if (condcode == OP_DEF) /* DEFINE - always false */ - { - condition = FALSE; - ecode += GET(ecode, 1); - } + case OP_DEF: /* DEFINE - always false */ + break; - /* The condition is an assertion. Call match() to evaluate it - setting - md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of - an assertion. */ + /* The condition is an assertion. Call match() to evaluate it - setting + md->match_function_type to MATCH_CONDASSERT causes it to stop at the end + of an assertion. */ - else - { + default: md->match_function_type = MATCH_CONDASSERT; - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3); + RMATCH(eptr, ecode, offset_top, md, NULL, RM3); if (rrc == MATCH_MATCH) { if (md->end_offset_top > offset_top) offset_top = md->end_offset_top; /* Captures may have happened */ condition = TRUE; - ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2); + + /* Advance ecode past the assertion to the start of the first branch, + but adjust it so that the general choosing code below works. */ + + ecode += GET(ecode, 1); while (*ecode == OP_ALT) ecode += GET(ecode, 1); + ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode]; } /* PCRE doesn't allow the effect of (*THEN) to escape beyond an - assertion; it is therefore treated as NOMATCH. */ + assertion; it is therefore treated as NOMATCH. Any other return is an + error. */ else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) { RRETURN(rrc); /* Need braces because of following else */ } - else - { - condition = FALSE; - ecode += codelink; - } + break; } - /* We are now at the branch that is to be obeyed. As there is only one, can - use tail recursion to avoid using another stack frame, except when there is - unlimited repeat of a possibly empty group. In the latter case, a recursive - call to match() is always required, unless the second alternative doesn't - exist, in which case we can just plough on. Note that, for compatibility - with Perl, the | in a conditional group is NOT treated as creating two - alternatives. If a THEN is encountered in the branch, it propagates out to - the enclosing alternative (unless nested in a deeper set of alternatives, - of course). */ + /* Choose branch according to the condition */ - if (condition || *ecode == OP_ALT) + ecode += condition? PRIV(OP_lengths)[condcode] : codelink; + + /* We are now at the branch that is to be obeyed. As there is only one, we + can use tail recursion to avoid using another stack frame, except when + there is unlimited repeat of a possibly empty group. In the latter case, a + recursive call to match() is always required, unless the second alternative + doesn't exist, in which case we can just plough on. Note that, for + compatibility with Perl, the | in a conditional group is NOT treated as + creating two alternatives. If a THEN is encountered in the branch, it + propagates out to the enclosing alternative (unless nested in a deeper set + of alternatives, of course). */ + + if (condition || ecode[-(1+LINK_SIZE)] == OP_ALT) { if (op != OP_SCOND) { - ecode += 1 + LINK_SIZE; goto TAIL_RECURSE; } md->match_function_type = MATCH_CBEGROUP; - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM49); RRETURN(rrc); } @@ -1504,7 +1442,6 @@ for (;;) else { - ecode += 1 + LINK_SIZE; } break; @@ -1513,7 +1450,7 @@ for (;;) to close any currently open capturing brackets. */ case OP_CLOSE: - number = GET2(ecode, 1); + number = GET2(ecode, 1); /* Must be less than 65536 */ offset = number << 1; #ifdef PCRE_DEBUG @@ -1521,8 +1458,8 @@ for (;;) printf("\n"); #endif - md->capture_last = number; - if (offset >= md->offset_max) md->offset_overflow = TRUE; else + md->capture_last = (md->capture_last & OVFLMASK) | number; + if (offset >= md->offset_max) md->capture_last |= OVFLBIT; else { md->offset_vector[offset] = md->offset_vector[md->offset_end - number]; @@ -1584,28 +1521,49 @@ for (;;) } else condassert = FALSE; + /* Loop for each branch */ + do { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4); + + /* A match means that the assertion is true; break out of the loop + that matches its alternatives. */ + if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) { mstart = md->start_match_ptr; /* In case \K reset it */ break; } + + /* If not matched, restore the previous mark setting. */ + md->mark = save_mark; - /* A COMMIT failure must fail the entire assertion, without trying any - subsequent branches. */ + /* See comment in the code for capturing groups above about handling + THEN. */ - if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH); + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } - /* PCRE does not allow THEN to escape beyond an assertion; it - is treated as NOMATCH. */ + /* Anything other than NOMATCH causes the entire assertion to fail, + passing back the return code. This includes COMMIT, SKIP, PRUNE and an + uncaptured THEN, which means they take their normal effect. This + consistent approach does not always have exactly the same effect as in + Perl. */ - if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += GET(ecode, 1); } - while (*ecode == OP_ALT); + while (*ecode == OP_ALT); /* Continue for next alternative */ + + /* If we have tried all the alternative branches, the assertion has + failed. If not, we broke out after a match. */ if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH); @@ -1613,17 +1571,16 @@ for (;;) if (condassert) RRETURN(MATCH_MATCH); - /* Continue from after the assertion, updating the offsets high water - mark, since extracts may have been taken during the assertion. */ + /* Continue from after a successful assertion, updating the offsets high + water mark, since extracts may have been taken during the assertion. */ do ecode += GET(ecode,1); while (*ecode == OP_ALT); ecode += 1 + LINK_SIZE; offset_top = md->end_offset_top; continue; - /* Negative assertion: all branches must fail to match. Encountering SKIP, - PRUNE, or COMMIT means we must assume failure without checking subsequent - branches. */ + /* Negative assertion: all branches must fail to match for the assertion to + succeed. */ case OP_ASSERT_NOT: case OP_ASSERTBACK_NOT: @@ -1635,28 +1592,64 @@ for (;;) } else condassert = FALSE; + /* Loop for each alternative branch. */ + do { RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5); - md->mark = save_mark; - if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH); - if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT) + md->mark = save_mark; /* Always restore the mark setting */ + + switch(rrc) { - do ecode += GET(ecode,1); while (*ecode == OP_ALT); + case MATCH_MATCH: /* A successful match means */ + case MATCH_ACCEPT: /* the assertion has failed. */ + RRETURN(MATCH_NOMATCH); + + case MATCH_NOMATCH: /* Carry on with next branch */ break; + + /* See comment in the code for capturing groups above about handling + THEN. */ + + case MATCH_THEN: + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + { + rrc = MATCH_NOMATCH; + break; + } + /* Otherwise fall through. */ + + /* COMMIT, SKIP, PRUNE, and an uncaptured THEN cause the whole + assertion to fail to match, without considering any more alternatives. + Failing to match means the assertion is true. This is a consistent + approach, but does not always have the same effect as in Perl. */ + + case MATCH_COMMIT: + case MATCH_SKIP: + case MATCH_SKIP_ARG: + case MATCH_PRUNE: + do ecode += GET(ecode,1); while (*ecode == OP_ALT); + goto NEG_ASSERT_TRUE; /* Break out of alternation loop */ + + /* Anything else is an error */ + + default: + RRETURN(rrc); } - /* PCRE does not allow THEN to escape beyond an assertion; it is treated - as NOMATCH. */ + /* Continue with next branch */ - if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode,1); } while (*ecode == OP_ALT); - if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */ + /* All branches in the assertion failed to match. */ - ecode += 1 + LINK_SIZE; + NEG_ASSERT_TRUE: + if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */ + ecode += 1 + LINK_SIZE; /* Continue with current branch */ continue; /* Move the subject pointer back. This occurs only at the start of @@ -1716,7 +1709,9 @@ for (;;) cb.pattern_position = GET(ecode, 2); cb.next_item_length = GET(ecode, 2 + LINK_SIZE); cb.capture_top = offset_top/2; - cb.capture_last = md->capture_last; + cb.capture_last = md->capture_last & CAPLMASK; + /* Internal change requires this for API compatibility. */ + if (cb.capture_last == 0) cb.capture_last = -1; cb.callout_data = md->callout_data; cb.mark = md->nomatch_mark; if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); @@ -1762,6 +1757,7 @@ for (;;) /* Add to "recursing stack" */ new_recursive.group_num = recno; + new_recursive.saved_capture_last = md->capture_last; new_recursive.subject_position = eptr; new_recursive.prevrec = md->recursive; md->recursive = &new_recursive; @@ -1785,8 +1781,9 @@ for (;;) new_recursive.saved_max * sizeof(int)); /* OK, now we can do the recursion. After processing each alternative, - restore the offset data. If there were nested recursions, md->recursive - might be changed, so reset it before looping. */ + restore the offset data and the last captured value. If there were nested + recursions, md->recursive might be changed, so reset it before looping. + */ DPRINTF(("Recursing into group %d\n", new_recursive.group_num)); cbegroup = (*callpat >= OP_SBRA); @@ -1797,6 +1794,7 @@ for (;;) md, eptrb, RM6); memcpy(md->offset_vector, new_recursive.offset_save, new_recursive.saved_max * sizeof(int)); + md->capture_last = new_recursive.saved_capture_last; md->recursive = new_recursive.prevrec; if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) { @@ -1813,11 +1811,16 @@ for (;;) goto RECURSION_MATCHED; /* Exit loop; end processing */ } - /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it - is treated as NOMATCH. */ + /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a + recursion; they cause a NOMATCH for the entire recursion. These codes + are defined in a range that can be tested for. */ - else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN && - rrc != MATCH_COMMIT) + if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX) + RRETURN(MATCH_NOMATCH); + + /* Any return code other than NOMATCH is an error. */ + + if (rrc != MATCH_NOMATCH) { DPRINTF(("Recursion gave error %d\n", rrc)); if (new_recursive.offset_save != stacksave) @@ -1947,8 +1950,8 @@ for (;;) /* Deal with capturing */ - md->capture_last = number; - if (offset >= md->offset_max) md->offset_overflow = TRUE; else + md->capture_last = (md->capture_last & OVFLMASK) | number; + if (offset >= md->offset_max) md->capture_last |= OVFLBIT; else { /* If offset is greater than offset_top, it means that we are "skipping" a capturing group, and that group's offsets must be marked @@ -2004,6 +2007,7 @@ for (;;) if (*ecode == OP_KETRPOS) { + md->start_match_ptr = mstart; /* In case \K reset it */ md->end_match_ptr = eptr; md->end_offset_top = offset_top; RRETURN(MATCH_KETRPOS); @@ -2099,7 +2103,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHARTEST(eptr) == NLBLOCK->nl[0]) + UCHAR21TEST(eptr) == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -2143,7 +2147,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHARTEST(eptr) == NLBLOCK->nl[0]) + UCHAR21TEST(eptr) == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -2286,7 +2290,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHARTEST(eptr) == NLBLOCK->nl[0]) + UCHAR21TEST(eptr) == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -2440,7 +2444,7 @@ for (;;) { SCHECK_PARTIAL(); } - else if (RAWUCHARTEST(eptr) == CHAR_LF) eptr++; + else if (UCHAR21TEST(eptr) == CHAR_LF) eptr++; break; case CHAR_LF: @@ -2571,19 +2575,24 @@ for (;;) RRETURN(MATCH_NOMATCH); break; - case PT_SPACE: /* Perl space */ - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) - == (op == OP_NOTPROP)) - RRETURN(MATCH_NOMATCH); - break; + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + case PT_SPACE: /* Perl space */ case PT_PXSPACE: /* POSIX space */ - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || - c == CHAR_FF || c == CHAR_CR) - == (op == OP_NOTPROP)) - RRETURN(MATCH_NOMATCH); + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH); + break; + + default: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == + (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); + break; + } break; case PT_WORD: @@ -2604,6 +2613,13 @@ for (;;) } break; + case PT_UCNC: + if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000) == (op == OP_NOTPROP)) + RRETURN(MATCH_NOMATCH); + break; + /* This should never occur */ default: @@ -2650,15 +2666,7 @@ for (;;) similar code to character type repeats - written out again for speed. However, if the referenced string is the empty string, always treat it as matched, any number of times (otherwise there could be infinite - loops). */ - - case OP_REF: - case OP_REFI: - caseless = op == OP_REFI; - offset = GET2(ecode, 1) << 1; /* Doubled ref number */ - ecode += 1 + IMM2_SIZE; - - /* If the reference is unset, there are two possibilities: + loops). If the reference is unset, there are two possibilities: (a) In the default, Perl-compatible state, set the length negative; this ensures that every attempt at a match fails. We can't just fail @@ -2668,8 +2676,45 @@ for (;;) so that the back reference matches an empty string. Otherwise, set the length to the length of what was matched by the - referenced subpattern. */ + referenced subpattern. + The OP_REF and OP_REFI opcodes are used for a reference to a numbered group + or to a non-duplicated named group. For a duplicated named group, OP_DNREF + and OP_DNREFI are used. In this case we must scan the list of groups to + which the name refers, and use the first one that is set. */ + + case OP_DNREF: + case OP_DNREFI: + caseless = op == OP_DNREFI; + { + int count = GET2(ecode, 1+IMM2_SIZE); + pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size; + ecode += 1 + 2*IMM2_SIZE; + + /* Setting the default length first and initializing 'offset' avoids + compiler warnings in the REF_REPEAT code. */ + + length = (md->jscript_compat)? 0 : -1; + offset = 0; + + while (count-- > 0) + { + offset = GET2(slot, 0) << 1; + if (offset < offset_top && md->offset_vector[offset] >= 0) + { + length = md->offset_vector[offset+1] - md->offset_vector[offset]; + break; + } + slot += md->name_entry_size; + } + } + goto REF_REPEAT; + + case OP_REF: + case OP_REFI: + caseless = op == OP_REFI; + offset = GET2(ecode, 1) << 1; /* Doubled ref number */ + ecode += 1 + IMM2_SIZE; if (offset >= offset_top || md->offset_vector[offset] < 0) length = (md->jscript_compat)? 0 : -1; else @@ -2677,6 +2722,7 @@ for (;;) /* Set up for repetition, or handle the non-repeated case */ + REF_REPEAT: switch (*ecode) { case OP_CRSTAR: @@ -2825,8 +2871,12 @@ for (;;) case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: c = *ecode++ - OP_CRSTAR; - minimize = (c & 1) != 0; + if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0; + else possessive = TRUE; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; @@ -2834,7 +2884,9 @@ for (;;) case OP_CRRANGE: case OP_CRMINRANGE: + case OP_CRPOSRANGE: minimize = (*ecode == OP_CRMINRANGE); + possessive = (*ecode == OP_CRPOSRANGE); min = GET2(ecode, 1); max = GET2(ecode, 1 + IMM2_SIZE); if (max == 0) max = INT_MAX; @@ -2976,6 +3028,9 @@ for (;;) if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; eptr += len; } + + if (possessive) continue; /* No backtracking */ + for (;;) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM18); @@ -3006,6 +3061,9 @@ for (;;) if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; eptr++; } + + if (possessive) continue; /* No backtracking */ + while (eptr >= pp) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM19); @@ -3021,9 +3079,10 @@ for (;;) /* Control never gets here */ - /* Match an extended character class. This opcode is encountered only - when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8 - mode, because Unicode properties are supported in non-UTF-8 mode. */ + /* Match an extended character class. In the 8-bit library, this opcode is + encountered only when UTF-8 mode mode is supported. In the 16-bit and + 32-bit libraries, codepoints greater than 255 may be encountered even when + UTF is not supported. */ #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: @@ -3039,8 +3098,12 @@ for (;;) case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: c = *ecode++ - OP_CRSTAR; - minimize = (c & 1) != 0; + if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0; + else possessive = TRUE; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; @@ -3048,7 +3111,9 @@ for (;;) case OP_CRRANGE: case OP_CRMINRANGE: + case OP_CRPOSRANGE: minimize = (*ecode == OP_CRMINRANGE); + possessive = (*ecode == OP_CRPOSRANGE); min = GET2(ecode, 1); max = GET2(ecode, 1 + IMM2_SIZE); if (max == 0) max = INT_MAX; @@ -3120,6 +3185,9 @@ for (;;) if (!PRIV(xclass)(c, data, utf)) break; eptr += len; } + + if (possessive) continue; /* No backtracking */ + for(;;) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM21); @@ -3150,7 +3218,7 @@ for (;;) CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */ RRETURN(MATCH_NOMATCH); } - while (length-- > 0) if (*ecode++ != RAWUCHARINC(eptr)) RRETURN(MATCH_NOMATCH); + while (length-- > 0) if (*ecode++ != UCHAR21INC(eptr)) RRETURN(MATCH_NOMATCH); } else #endif @@ -3190,7 +3258,7 @@ for (;;) if (fc < 128) { - pcre_uchar cc = RAWUCHAR(eptr); + pcre_uint32 cc = UCHAR21(eptr); if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH); ecode++; eptr++; @@ -3295,7 +3363,22 @@ for (;;) max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; - /* Common code for all repeated single-character matches. */ + /* Common code for all repeated single-character matches. We first check + for the minimum number of characters. If the minimum equals the maximum, we + are done. Otherwise, if minimizing, check the rest of the pattern for a + match; if there isn't one, advance up to the maximum, one character at a + time. + + If maximizing, advance up to the maximum number of matching characters, + until eptr is past the end of the maximum run. If possessive, we are + then done (no backing up). Otherwise, match at this position; anything + other than no match is immediately returned. For nomatch, back up one + character, unless we are matching \R and the last thing matched was + \r\n, in which case, back up two bytes. When we reach the first optional + character position, we can save stack by doing a tail recurse. + + The various UTF/non-UTF and caseful/caseless cases are handled separately, + for speed. */ REPEATCHAR: #ifdef SUPPORT_UTF @@ -3379,13 +3462,12 @@ for (;;) } } - if (possessive) continue; - + if (possessive) continue; /* No backtracking */ for(;;) { + if (eptr == pp) goto TAIL_RECURSE; RMATCH(eptr, ecode, offset_top, md, eptrb, RM23); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr == pp) { RRETURN(MATCH_NOMATCH); } #ifdef SUPPORT_UCP eptr--; BACKCHAR(eptr); @@ -3439,14 +3521,13 @@ for (;;) for (i = 1; i <= min; i++) { - pcre_uchar cc; - + pcre_uint32 cc; /* Faster than pcre_uchar */ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHARTEST(eptr); + cc = UCHAR21TEST(eptr); if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH); eptr++; } @@ -3455,8 +3536,7 @@ for (;;) { for (fi = min;; fi++) { - pcre_uchar cc; - + pcre_uint32 cc; /* Faster than pcre_uchar */ RMATCH(eptr, ecode, offset_top, md, eptrb, RM24); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); @@ -3465,7 +3545,7 @@ for (;;) SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHARTEST(eptr); + cc = UCHAR21TEST(eptr); if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH); eptr++; } @@ -3476,29 +3556,26 @@ for (;;) pp = eptr; for (i = min; i < max; i++) { - pcre_uchar cc; - + pcre_uint32 cc; /* Faster than pcre_uchar */ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } - cc = RAWUCHARTEST(eptr); + cc = UCHAR21TEST(eptr); if (fc != cc && foc != cc) break; eptr++; } - - if (possessive) continue; - - while (eptr >= pp) + if (possessive) continue; /* No backtracking */ + for (;;) { + if (eptr == pp) goto TAIL_RECURSE; RMATCH(eptr, ecode, offset_top, md, eptrb, RM25); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } - RRETURN(MATCH_NOMATCH); + /* Control never gets here */ } - /* Control never gets here */ } /* Caseful comparisons (includes all multi-byte characters) */ @@ -3512,7 +3589,7 @@ for (;;) SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH); + if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH); } if (min == max) continue; @@ -3529,7 +3606,7 @@ for (;;) SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH); + if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -3543,18 +3620,18 @@ for (;;) SCHECK_PARTIAL(); break; } - if (fc != RAWUCHARTEST(eptr)) break; + if (fc != UCHAR21TEST(eptr)) break; eptr++; } - if (possessive) continue; - - while (eptr >= pp) + if (possessive) continue; /* No backtracking */ + for (;;) { + if (eptr == pp) goto TAIL_RECURSE; RMATCH(eptr, ecode, offset_top, md, eptrb, RM27); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } - RRETURN(MATCH_NOMATCH); + /* Control never gets here */ } } /* Control never gets here */ @@ -3726,7 +3803,7 @@ for (;;) } } else -#endif +#endif /* SUPPORT_UTF */ /* Not UTF mode */ { for (i = 1; i <= min; i++) @@ -3764,7 +3841,7 @@ for (;;) } } else -#endif +#endif /*SUPPORT_UTF */ /* Not UTF mode */ { for (fi = min;; fi++) @@ -3806,17 +3883,18 @@ for (;;) if (fc == d || (unsigned int)foc == d) break; eptr += len; } - if (possessive) continue; + if (possessive) continue; /* No backtracking */ for(;;) { + if (eptr == pp) goto TAIL_RECURSE; RMATCH(eptr, ecode, offset_top, md, eptrb, RM30); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr-- == pp) break; /* Stop if tried at original pos */ + eptr--; BACKCHAR(eptr); } } else -#endif +#endif /* SUPPORT_UTF */ /* Not UTF mode */ { for (i = min; i < max; i++) @@ -3829,18 +3907,17 @@ for (;;) if (fc == *eptr || foc == *eptr) break; eptr++; } - if (possessive) continue; - while (eptr >= pp) + if (possessive) continue; /* No backtracking */ + for (;;) { + if (eptr == pp) goto TAIL_RECURSE; RMATCH(eptr, ecode, offset_top, md, eptrb, RM31); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } - - RRETURN(MATCH_NOMATCH); + /* Control never gets here */ } - /* Control never gets here */ } /* Caseful comparisons */ @@ -3941,12 +4018,13 @@ for (;;) if (fc == d) break; eptr += len; } - if (possessive) continue; + if (possessive) continue; /* No backtracking */ for(;;) { + if (eptr == pp) goto TAIL_RECURSE; RMATCH(eptr, ecode, offset_top, md, eptrb, RM34); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr-- == pp) break; /* Stop if tried at original pos */ + eptr--; BACKCHAR(eptr); } } @@ -3964,16 +4042,16 @@ for (;;) if (fc == *eptr) break; eptr++; } - if (possessive) continue; - while (eptr >= pp) + if (possessive) continue; /* No backtracking */ + for (;;) { + if (eptr == pp) goto TAIL_RECURSE; RMATCH(eptr, ecode, offset_top, md, eptrb, RM35); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } - - RRETURN(MATCH_NOMATCH); + /* Control never gets here */ } } /* Control never gets here */ @@ -4155,22 +4233,11 @@ for (;;) } break; - case PT_SPACE: /* Perl space */ - for (i = 1; i <= min; i++) - { - if (eptr >= md->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || - c == CHAR_FF || c == CHAR_CR) - == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - break; + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + case PT_SPACE: /* Perl space */ case PT_PXSPACE: /* POSIX space */ for (i = 1; i <= min; i++) { @@ -4180,10 +4247,18 @@ for (;;) RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || - c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) - == prop_fail_result) - RRETURN(MATCH_NOMATCH); + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + if (prop_fail_result) RRETURN(MATCH_NOMATCH); + break; + + default: + if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + break; + } } break; @@ -4225,6 +4300,22 @@ for (;;) } break; + case PT_UCNC: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + break; + /* This should not occur */ default: @@ -4284,7 +4375,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHAR(eptr) == NLBLOCK->nl[0]) + UCHAR21(eptr) == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -4326,7 +4417,7 @@ for (;;) default: RRETURN(MATCH_NOMATCH); case CHAR_CR: - if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++; + if (eptr < md->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++; break; case CHAR_LF: @@ -4430,14 +4521,13 @@ for (;;) case OP_DIGIT: for (i = 1; i <= min; i++) { - pcre_uchar cc; - + pcre_uint32 cc; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHAR(eptr); + cc = UCHAR21(eptr); if (cc >= 128 || (md->ctypes[cc] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); eptr++; @@ -4448,14 +4538,13 @@ for (;;) case OP_NOT_WHITESPACE: for (i = 1; i <= min; i++) { - pcre_uchar cc; - + pcre_uint32 cc; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHAR(eptr); + cc = UCHAR21(eptr); if (cc < 128 && (md->ctypes[cc] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); eptr++; @@ -4466,14 +4555,13 @@ for (;;) case OP_WHITESPACE: for (i = 1; i <= min; i++) { - pcre_uchar cc; - + pcre_uint32 cc; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHAR(eptr); + cc = UCHAR21(eptr); if (cc >= 128 || (md->ctypes[cc] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); eptr++; @@ -4484,14 +4572,13 @@ for (;;) case OP_NOT_WORDCHAR: for (i = 1; i <= min; i++) { - pcre_uchar cc; - + pcre_uint32 cc; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHAR(eptr); + cc = UCHAR21(eptr); if (cc < 128 && (md->ctypes[cc] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); eptr++; @@ -4502,14 +4589,13 @@ for (;;) case OP_WORDCHAR: for (i = 1; i <= min; i++) { - pcre_uchar cc; - + pcre_uint32 cc; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHAR(eptr); + cc = UCHAR21(eptr); if (cc >= 128 || (md->ctypes[cc] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); eptr++; @@ -4892,25 +4978,11 @@ for (;;) } /* Control never gets here */ - case PT_SPACE: /* Perl space */ - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, md, eptrb, RM60); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= md->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || - c == CHAR_FF || c == CHAR_CR) - == prop_fail_result) - RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + case PT_SPACE: /* Perl space */ case PT_PXSPACE: /* POSIX space */ for (fi = min;; fi++) { @@ -4923,10 +4995,18 @@ for (;;) RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || - c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) - == prop_fail_result) - RRETURN(MATCH_NOMATCH); + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + if (prop_fail_result) RRETURN(MATCH_NOMATCH); + break; + + default: + if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + break; + } } /* Control never gets here */ @@ -4976,6 +5056,25 @@ for (;;) } /* Control never gets here */ + case PT_UCNC: + for (fi = min;; fi++) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM60); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(c, eptr); + if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + /* This should never occur */ default: RRETURN(PCRE_ERROR_INTERNAL); @@ -5057,7 +5156,7 @@ for (;;) { default: RRETURN(MATCH_NOMATCH); case CHAR_CR: - if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++; + if (eptr < md->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++; break; case CHAR_LF: @@ -5391,24 +5490,11 @@ for (;;) } break; - case PT_SPACE: /* Perl space */ - for (i = min; i < max; i++) - { - int len = 1; - if (eptr >= md->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || - c == CHAR_FF || c == CHAR_CR) - == prop_fail_result) - break; - eptr+= len; - } - break; + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + case PT_SPACE: /* Perl space */ case PT_PXSPACE: /* POSIX space */ for (i = min; i < max; i++) { @@ -5419,12 +5505,21 @@ for (;;) break; } GETCHARLENTEST(c, eptr, len); - if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || - c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) - == prop_fail_result) + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + if (prop_fail_result) goto ENDLOOP99; /* Break the loop */ break; + + default: + if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result) + goto ENDLOOP99; /* Break the loop */ + break; + } eptr+= len; } + ENDLOOP99: break; case PT_WORD: @@ -5470,23 +5565,42 @@ for (;;) GOT_MAX: break; + case PT_UCNC: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(c, eptr, len); + if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) || + c >= 0xe000) == prop_fail_result) + break; + eptr += len; + } + break; + default: RRETURN(PCRE_ERROR_INTERNAL); } /* eptr is now past the end of the maximum run */ - if (possessive) continue; + if (possessive) continue; /* No backtracking */ for(;;) { + if (eptr == pp) goto TAIL_RECURSE; RMATCH(eptr, ecode, offset_top, md, eptrb, RM44); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr-- == pp) break; /* Stop if tried at original pos */ + eptr--; if (utf) BACKCHAR(eptr); } } - /* Match extended Unicode sequences. We will get here only if the + /* Match extended Unicode grapheme clusters. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ else if (ctype == OP_EXTUNI) @@ -5518,22 +5632,42 @@ for (;;) /* eptr is now past the end of the maximum run */ - if (possessive) continue; + if (possessive) continue; /* No backtracking */ for(;;) { + int lgb, rgb; + PCRE_PUCHAR fptr; + + if (eptr == pp) goto TAIL_RECURSE; /* At start of char run */ RMATCH(eptr, ecode, offset_top, md, eptrb, RM45); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr-- == pp) break; /* Stop if tried at original pos */ - for (;;) /* Move back over one extended */ + + /* Backtracking over an extended grapheme cluster involves inspecting + the previous two characters (if present) to see if a break is + permitted between them. */ + + eptr--; + if (!utf) c = *eptr; else { - if (!utf) c = *eptr; else + BACKCHAR(eptr); + GETCHAR(c, eptr); + } + rgb = UCD_GRAPHBREAK(c); + + for (;;) + { + if (eptr == pp) goto TAIL_RECURSE; /* At start of char run */ + fptr = eptr - 1; + if (!utf) c = *fptr; else { - BACKCHAR(eptr); - GETCHAR(c, eptr); + BACKCHAR(fptr); + GETCHAR(c, fptr); } - if (UCD_CATEGORY(c) != ucp_M) break; - eptr--; + lgb = UCD_GRAPHBREAK(c); + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + eptr = fptr; + rgb = lgb; } } } @@ -5561,7 +5695,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHAR(eptr) == NLBLOCK->nl[0]) + UCHAR21(eptr) == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -5587,7 +5721,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHAR(eptr) == NLBLOCK->nl[0]) + UCHAR21(eptr) == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -5644,7 +5778,7 @@ for (;;) if (c == CHAR_CR) { if (++eptr >= md->end_subject) break; - if (RAWUCHAR(eptr) == CHAR_LF) eptr++; + if (UCHAR21(eptr) == CHAR_LF) eptr++; } else { @@ -5799,21 +5933,16 @@ for (;;) RRETURN(PCRE_ERROR_INTERNAL); } - /* eptr is now past the end of the maximum run. If possessive, we are - done (no backing up). Otherwise, match at this position; anything other - than no match is immediately returned. For nomatch, back up one - character, unless we are matching \R and the last thing matched was - \r\n, in which case, back up two bytes. */ - - if (possessive) continue; + if (possessive) continue; /* No backtracking */ for(;;) { + if (eptr == pp) goto TAIL_RECURSE; RMATCH(eptr, ecode, offset_top, md, eptrb, RM46); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr-- == pp) break; /* Stop if tried at original pos */ + eptr--; BACKCHAR(eptr); - if (ctype == OP_ANYNL && eptr > pp && RAWUCHAR(eptr) == CHAR_NL && - RAWUCHAR(eptr - 1) == CHAR_CR) eptr--; + if (ctype == OP_ANYNL && eptr > pp && UCHAR21(eptr) == CHAR_NL && + UCHAR21(eptr - 1) == CHAR_CR) eptr--; } } else @@ -6048,15 +6177,10 @@ for (;;) RRETURN(PCRE_ERROR_INTERNAL); } - /* eptr is now past the end of the maximum run. If possessive, we are - done (no backing up). Otherwise, match at this position; anything other - than no match is immediately returned. For nomatch, back up one - character (byte), unless we are matching \R and the last thing matched - was \r\n, in which case, back up two bytes. */ - - if (possessive) continue; - while (eptr >= pp) + if (possessive) continue; /* No backtracking */ + for (;;) { + if (eptr == pp) goto TAIL_RECURSE; RMATCH(eptr, ecode, offset_top, md, eptrb, RM47); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; @@ -6065,11 +6189,8 @@ for (;;) } } - /* Get here if we can't make it match with any permitted repetitions */ - - RRETURN(MATCH_NOMATCH); + /* Control never gets here */ } - /* Control never gets here */ /* There's been some horrible disaster. Arrival here can only mean there is something seriously wrong in the code above or the OP_xxx definitions. */ @@ -6103,10 +6224,10 @@ switch (frame->Xwhere) LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64) LBL(65) LBL(66) #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 - LBL(21) + LBL(20) LBL(21) #endif #ifdef SUPPORT_UTF - LBL(16) LBL(18) LBL(20) + LBL(16) LBL(18) LBL(22) LBL(23) LBL(28) LBL(30) LBL(32) LBL(34) LBL(42) LBL(46) #ifdef SUPPORT_UCP @@ -6264,6 +6385,7 @@ const pcre_uint8 *start_bits = NULL; PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset; PCRE_PUCHAR end_subject; PCRE_PUCHAR start_partial = NULL; +PCRE_PUCHAR match_partial = NULL; PCRE_PUCHAR req_char_ptr = start_match - 1; const pcre_study_data *study; @@ -6393,6 +6515,8 @@ md->callout_data = NULL; tables = re->tables; +/* The two limit values override the defaults, whatever their value. */ + if (extra_data != NULL) { register unsigned int flags = extra_data->flags; @@ -6407,6 +6531,15 @@ if (extra_data != NULL) if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables; } +/* Limits in the regex override only if they are smaller. */ + +if ((re->flags & PCRE_MLSET) != 0 && re->limit_match < md->match_limit) + md->match_limit = re->limit_match; + +if ((re->flags & PCRE_RLSET) != 0 && + re->limit_recursion < md->match_limit_recursion) + md->match_limit_recursion = re->limit_recursion; + /* If the exec call supplied NULL for tables, use the inbuilt ones. This is a feature that makes it possible to save compiled regex and re-use them in other programs later. */ @@ -6432,7 +6565,7 @@ end_subject = md->end_subject; md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; md->use_ucp = (re->options & PCRE_UCP) != 0; md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; -md->ignore_skip_arg = FALSE; +md->ignore_skip_arg = 0; /* Some options are unpacked into BOOL variables in the hope that testing them will be faster than individual option bits. */ @@ -6542,11 +6675,9 @@ if (re->top_backref > 0 && re->top_backref >= ocount/3) DPRINTF(("Got memory to hold back references\n")); } else md->offset_vector = offsets; - md->offset_end = ocount; md->offset_max = (2*ocount)/3; -md->offset_overflow = FALSE; -md->capture_last = -1; +md->capture_last = 0; /* Reset the working variable associated with each extraction. These should never be used unless previously set, but they get saved and restored, and so we @@ -6658,10 +6789,10 @@ for(;;) if (first_char != first_char2) while (start_match < end_subject && - (smc = RAWUCHARTEST(start_match)) != first_char && smc != first_char2) + (smc = UCHAR21TEST(start_match)) != first_char && smc != first_char2) start_match++; else - while (start_match < end_subject && RAWUCHARTEST(start_match) != first_char) + while (start_match < end_subject && UCHAR21TEST(start_match) != first_char) start_match++; } @@ -6693,7 +6824,7 @@ for(;;) if (start_match[-1] == CHAR_CR && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) && start_match < end_subject && - RAWUCHARTEST(start_match) == CHAR_NL) + UCHAR21TEST(start_match) == CHAR_NL) start_match++; } } @@ -6704,22 +6835,12 @@ for(;;) { while (start_match < end_subject) { - register pcre_uint32 c = RAWUCHARTEST(start_match); + register pcre_uint32 c = UCHAR21TEST(start_match); #ifndef COMPILE_PCRE8 if (c > 255) c = 255; #endif - if ((start_bits[c/8] & (1 << (c&7))) == 0) - { - 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; + if ((start_bits[c/8] & (1 << (c&7))) != 0) break; + start_match++; } } } /* Starting optimizations */ @@ -6772,7 +6893,7 @@ for(;;) { while (p < end_subject) { - register pcre_uint32 pp = RAWUCHARINCTEST(p); + register pcre_uint32 pp = UCHAR21INCTEST(p); if (pp == req_char || pp == req_char2) { p--; break; } } } @@ -6780,7 +6901,7 @@ for(;;) { while (p < end_subject) { - if (RAWUCHARINCTEST(p) == req_char) { p--; break; } + if (UCHAR21INCTEST(p) == req_char) { p--; break; } } } @@ -6816,8 +6937,13 @@ for(;;) md->match_call_count = 0; md->match_function_type = 0; md->end_offset_top = 0; + md->skip_arg_count = 0; rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0); - if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr; + if (md->hitend && start_partial == NULL) + { + start_partial = md->start_used_ptr; + match_partial = start_match; + } switch(rc) { @@ -6830,14 +6956,14 @@ for(;;) case MATCH_SKIP_ARG: new_start_match = start_match; - md->ignore_skip_arg = TRUE; + md->ignore_skip_arg = md->skip_arg_count; break; - /* SKIP passes back the next starting point explicitly, but if it is the - same as the match we have just done, treat it as NOMATCH. */ + /* SKIP passes back the next starting point explicitly, but if it is no + greater than the match we have just done, treat it as NOMATCH. */ case MATCH_SKIP: - if (md->start_match_ptr != start_match) + if (md->start_match_ptr > start_match) { new_start_match = md->start_match_ptr; break; @@ -6845,12 +6971,12 @@ for(;;) /* Fall through */ /* NOMATCH and PRUNE advance by one character. THEN at this level acts - exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */ + exactly like PRUNE. Unset ignore SKIP-with-argument. */ case MATCH_NOMATCH: case MATCH_PRUNE: case MATCH_THEN: - md->ignore_skip_arg = FALSE; + md->ignore_skip_arg = 0; new_start_match = start_match + 1; #ifdef SUPPORT_UTF if (utf) @@ -6943,7 +7069,7 @@ if (rc == MATCH_MATCH || rc == MATCH_ACCEPT) (arg_offset_max - 2) * sizeof(int)); DPRINTF(("Copied offsets from temporary memory\n")); } - if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE; + if (md->end_offset_top > arg_offset_max) md->capture_last |= OVFLBIT; DPRINTF(("Freeing temporary memory\n")); (PUBL(free))(md->offset_vector); } @@ -6951,7 +7077,8 @@ if (rc == MATCH_MATCH || rc == MATCH_ACCEPT) /* Set the return code to the number of captured strings, or 0 if there were too many to fit into the vector. */ - rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)? + rc = ((md->capture_last & OVFLBIT) != 0 && + md->end_offset_top >= arg_offset_max)? 0 : md->end_offset_top/2; /* If there is space in the offset vector, set any unused pairs at the end of @@ -7016,7 +7143,7 @@ if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL) /* Handle partial matches - disable any mark data */ -if (start_partial != NULL) +if (match_partial != NULL) { DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n")); md->mark = NULL; @@ -7024,6 +7151,8 @@ if (start_partial != NULL) { offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject); offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject); + if (offsetcount > 2) + offsets[2] = (int)(match_partial - (PCRE_PUCHAR)subject); } rc = PCRE_ERROR_PARTIAL; } diff --git a/tools/pcre/pcre_fullinfo.c b/tools/pcre/pcre_fullinfo.c index 02c9df4a..a6c2ece6 100644 --- a/tools/pcre/pcre_fullinfo.c +++ b/tools/pcre/pcre_fullinfo.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2013 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -222,6 +222,20 @@ switch (what) *((int *)where) = re->max_lookbehind; break; + case PCRE_INFO_MATCHLIMIT: + if ((re->flags & PCRE_MLSET) == 0) return PCRE_ERROR_UNSET; + *((pcre_uint32 *)where) = re->limit_match; + break; + + case PCRE_INFO_RECURSIONLIMIT: + if ((re->flags & PCRE_RLSET) == 0) return PCRE_ERROR_UNSET; + *((pcre_uint32 *)where) = re->limit_recursion; + break; + + case PCRE_INFO_MATCH_EMPTY: + *((int *)where) = (re->flags & PCRE_MATCH_EMPTY) != 0; + break; + default: return PCRE_ERROR_BADOPTION; } diff --git a/tools/pcre/pcre_globals.c b/tools/pcre/pcre_globals.c index 36e6ddb3..0f106aa9 100644 --- a/tools/pcre/pcre_globals.c +++ b/tools/pcre/pcre_globals.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -72,6 +72,7 @@ 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; +PCRE_EXP_DATA_DEFN int (*PUBL(stack_guard))(void) = NULL; #elif !defined VPCOMPAT PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = malloc; @@ -79,6 +80,7 @@ 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; +PCRE_EXP_DATA_DEFN int (*PUBL(stack_guard))(void) = NULL; #endif /* End of pcre_globals.c */ diff --git a/tools/pcre/pcre_internal.h b/tools/pcre/pcre_internal.h index f3cb001f..6e915a0e 100644 --- a/tools/pcre/pcre_internal.h +++ b/tools/pcre/pcre_internal.h @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -194,23 +194,31 @@ preprocessor time in standard C environments. */ typedef unsigned char pcre_uint8; #if USHRT_MAX == 65535 - typedef unsigned short pcre_uint16; - typedef short pcre_int16; +typedef unsigned short pcre_uint16; +typedef short pcre_int16; +#define PCRE_UINT16_MAX USHRT_MAX +#define PCRE_INT16_MAX SHRT_MAX #elif UINT_MAX == 65535 - typedef unsigned int pcre_uint16; - typedef int pcre_int16; +typedef unsigned int pcre_uint16; +typedef int pcre_int16; +#define PCRE_UINT16_MAX UINT_MAX +#define PCRE_INT16_MAX INT_MAX #else -# error Cannot determine a type for 16-bit unsigned integers +#error Cannot determine a type for 16-bit integers #endif -#if UINT_MAX == 4294967295 - typedef unsigned int pcre_uint32; - typedef int pcre_int32; -#elif ULONG_MAX == 4294967295 - typedef unsigned long int pcre_uint32; - typedef long int pcre_int32; +#if UINT_MAX == 4294967295U +typedef unsigned int pcre_uint32; +typedef int pcre_int32; +#define PCRE_UINT32_MAX UINT_MAX +#define PCRE_INT32_MAX INT_MAX +#elif ULONG_MAX == 4294967295UL +typedef unsigned long int pcre_uint32; +typedef long int pcre_int32; +#define PCRE_UINT32_MAX ULONG_MAX +#define PCRE_INT32_MAX LONG_MAX #else -# error Cannot determine a type for 32-bit unsigned integers +#error Cannot determine a type for 32-bit integers #endif /* When checking for integer overflow in pcre_compile(), we need to handle @@ -308,8 +316,8 @@ start/end of string field names are. */ &(NLBLOCK->nllen), utf)) \ : \ ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \ - RAWUCHARTEST(p) == NLBLOCK->nl[0] && \ - (NLBLOCK->nllen == 1 || RAWUCHARTEST(p+1) == NLBLOCK->nl[1]) \ + UCHAR21TEST(p) == NLBLOCK->nl[0] && \ + (NLBLOCK->nllen == 1 || UCHAR21TEST(p+1) == NLBLOCK->nl[1]) \ ) \ ) @@ -322,8 +330,8 @@ start/end of string field names are. */ &(NLBLOCK->nllen), utf)) \ : \ ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \ - RAWUCHARTEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \ - (NLBLOCK->nllen == 1 || RAWUCHARTEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \ + UCHAR21TEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \ + (NLBLOCK->nllen == 1 || UCHAR21TEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \ ) \ ) @@ -574,12 +582,27 @@ changed in future to be a fixed number of bytes or to depend on LINK_SIZE. */ #define MAX_MARK ((1u << 8) - 1) #endif +/* There is a proposed future special "UTF-21" mode, in which only the lowest +21 bits of a 32-bit character are interpreted as UTF, with the remaining 11 +high-order bits available to the application for other uses. In preparation for +the future implementation of this mode, there are macros that load a data item +and, if in this special mode, mask it to 21 bits. These macros all have names +starting with UCHAR21. In all other modes, including the normal 32-bit +library, the macros all have the same simple definitions. When the new mode is +implemented, it is expected that these definitions will be varied appropriately +using #ifdef when compiling the library that supports the special mode. */ + +#define UCHAR21(eptr) (*(eptr)) +#define UCHAR21TEST(eptr) (*(eptr)) +#define UCHAR21INC(eptr) (*(eptr)++) +#define UCHAR21INCTEST(eptr) (*(eptr)++) + /* When UTF encoding is being used, a character is no longer just a single -byte. 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. */ +byte in 8-bit mode or a single short in 16-bit mode. The macros for character +handling generate simple sequences when used in the basic mode, and more +complicated ones for UTF characters. GETCHARLENTEST and other macros are not +used when UTF is not supported. To make sure they can never even appear when +UTF support is omitted, we don't even define them. */ #ifndef SUPPORT_UTF @@ -592,10 +615,6 @@ we don't even define them. */ #define GETCHARINC(c, eptr) c = *eptr++; #define GETCHARINCTEST(c, eptr) c = *eptr++; #define GETCHARLEN(c, eptr, len) c = *eptr; -#define RAWUCHAR(eptr) (*(eptr)) -#define RAWUCHARINC(eptr) (*(eptr)++) -#define RAWUCHARTEST(eptr) (*(eptr)) -#define RAWUCHARINCTEST(eptr) (*(eptr)++) /* #define GETCHARLENTEST(c, eptr, len) */ /* #define BACKCHAR(eptr) */ /* #define FORWARDCHAR(eptr) */ @@ -768,30 +787,6 @@ do not know if we are in UTF-8 mode. */ c = *eptr; \ if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len); -/* Returns the next uchar, not advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHAR(eptr) \ - (*(eptr)) - -/* Returns the next uchar, advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHARINC(eptr) \ - (*((eptr)++)) - -/* Returns the next uchar, testing for UTF mode, and not advancing the -pointer. */ - -#define RAWUCHARTEST(eptr) \ - (*(eptr)) - -/* Returns the next uchar, testing for UTF mode, advancing the -pointer. */ - -#define RAWUCHARINCTEST(eptr) \ - (*((eptr)++)) - /* 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 because almost all calls are already within a block of UTF-8 only code. */ @@ -887,30 +882,6 @@ we do not know if we are in UTF-16 mode. */ c = *eptr; \ if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); -/* Returns the next uchar, not advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHAR(eptr) \ - (*(eptr)) - -/* Returns the next uchar, advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHARINC(eptr) \ - (*((eptr)++)) - -/* Returns the next uchar, testing for UTF mode, and not advancing the -pointer. */ - -#define RAWUCHARTEST(eptr) \ - (*(eptr)) - -/* Returns the next uchar, testing for UTF mode, advancing the -pointer. */ - -#define RAWUCHARINCTEST(eptr) \ - (*((eptr)++)) - /* 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 @@ -972,30 +943,6 @@ This is called when we do not know if we are in UTF-32 mode. */ #define GETCHARLENTEST(c, eptr, len) \ GETCHARTEST(c, eptr) -/* Returns the next uchar, not advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHAR(eptr) \ - (*(eptr)) - -/* Returns the next uchar, advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHARINC(eptr) \ - (*((eptr)++)) - -/* Returns the next uchar, testing for UTF mode, and not advancing the -pointer. */ - -#define RAWUCHARTEST(eptr) \ - (*(eptr)) - -/* Returns the next uchar, testing for UTF mode, advancing the -pointer. */ - -#define RAWUCHARINCTEST(eptr) \ - (*((eptr)++)) - /* If the pointer is not at the start of a character, move it back until it is. This is called only in UTF-32 mode - we don't put a test within the macro because almost all calls are already within a block of UTF-32 only @@ -1121,23 +1068,27 @@ other. NOTE: The values also appear in pcre_jit_compile.c. */ /* Private flags containing information about the compiled regex. They used to -live at the top end of the options word, but that got almost full, so now they -are in a 16-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as -the restrictions on partial matching have been lifted. It remains for backwards +live at the top end of the options word, but that got almost full, so they were +moved to a 16-bit flags word - which got almost full, so now they are in a +32-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as the +restrictions on partial matching have been lifted. It remains for backwards compatibility. */ -#define PCRE_MODE8 0x0001 /* compiled in 8 bit mode */ -#define PCRE_MODE16 0x0002 /* compiled in 16 bit mode */ -#define PCRE_MODE32 0x0004 /* compiled in 32 bit mode */ -#define PCRE_FIRSTSET 0x0010 /* first_char is set */ -#define PCRE_FCH_CASELESS 0x0020 /* caseless first char */ -#define PCRE_REQCHSET 0x0040 /* req_byte is set */ -#define PCRE_RCH_CASELESS 0x0080 /* caseless requested char */ -#define PCRE_STARTLINE 0x0100 /* start after \n for multiline */ -#define PCRE_NOPARTIAL 0x0200 /* can't use partial with this regex */ -#define PCRE_JCHANGED 0x0400 /* j option used in regex */ -#define PCRE_HASCRORLF 0x0800 /* explicit \r or \n in pattern */ -#define PCRE_HASTHEN 0x1000 /* pattern contains (*THEN) */ +#define PCRE_MODE8 0x00000001 /* compiled in 8 bit mode */ +#define PCRE_MODE16 0x00000002 /* compiled in 16 bit mode */ +#define PCRE_MODE32 0x00000004 /* compiled in 32 bit mode */ +#define PCRE_FIRSTSET 0x00000010 /* first_char is set */ +#define PCRE_FCH_CASELESS 0x00000020 /* caseless first char */ +#define PCRE_REQCHSET 0x00000040 /* req_byte is set */ +#define PCRE_RCH_CASELESS 0x00000080 /* caseless requested char */ +#define PCRE_STARTLINE 0x00000100 /* start after \n for multiline */ +#define PCRE_NOPARTIAL 0x00000200 /* can't use partial with this regex */ +#define PCRE_JCHANGED 0x00000400 /* j option used in regex */ +#define PCRE_HASCRORLF 0x00000800 /* explicit \r or \n in pattern */ +#define PCRE_HASTHEN 0x00001000 /* pattern contains (*THEN) */ +#define PCRE_MLSET 0x00002000 /* match limit set by regex */ +#define PCRE_RLSET 0x00004000 /* recursion limit set by regex */ +#define PCRE_MATCH_EMPTY 0x00008000 /* pattern can match empty string */ #if defined COMPILE_PCRE8 #define PCRE_MODE PCRE_MODE8 @@ -1162,9 +1113,10 @@ time, run time, or study time, respectively. */ #define PUBLIC_COMPILE_OPTIONS \ (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \ PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \ - PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \ + PCRE_NO_AUTO_CAPTURE|PCRE_NO_AUTO_POSSESS| \ + PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \ PCRE_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \ - PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE) + PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE|PCRE_NEVER_UTF) #define PUBLIC_EXEC_OPTIONS \ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \ @@ -1520,20 +1472,25 @@ a positive value. */ #define STRING_xdigit "xdigit" #define STRING_DEFINE "DEFINE" +#define STRING_WEIRD_STARTWORD "[:<:]]" +#define STRING_WEIRD_ENDWORD "[:>:]]" -#define STRING_CR_RIGHTPAR "CR)" -#define STRING_LF_RIGHTPAR "LF)" -#define STRING_CRLF_RIGHTPAR "CRLF)" -#define STRING_ANY_RIGHTPAR "ANY)" -#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)" -#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)" -#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)" -#define STRING_UTF8_RIGHTPAR "UTF8)" -#define STRING_UTF16_RIGHTPAR "UTF16)" -#define STRING_UTF32_RIGHTPAR "UTF32)" -#define STRING_UTF_RIGHTPAR "UTF)" -#define STRING_UCP_RIGHTPAR "UCP)" -#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" +#define STRING_CR_RIGHTPAR "CR)" +#define STRING_LF_RIGHTPAR "LF)" +#define STRING_CRLF_RIGHTPAR "CRLF)" +#define STRING_ANY_RIGHTPAR "ANY)" +#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)" +#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)" +#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)" +#define STRING_UTF8_RIGHTPAR "UTF8)" +#define STRING_UTF16_RIGHTPAR "UTF16)" +#define STRING_UTF32_RIGHTPAR "UTF32)" +#define STRING_UTF_RIGHTPAR "UTF)" +#define STRING_UCP_RIGHTPAR "UCP)" +#define STRING_NO_AUTO_POSSESS_RIGHTPAR "NO_AUTO_POSSESS)" +#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" +#define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH=" +#define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION=" #else /* SUPPORT_UTF */ @@ -1781,20 +1738,25 @@ only. */ #define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t #define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E +#define STRING_WEIRD_STARTWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET +#define STRING_WEIRD_ENDWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET -#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS -#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS -#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS -#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS -#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS -#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS -#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS -#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS -#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS -#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS -#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS -#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS -#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS +#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS +#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS +#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS +#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS +#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS +#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS +#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS +#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS +#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS +#define STRING_NO_AUTO_POSSESS_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_A STR_U STR_T STR_O STR_UNDERSCORE STR_P STR_O STR_S STR_S STR_E STR_S STR_S STR_RIGHT_PARENTHESIS +#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS +#define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN +#define STRING_LIMIT_RECURSION_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN #endif /* SUPPORT_UTF */ @@ -1835,12 +1797,25 @@ only. */ #define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */ #define PT_WORD 8 /* Word - L plus N plus underscore */ #define PT_CLIST 9 /* Pseudo-property: match character list */ +#define PT_UCNC 10 /* Universal Character nameable character */ +#define PT_TABSIZE 11 /* Size of square table for autopossessify tests */ + +/* The following special properties are used only in XCLASS items, when POSIX +classes are specified and PCRE_UCP is set - in other words, for Unicode +handling of these classes. They are not available via the \p or \P escapes like +those in the above list, and so they do not take part in the autopossessifying +table. */ + +#define PT_PXGRAPH 11 /* [:graph:] - characters that mark the paper */ +#define PT_PXPRINT 12 /* [:print:] - [:graph:] plus non-control spaces */ +#define PT_PXPUNCT 13 /* [:punct:] - punctuation characters */ /* Flag bits and data types for the extended class (OP_XCLASS) for classes that contain characters with values greater than 255. */ -#define XCL_NOT 0x01 /* Flag: this is a negative class */ -#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */ +#define XCL_NOT 0x01 /* Flag: this is a negative class */ +#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */ +#define XCL_HASPROP 0x04 /* Flag: property checks are present. */ #define XCL_END 0 /* Marks end of individual items */ #define XCL_SINGLE 1 /* Single item (one multibyte char) follows */ @@ -1849,9 +1824,9 @@ contain characters with values greater than 255. */ #define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ /* These are escaped items that aren't just an encoding of a particular data -value such as \n. They must have non-zero values, as check_escape() returns -0 for a data character. Also, they must appear in the same order as in the opcode -definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it +value such as \n. They must have non-zero values, as check_escape() returns 0 +for a data character. Also, they must appear in the same order as in the +opcode definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it corresponds to "." in DOTALL mode rather than an escape sequence. It is also used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves like \N. @@ -1874,12 +1849,31 @@ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_E, ESC_Q, ESC_g, ESC_k, ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu }; -/* Opcode table: Starting from 1 (i.e. after OP_END), the values up to -OP_EOD must correspond in order to the list of escapes immediately above. -*** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions -that follow must also be updated to match. There are also tables called -"coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */ +/********************** Opcode definitions ******************/ + +/****** NOTE NOTE NOTE ****** + +Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in +order to the list of escapes immediately above. Furthermore, values up to +OP_DOLLM must not be changed without adjusting the table called autoposstab in +pcre_compile.c + +Whenever this list is updated, the two macro definitions that follow must be +updated to match. The possessification table called "opcode_possessify" in +pcre_compile.c must also be updated, and also the tables called "coptable" +and "poptable" in pcre_dfa_exec.c. + +****** NOTE NOTE NOTE ******/ + + +/* The values between FIRST_AUTOTAB_OP and LAST_AUTOTAB_RIGHT_OP, inclusive, +are used in a table for deciding whether a repeated character type can be +auto-possessified. */ + +#define FIRST_AUTOTAB_OP OP_NOT_DIGIT +#define LAST_AUTOTAB_LEFT_OP OP_EXTUNI +#define LAST_AUTOTAB_RIGHT_OP OP_DOLLM enum { OP_END, /* 0 End of pattern */ @@ -1912,10 +1906,15 @@ enum { OP_EODN, /* 23 End of data or \n at end of data (\Z) */ OP_EOD, /* 24 End of data (\z) */ - OP_CIRC, /* 25 Start of line - not multiline */ - OP_CIRCM, /* 26 Start of line - multiline */ - OP_DOLL, /* 27 End of line - not multiline */ - OP_DOLLM, /* 28 End of line - multiline */ + /* Line end assertions */ + + OP_DOLL, /* 25 End of line - not multiline */ + OP_DOLLM, /* 26 End of line - multiline */ + OP_CIRC, /* 27 Start of line - not multiline */ + OP_CIRCM, /* 28 Start of line - multiline */ + + /* Single characters; caseful must precede the caseless ones */ + OP_CHAR, /* 29 Match one character, casefully */ OP_CHARI, /* 30 Match one character, caselessly */ OP_NOT, /* 31 Match one character, not the given one, casefully */ @@ -1924,7 +1923,7 @@ enum { /* The following sets of 13 opcodes must always be kept in step because the offset from the first one is used to generate the others. */ - /**** Single characters, caseful, must precede the caseless ones ****/ + /* Repeated characters; caseful must precede the caseless ones */ OP_STAR, /* 33 The maximizing and minimizing versions of */ OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */ @@ -1942,7 +1941,7 @@ enum { OP_POSQUERY, /* 44 Posesssified query, caseful */ OP_POSUPTO, /* 45 Possessified upto, caseful */ - /**** Single characters, caseless, must follow the caseful ones */ + /* Repeated characters; caseless must follow the caseful ones */ OP_STARI, /* 46 */ OP_MINSTARI, /* 47 */ @@ -1960,8 +1959,8 @@ enum { OP_POSQUERYI, /* 57 Posesssified query, caseless */ OP_POSUPTOI, /* 58 Possessified upto, caseless */ - /**** The negated ones must follow the non-negated ones, and match them ****/ - /**** Negated single character, caseful; must precede the caseless ones ****/ + /* The negated ones must follow the non-negated ones, and match them */ + /* Negated repeated character, caseful; must precede the caseless ones */ OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */ OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */ @@ -1979,7 +1978,7 @@ enum { OP_NOTPOSQUERY, /* 70 */ OP_NOTPOSUPTO, /* 71 */ - /**** Negated single character, caseless; must follow the caseful ones ****/ + /* Negated repeated character, caseless; must follow the caseful ones */ OP_NOTSTARI, /* 72 */ OP_NOTMINSTARI, /* 73 */ @@ -1997,7 +1996,7 @@ enum { OP_NOTPOSQUERYI, /* 83 */ OP_NOTPOSUPTOI, /* 84 */ - /**** Character types ****/ + /* Character types */ OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */ OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */ @@ -2028,89 +2027,96 @@ enum { OP_CRRANGE, /* 104 These are different to the three sets above. */ OP_CRMINRANGE, /* 105 */ + OP_CRPOSSTAR, /* 106 Possessified versions */ + OP_CRPOSPLUS, /* 107 */ + OP_CRPOSQUERY, /* 108 */ + OP_CRPOSRANGE, /* 109 */ + /* End of quantifier opcodes */ - OP_CLASS, /* 106 Match a character class, chars < 256 only */ - OP_NCLASS, /* 107 Same, but the bitmap was created from a negative + OP_CLASS, /* 110 Match a character class, chars < 256 only */ + OP_NCLASS, /* 111 Same, but the bitmap was created from a negative class - the difference is relevant only when a character > 255 is encountered. */ - OP_XCLASS, /* 108 Extended class for handling > 255 chars within the + OP_XCLASS, /* 112 Extended class for handling > 255 chars within the class. This does both positive and negative. */ - OP_REF, /* 109 Match a back reference, casefully */ - OP_REFI, /* 110 Match a back reference, caselessly */ - OP_RECURSE, /* 111 Match a numbered subpattern (possibly recursive) */ - OP_CALLOUT, /* 112 Call out to external function if provided */ + OP_REF, /* 113 Match a back reference, casefully */ + OP_REFI, /* 114 Match a back reference, caselessly */ + OP_DNREF, /* 115 Match a duplicate name backref, casefully */ + OP_DNREFI, /* 116 Match a duplicate name backref, caselessly */ + OP_RECURSE, /* 117 Match a numbered subpattern (possibly recursive) */ + OP_CALLOUT, /* 118 Call out to external function if provided */ - OP_ALT, /* 113 Start of alternation */ - OP_KET, /* 114 End of group that doesn't have an unbounded repeat */ - OP_KETRMAX, /* 115 These two must remain together and in this */ - OP_KETRMIN, /* 116 order. They are for groups the repeat for ever. */ - OP_KETRPOS, /* 117 Possessive unlimited repeat. */ + OP_ALT, /* 119 Start of alternation */ + OP_KET, /* 120 End of group that doesn't have an unbounded repeat */ + OP_KETRMAX, /* 121 These two must remain together and in this */ + OP_KETRMIN, /* 122 order. They are for groups the repeat for ever. */ + OP_KETRPOS, /* 123 Possessive unlimited repeat. */ /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four asserts must remain in order. */ - OP_REVERSE, /* 118 Move pointer back - used in lookbehind assertions */ - OP_ASSERT, /* 119 Positive lookahead */ - OP_ASSERT_NOT, /* 120 Negative lookahead */ - OP_ASSERTBACK, /* 121 Positive lookbehind */ - OP_ASSERTBACK_NOT, /* 122 Negative lookbehind */ + OP_REVERSE, /* 124 Move pointer back - used in lookbehind assertions */ + OP_ASSERT, /* 125 Positive lookahead */ + OP_ASSERT_NOT, /* 126 Negative lookahead */ + OP_ASSERTBACK, /* 127 Positive lookbehind */ + OP_ASSERTBACK_NOT, /* 128 Negative lookbehind */ /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately after the assertions, with ONCE first, as there's a test for >= ONCE for a subpattern that isn't an assertion. The POS versions must immediately follow the non-POS versions in each case. */ - OP_ONCE, /* 123 Atomic group, contains captures */ - OP_ONCE_NC, /* 124 Atomic group containing no captures */ - OP_BRA, /* 125 Start of non-capturing bracket */ - OP_BRAPOS, /* 126 Ditto, with unlimited, possessive repeat */ - OP_CBRA, /* 127 Start of capturing bracket */ - OP_CBRAPOS, /* 128 Ditto, with unlimited, possessive repeat */ - OP_COND, /* 129 Conditional group */ + OP_ONCE, /* 129 Atomic group, contains captures */ + OP_ONCE_NC, /* 130 Atomic group containing no captures */ + OP_BRA, /* 131 Start of non-capturing bracket */ + OP_BRAPOS, /* 132 Ditto, with unlimited, possessive repeat */ + OP_CBRA, /* 133 Start of capturing bracket */ + OP_CBRAPOS, /* 134 Ditto, with unlimited, possessive repeat */ + OP_COND, /* 135 Conditional group */ /* These five must follow the previous five, in the same order. There's a check for >= SBRA to distinguish the two sets. */ - OP_SBRA, /* 130 Start of non-capturing bracket, check empty */ - OP_SBRAPOS, /* 131 Ditto, with unlimited, possessive repeat */ - OP_SCBRA, /* 132 Start of capturing bracket, check empty */ - OP_SCBRAPOS, /* 133 Ditto, with unlimited, possessive repeat */ - OP_SCOND, /* 134 Conditional group, check empty */ + OP_SBRA, /* 136 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 137 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 138 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 139 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 140 Conditional group, check empty */ /* The next two pairs must (respectively) be kept together. */ - OP_CREF, /* 135 Used to hold a capture number as condition */ - OP_NCREF, /* 136 Same, but generated by a name reference*/ - OP_RREF, /* 137 Used to hold a recursion number as condition */ - OP_NRREF, /* 138 Same, but generated by a name reference*/ - OP_DEF, /* 139 The DEFINE condition */ + OP_CREF, /* 141 Used to hold a capture number as condition */ + OP_DNCREF, /* 142 Used to point to duplicate names as a condition */ + OP_RREF, /* 143 Used to hold a recursion number as condition */ + OP_DNRREF, /* 144 Used to point to duplicate names as a condition */ + OP_DEF, /* 145 The DEFINE condition */ - OP_BRAZERO, /* 140 These two must remain together and in this */ - OP_BRAMINZERO, /* 141 order. */ - OP_BRAPOSZERO, /* 142 */ + OP_BRAZERO, /* 146 These two must remain together and in this */ + OP_BRAMINZERO, /* 147 order. */ + OP_BRAPOSZERO, /* 148 */ /* These are backtracking control verbs */ - OP_MARK, /* 143 always has an argument */ - OP_PRUNE, /* 144 */ - OP_PRUNE_ARG, /* 145 same, but with argument */ - OP_SKIP, /* 146 */ - OP_SKIP_ARG, /* 147 same, but with argument */ - OP_THEN, /* 148 */ - OP_THEN_ARG, /* 149 same, but with argument */ - OP_COMMIT, /* 150 */ + OP_MARK, /* 149 always has an argument */ + OP_PRUNE, /* 150 */ + OP_PRUNE_ARG, /* 151 same, but with argument */ + OP_SKIP, /* 152 */ + OP_SKIP_ARG, /* 153 same, but with argument */ + OP_THEN, /* 154 */ + OP_THEN_ARG, /* 155 same, but with argument */ + OP_COMMIT, /* 156 */ /* These are forced failure and success verbs */ - OP_FAIL, /* 151 */ - OP_ACCEPT, /* 152 */ - OP_ASSERT_ACCEPT, /* 153 Used inside assertions */ - OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */ + OP_FAIL, /* 157 */ + OP_ACCEPT, /* 158 */ + OP_ASSERT_ACCEPT, /* 159 Used inside assertions */ + OP_CLOSE, /* 160 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ - OP_SKIPZERO, /* 155 */ + OP_SKIPZERO, /* 161 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been @@ -2121,7 +2127,8 @@ enum { /* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro definitions that follow must also be updated to match. There are also tables -called "coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */ +called "opcode_possessify" in pcre_compile.c and "coptable" and "poptable" in +pcre_dfa_exec.c that must be updated. */ /* This macro defines textual names for all the opcodes. These are used only @@ -2134,7 +2141,7 @@ some cases doesn't actually use these names at all). */ "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \ "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \ "extuni", "\\Z", "\\z", \ - "^", "^", "$", "$", "char", "chari", "not", "noti", \ + "$", "$", "^", "^", "char", "chari", "not", "noti", \ "*", "*?", "+", "+?", "?", "??", \ "{", "{", "{", \ "*+","++", "?+", "{", \ @@ -2150,7 +2157,8 @@ some cases doesn't actually use these names at all). */ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", \ - "class", "nclass", "xclass", "Ref", "Refi", \ + "*+","++", "?+", "{", \ + "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \ "Recurse", "Callout", \ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \ @@ -2159,7 +2167,7 @@ some cases doesn't actually use these names at all). */ "Cond", \ "SBra", "SBraPos", "SCBra", "SCBraPos", \ "SCond", \ - "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \ + "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec", "Cond def", \ "Brazero", "Braminzero", "Braposzero", \ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ "*THEN", "*THEN", "*COMMIT", "*FAIL", \ @@ -2184,7 +2192,7 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 3, 3, /* \P, \p */ \ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \ 1, /* \X */ \ - 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \ + 1, 1, 1, 1, 1, 1, /* \Z, \z, $, $M ^, ^M */ \ 2, /* Char - the minimum length */ \ 2, /* Chari - the minimum length */ \ 2, /* not */ \ @@ -2215,11 +2223,14 @@ in UTF-8 mode. The code that uses this table must know about such things. */ /* Character class & ref repeats */ \ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \ 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \ + 1, 1, 1, 1+2*IMM2_SIZE, /* Possessive *+, ++, ?+, CRPOSRANGE */ \ 1+(32/sizeof(pcre_uchar)), /* CLASS */ \ 1+(32/sizeof(pcre_uchar)), /* NCLASS */ \ 0, /* XCLASS - variable length */ \ 1+IMM2_SIZE, /* REF */ \ 1+IMM2_SIZE, /* REFI */ \ + 1+2*IMM2_SIZE, /* DNREF */ \ + 1+2*IMM2_SIZE, /* DNREFI */ \ 1+LINK_SIZE, /* RECURSE */ \ 2+2*LINK_SIZE, /* CALLOUT */ \ 1+LINK_SIZE, /* Alt */ \ @@ -2244,8 +2255,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \ 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \ 1+LINK_SIZE, /* SCOND */ \ - 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \ - 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \ + 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* CREF, DNCREF */ \ + 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* RREF, DNRREF */ \ 1, /* DEF */ \ 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \ 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \ @@ -2254,8 +2265,7 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \ 1+IMM2_SIZE, 1 /* CLOSE, SKIPZERO */ -/* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion" -condition. */ +/* A magic value for OP_RREF to indicate the "any recursion" condition. */ #define RREF_ANY 0xffff @@ -2270,9 +2280,11 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, - ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERRCOUNT }; + ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, + ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, 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 }; @@ -2280,48 +2292,49 @@ enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE, code vector run on as long as necessary after the end. We store an explicit offset to the name table so that if a regex is compiled on one host, saved, and then run on another where the size of pointers is different, all might still -be well. For the case of compiled-on-4 and run-on-8, we include an extra -pointer that is always NULL. For future-proofing, a few dummy fields were -originally included - even though you can never get this planning right - but -there is only one left now. +be well. -NOTE NOTE NOTE: -Because people can now save and re-use compiled patterns, any additions to this -structure should be made at the end, and something earlier (e.g. a new -flag in the options or one of the dummy fields) should indicate that the new -fields are present. Currently PCRE always sets the dummy fields to zero. -NOTE NOTE NOTE +The size of the structure must be a multiple of 8 bytes. For the case of +compiled-on-4 and run-on-8, we include an extra pointer that is always NULL so +that there are an even number of pointers which therefore are a multiple of 8 +bytes. + +It is necessary to fork the struct for the 32 bit library, since it needs to +use pcre_uint32 for first_char and req_char. We can't put an ifdef inside the +typedef because pcretest needs access to the struct of the 8-, 16- and 32-bit +variants. + +*** WARNING *** +When new fields are added to these structures, remember to adjust the code in +pcre_byte_order.c that is concerned with swapping the byte order of the fields +when a compiled regex is reloaded on a host with different endianness. +*** WARNING *** +There is also similar byte-flipping code in pcretest.c, which is used for +testing the byte-flipping features. It must also be kept in step. +*** WARNING *** */ -#if defined COMPILE_PCRE8 -#define REAL_PCRE real_pcre -#elif defined COMPILE_PCRE16 -#define REAL_PCRE real_pcre16 -#elif defined COMPILE_PCRE32 -#define REAL_PCRE real_pcre32 -#endif - -/* It is necessary to fork the struct for 32 bit, since it needs to use - * pcre_uchar for first_char and req_char. Can't put an ifdef inside the - * typedef since pcretest needs access to the struct of the 8-, 16- - * and 32-bit variants. */ - typedef struct real_pcre8_or_16 { pcre_uint32 magic_number; pcre_uint32 size; /* Total that was malloced */ pcre_uint32 options; /* Public options */ - pcre_uint16 flags; /* Private flags */ + pcre_uint32 flags; /* Private flags */ + pcre_uint32 limit_match; /* Limit set from regex */ + pcre_uint32 limit_recursion; /* Limit set from regex */ + pcre_uint16 first_char; /* Starting character */ + pcre_uint16 req_char; /* This character must be seen */ pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */ pcre_uint16 top_bracket; /* Highest numbered group */ pcre_uint16 top_backref; /* Highest numbered back reference */ - pcre_uint16 first_char; /* Starting character */ - pcre_uint16 req_char; /* This character must be seen */ pcre_uint16 name_table_offset; /* Offset to name table that follows */ pcre_uint16 name_entry_size; /* Size of any name items */ pcre_uint16 name_count; /* Number of name items */ pcre_uint16 ref_count; /* Reference count */ + pcre_uint16 dummy1; /* To ensure size is a multiple of 8 */ + pcre_uint16 dummy2; /* To ensure size is a multiple of 8 */ + pcre_uint16 dummy3; /* To ensure size is a multiple of 8 */ const pcre_uint8 *tables; /* Pointer to tables or NULL for std */ - const pcre_uint8 *nullpad; /* NULL padding */ + void *nullpad; /* NULL padding */ } real_pcre8_or_16; typedef struct real_pcre8_or_16 real_pcre; @@ -2331,22 +2344,31 @@ typedef struct real_pcre32 { pcre_uint32 magic_number; pcre_uint32 size; /* Total that was malloced */ pcre_uint32 options; /* Public options */ - pcre_uint16 flags; /* Private flags */ + pcre_uint32 flags; /* Private flags */ + pcre_uint32 limit_match; /* Limit set from regex */ + pcre_uint32 limit_recursion; /* Limit set from regex */ + pcre_uint32 first_char; /* Starting character */ + pcre_uint32 req_char; /* This character must be seen */ pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */ pcre_uint16 top_bracket; /* Highest numbered group */ pcre_uint16 top_backref; /* Highest numbered back reference */ - pcre_uint32 first_char; /* Starting character */ - pcre_uint32 req_char; /* This character must be seen */ pcre_uint16 name_table_offset; /* Offset to name table that follows */ pcre_uint16 name_entry_size; /* Size of any name items */ pcre_uint16 name_count; /* Number of name items */ pcre_uint16 ref_count; /* Reference count */ - pcre_uint16 dummy1; /* for later expansion */ - pcre_uint16 dummy2; /* for later expansion */ + pcre_uint16 dummy; /* To ensure size is a multiple of 8 */ const pcre_uint8 *tables; /* Pointer to tables or NULL for std */ - void *nullpad; /* for later expansion */ + void *nullpad; /* NULL padding */ } real_pcre32; +#if defined COMPILE_PCRE8 +#define REAL_PCRE real_pcre +#elif defined COMPILE_PCRE16 +#define REAL_PCRE real_pcre16 +#elif defined COMPILE_PCRE32 +#define REAL_PCRE real_pcre32 +#endif + /* Assert that the size of REAL_PCRE is divisible by 8 */ typedef int __assert_real_pcre_size_divisible_8[(sizeof(REAL_PCRE) % 8) == 0 ? 1 : -1]; @@ -2380,6 +2402,15 @@ typedef struct open_capitem { pcre_uint16 flag; /* Set TRUE if recursive back ref */ } open_capitem; +/* Structure for building a list of named groups during the first pass of +compiling. */ + +typedef struct named_group { + const pcre_uchar *name; /* Points to the name in the pattern */ + int length; /* Length of the name */ + pcre_uint32 number; /* Group number */ +} named_group; + /* Structure for passing "static" information around between the functions doing the compiling, so that they are thread-safe. */ @@ -2392,24 +2423,29 @@ typedef struct compile_data { const pcre_uchar *start_code; /* The start of the compiled code */ const pcre_uchar *start_pattern; /* The start of the pattern */ const pcre_uchar *end_pattern; /* The end of the pattern */ - open_capitem *open_caps; /* Chain of open capture items */ pcre_uchar *hwm; /* High watermark of workspace */ + open_capitem *open_caps; /* Chain of open capture items */ + named_group *named_groups; /* Points to vector in pre-compile */ pcre_uchar *name_table; /* The name/number table */ int names_found; /* Number of entries so far */ int name_entry_size; /* Size of each entry */ + int named_group_list_size; /* Number of entries in the list */ int workspace_size; /* Size of workspace */ - unsigned int bracount; /* Count of capturing parens as we compile */ + unsigned int bracount; /* Count of capturing parens as we compile */ int final_bracount; /* Saved value after first pass */ int max_lookbehind; /* Maximum lookbehind (characters) */ int top_backref; /* Maximum back reference */ unsigned int backref_map; /* Bitmap of low back refs */ + unsigned int namedrefcount; /* Number of backreferences by name */ + int parens_depth; /* Depth of nested parentheses */ int assert_depth; /* Depth of nested assertions */ - int external_options; /* External (initial) options */ - int external_flags; /* External flag bits to be set */ + pcre_uint32 external_options; /* External (initial) options */ + pcre_uint32 external_flags; /* External flag bits to be set */ int req_varyopt; /* "After variable item" flag for reqbyte */ BOOL had_accept; /* (*ACCEPT) encountered */ BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ BOOL check_lookbehind; /* Lookbehinds need later checking */ + BOOL dupnames; /* Duplicate names exist */ int nltype; /* Newline type */ int nllen; /* Newline string length */ pcre_uchar nl[4]; /* Newline string when fixed length */ @@ -2431,6 +2467,7 @@ typedef struct recursion_info { unsigned int group_num; /* Number of group that was called */ int *offset_save; /* Pointer to start of saved offsets */ int saved_max; /* Number of saved offsets */ + int saved_capture_last; /* Last capture number */ PCRE_PUCHAR subject_position; /* Position at start of recursion */ } recursion_info; @@ -2467,12 +2504,13 @@ typedef struct match_data { int nllen; /* Newline string length */ int name_count; /* Number of names in name table */ int name_entry_size; /* Size of entry in names table */ + unsigned int skip_arg_count; /* For counting SKIP_ARGs */ + unsigned int ignore_skip_arg; /* For re-run when SKIP arg name not found */ pcre_uchar *name_table; /* Table of names */ pcre_uchar nl[4]; /* Newline string when fixed */ const pcre_uint8 *lcc; /* Points to lower casing table */ const pcre_uint8 *fcc; /* Points to case-flipping table */ const pcre_uint8 *ctypes; /* Points to table of type maps */ - BOOL offset_overflow; /* Set if too many extractions */ BOOL notbol; /* NOTBOL flag */ BOOL noteol; /* NOTEOL flag */ BOOL utf; /* UTF-8 / UTF-16 flag */ @@ -2484,7 +2522,6 @@ typedef struct match_data { BOOL hitend; /* Hit the end of the subject at some point */ BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */ BOOL hasthen; /* Pattern contains (*THEN) */ - BOOL ignore_skip_arg; /* For re-run when SKIP name not found */ const pcre_uchar *start_code; /* For use when recursing */ PCRE_PUCHAR start_subject; /* Start of the subject string */ PCRE_PUCHAR end_subject; /* End of the subject string */ @@ -2493,7 +2530,7 @@ typedef struct match_data { PCRE_PUCHAR start_used_ptr; /* Earliest consulted character */ int partial; /* PARTIAL options */ int end_offset_top; /* Highwater mark at end of match */ - int capture_last; /* Most recent capture number */ + pcre_int32 capture_last; /* Most recent capture number + overflow flag */ int start_offset; /* The start offset value */ int match_function_type; /* Set for certain special calls of MATCH() */ eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */ diff --git a/tools/pcre/pcre_jit_compile.c b/tools/pcre/pcre_jit_compile.c index cc9f0976..e67071ef 100644 --- a/tools/pcre/pcre_jit_compile.c +++ b/tools/pcre/pcre_jit_compile.c @@ -6,10 +6,10 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2013 University of Cambridge The machine code generator part (this module) was written by Zoltan Herczeg - Copyright (c) 2010-2012 + Copyright (c) 2010-2013 ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -65,6 +65,15 @@ system files. */ #error Unsupported architecture #endif +/* Defines for debugging purposes. */ + +/* 1 - Use unoptimized capturing brackets. + 2 - Enable capture_last_ptr (includes option 1). */ +/* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */ + +/* 1 - Always have a control head. */ +/* #define DEBUG_FORCE_CONTROL_HEAD 1 */ + /* Allocate memory for the regex stack on the real machine stack. Fast, but limited size. */ #define MACHINE_STACK_SIZE 32768 @@ -157,9 +166,11 @@ typedef struct jit_arguments { int *offsets; pcre_uchar *uchar_ptr; pcre_uchar *mark_ptr; + void *callout_data; /* Everything else after. */ - int offsetcount; - int calllimit; + pcre_uint32 limit_match; + int real_offset_count; + int offset_count; pcre_uint8 notbol; pcre_uint8 noteol; pcre_uint8 notempty; @@ -168,10 +179,12 @@ typedef struct jit_arguments { typedef struct executable_functions { void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; + sljit_uw *read_only_data[JIT_NUMBER_OF_COMPILE_MODES]; + sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; PUBL(jit_callback) callback; void *userdata; pcre_uint32 top_bracket; - sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; + pcre_uint32 limit_match; } executable_functions; typedef struct jump_list { @@ -179,21 +192,33 @@ typedef struct jump_list { 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 *quit; struct stub_list *next; } stub_list; +typedef struct label_addr_list { + struct sljit_label *label; + sljit_uw *addr; + struct label_addr_list *next; +} label_addr_list; + +enum frame_types { + no_frame = -1, + no_stack = -2 +}; + +enum control_types { + type_mark = 0, + type_then_trap = 1 +}; + 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_matchingpath, and contains -the aguments for compile_backtrackingpath. Must be the first member +the arguments for compile_backtrackingpath. Must be the first member of its descendants. */ typedef struct backtrack_common { /* Concatenation stack. */ @@ -209,7 +234,7 @@ typedef struct backtrack_common { typedef struct assert_backtrack { backtrack_common common; jump_list *condfailed; - /* Less than 0 (-1) if a frame is not needed. */ + /* Less than 0 if a frame is not needed. */ int framesize; /* Points to our private memory word on the stack. */ int private_data_ptr; @@ -230,7 +255,7 @@ typedef struct bracket_backtrack { /* Both for OP_COND, OP_SCOND. */ jump_list *condfailed; assert_backtrack *assert; - /* For OP_ONCE. -1 if not needed. */ + /* For OP_ONCE. Less than 0 if not needed. */ int framesize; } u; /* Points to our private memory word on the stack. */ @@ -265,31 +290,58 @@ typedef struct recurse_entry { /* Collects the calls until the function is not created. */ jump_list *calls; /* Points to the starting opcode. */ - int start; + sljit_sw start; } recurse_entry; typedef struct recurse_backtrack { backtrack_common common; + BOOL inlined_pattern; } recurse_backtrack; -#define MAX_RANGE_SIZE 6 +#define OP_THEN_TRAP OP_TABLE_LENGTH + +typedef struct then_trap_backtrack { + backtrack_common common; + /* If then_trap is not NULL, this structure contains the real + then_trap for the backtracking path. */ + struct then_trap_backtrack *then_trap; + /* Points to the starting opcode. */ + sljit_sw start; + /* Exit point for the then opcodes of this alternative. */ + jump_list *quit; + /* Frame size of the current alternative. */ + int framesize; +} then_trap_backtrack; + +#define MAX_RANGE_SIZE 4 typedef struct compiler_common { + /* The sljit ceneric compiler. */ struct sljit_compiler *compiler; + /* First byte code. */ pcre_uchar *start; - /* Maps private data offset to each opcode. */ - int *private_data_ptrs; + sljit_si *private_data_ptrs; + /* This read-only data is available during runtime. */ + sljit_uw *read_only_data; + /* The total size of the read-only data. */ + sljit_uw read_only_data_size; + /* The next free entry of the read_only_data. */ + sljit_uw *read_only_data_ptr; /* Tells whether the capturing bracket is optimized. */ pcre_uint8 *optimized_cbracket; + /* Tells whether the starting offset is a target of then. */ + pcre_uint8 *then_offsets; + /* Current position where a THEN must jump. */ + then_trap_backtrack *then_trap; /* Starting offset of private data for capturing brackets. */ - int cbraptr; - /* OVector starting point. Must be divisible by 2. */ + int cbra_ptr; + /* Output vector 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; + int recursive_head_ptr; /* First inspected character for partial matching. */ int start_used_ptr; /* Starting pointer for partial soft matches. */ @@ -298,36 +350,63 @@ typedef struct compiler_common { int first_line_end; /* Points to the marked string. */ int mark_ptr; + /* Recursive control verb management chain. */ + int control_head_ptr; + /* Points to the last matched capture block index. */ + int capture_last_ptr; + /* Points to the starting position of the current match. */ + int start_ptr; /* Flipped and lower case tables. */ const pcre_uint8 *fcc; sljit_sw lcc; /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */ int mode; + /* TRUE, when minlength is greater than 0. */ + BOOL might_be_empty; + /* \K is found in the pattern. */ + BOOL has_set_som; + /* (*SKIP:arg) is found in the pattern. */ + BOOL has_skip_arg; + /* (*THEN) is found in the pattern. */ + BOOL has_then; + /* Needs to know the start position anytime. */ + BOOL needs_start_ptr; + /* Currently in recurse or negative assert. */ + BOOL local_exit; + /* Currently in a positive assert. */ + BOOL positive_assert; /* Newline control. */ int nltype; + pcre_uint32 nlmax; + pcre_uint32 nlmin; int newline; int bsr_nltype; + pcre_uint32 bsr_nlmax; + pcre_uint32 bsr_nlmin; /* Dollar endonly. */ int endonly; - BOOL has_set_som; /* Tables. */ sljit_sw ctypes; - int digits[2 + MAX_RANGE_SIZE]; /* Named capturing brackets. */ - sljit_uw name_table; + pcre_uchar *name_table; sljit_sw name_count; sljit_sw name_entry_size; /* Labels and jump lists. */ struct sljit_label *partialmatchlabel; - struct sljit_label *quitlabel; - struct sljit_label *acceptlabel; + struct sljit_label *quit_label; + struct sljit_label *forced_quit_label; + struct sljit_label *accept_label; + struct sljit_label *ff_newline_shortcut; stub_list *stubs; + label_addr_list *label_addrs; recurse_entry *entries; recurse_entry *currententry; jump_list *partialmatch; jump_list *quit; + jump_list *positive_assert_quit; + jump_list *forced_quit; jump_list *accept; jump_list *calllimit; jump_list *stackalloc; @@ -338,16 +417,16 @@ typedef struct compiler_common { jump_list *vspace; jump_list *casefulcmp; jump_list *caselesscmp; + jump_list *reset_match; BOOL jscript_compat; #ifdef SUPPORT_UTF BOOL utf; #ifdef SUPPORT_UCP BOOL use_ucp; #endif -#ifndef COMPILE_PCRE32 - jump_list *utfreadchar; -#endif #ifdef COMPILE_PCRE8 + jump_list *utfreadchar; + jump_list *utfreadchar16; jump_list *utfreadtype8; #endif #endif /* SUPPORT_UTF */ @@ -390,12 +469,6 @@ typedef struct compare_context { #endif } compare_context; -enum { - frame_end = 0, - frame_setstrbegin = -1, - frame_setmark = -2 -}; - /* Undefine sljit macros. */ #undef CMP @@ -410,7 +483,7 @@ enum { #define STACK_TOP SLJIT_SCRATCH_REG2 #define STACK_LIMIT SLJIT_SAVED_REG3 #define ARGUMENTS SLJIT_SAVED_EREG1 -#define CALL_COUNT SLJIT_SAVED_EREG2 +#define COUNT_MATCH SLJIT_SAVED_EREG2 #define RETURN_ADDR SLJIT_TEMPORARY_EREG1 /* Local space layout. */ @@ -421,14 +494,14 @@ enum { #define POSSESSIVE0 (2 * sizeof(sljit_sw)) #define POSSESSIVE1 (3 * sizeof(sljit_sw)) /* Max limit of recursions. */ -#define CALL_LIMIT (4 * sizeof(sljit_sw)) +#define LIMIT_MATCH (4 * sizeof(sljit_sw)) /* 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_sw)) -#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_sw)) +#define OVECTOR(i) (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw)) +#define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw)) #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start]) #if defined COMPILE_PCRE8 @@ -459,6 +532,8 @@ the start pointers when the end of the capturing group has not yet reached. */ sljit_set_label(sljit_emit_jump(compiler, (type)), (label)) #define JUMPHERE(jump) \ sljit_set_label((jump), sljit_emit_label(compiler)) +#define SET_LABEL(jump, label) \ + sljit_set_label((jump), (label)) #define CMP(type, src1, src1w, src2, src2w) \ sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)) #define CMPTO(type, src1, src1w, src2, src2w, label) \ @@ -468,6 +543,8 @@ the start pointers when the end of the capturing group has not yet reached. */ #define GET_LOCAL_BASE(dst, dstw, offset) \ sljit_get_local_base(compiler, (dst), (dstw), (offset)) +#define READ_CHAR_MAX 0x7fffffff + static pcre_uchar* bracketend(pcre_uchar* cc) { SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); @@ -477,13 +554,32 @@ cc += 1 + LINK_SIZE; return cc; } +static int no_alternatives(pcre_uchar* cc) +{ +int count = 0; +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +do + { + cc += GET(cc, 1); + count++; + } +while (*cc == OP_ALT); +SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); +return count; +} + +static int ones_in_half_byte[16] = { + /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3, + /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4 +}; + /* Functions whose might need modification for all new supported opcodes: next_opcode - get_private_data_length + check_opcode_types set_private_data_ptrs get_framesize init_frame - get_private_data_length_for_copy + get_private_data_copy_length copy_private_data compile_matchingpath compile_backtrackingpath @@ -507,6 +603,8 @@ switch(*cc) case OP_WORDCHAR: case OP_ANY: case OP_ALLANY: + case OP_NOTPROP: + case OP_PROP: case OP_ANYNL: case OP_NOT_HSPACE: case OP_HSPACE: @@ -519,37 +617,66 @@ switch(*cc) 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_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: + case OP_CRPOSRANGE: + case OP_CLASS: + case OP_NCLASS: + case OP_REF: + case OP_REFI: + case OP_DNREF: + case OP_DNREFI: + case OP_RECURSE: + case OP_CALLOUT: + case OP_ALT: + case OP_KET: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + case OP_REVERSE: + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_BRAPOS: + case OP_CBRA: + case OP_CBRAPOS: + case OP_COND: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + case OP_SCOND: + case OP_CREF: + case OP_DNCREF: + case OP_RREF: + case OP_DNRREF: case OP_DEF: case OP_BRAZERO: case OP_BRAMINZERO: case OP_BRAPOSZERO: + case OP_PRUNE: + case OP_SKIP: + case OP_THEN: case OP_COMMIT: case OP_FAIL: case OP_ACCEPT: case OP_ASSERT_ACCEPT: + case OP_CLOSE: case OP_SKIPZERO: - return cc + 1; - - case OP_ANYBYTE: -#ifdef SUPPORT_UTF - if (common->utf) return NULL; -#endif - return cc + 1; + return cc + PRIV(OP_lengths)[*cc]; case OP_CHAR: case OP_CHARI: @@ -561,130 +688,337 @@ switch(*cc) 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_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_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: case OP_NOTPOSUPTOI: - cc += 2 + IMM2_SIZE; + cc += PRIV(OP_lengths)[*cc]; #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; - + /* Special cases. */ + 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_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; + return cc + PRIV(OP_lengths)[*cc] - 1; - 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); + case OP_ANYBYTE: +#ifdef SUPPORT_UTF + if (common->utf) return NULL; +#endif + return cc + 1; #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: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: return cc + 1 + 2 + cc[1]; default: + /* All opcodes are supported now! */ + SLJIT_ASSERT_STOP(); return NULL; } } +static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) +{ +int count; +pcre_uchar *slot; + +/* 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; + common->might_be_empty = TRUE; + cc += 1; + break; + + case OP_REF: + case OP_REFI: + common->optimized_cbracket[GET2(cc, 1)] = 0; + cc += 1 + IMM2_SIZE; + break; + + case OP_BRA: + case OP_CBRA: + case OP_SBRA: + case OP_SCBRA: + count = no_alternatives(cc); + if (count > 4) + common->read_only_data_size += count * sizeof(sljit_uw); + cc += 1 + LINK_SIZE + (*cc == OP_CBRA || *cc == OP_SCBRA ? IMM2_SIZE : 0); + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_COND: + case OP_SCOND: + /* Only AUTO_CALLOUT can insert this opcode. We do + not intend to support this case. */ + if (cc[1 + LINK_SIZE] == OP_CALLOUT) + return FALSE; + cc += 1 + LINK_SIZE; + break; + + case OP_CREF: + common->optimized_cbracket[GET2(cc, 1)] = 0; + cc += 1 + IMM2_SIZE; + break; + + case OP_DNREF: + case OP_DNREFI: + case OP_DNCREF: + count = GET2(cc, 1 + IMM2_SIZE); + slot = common->name_table + GET2(cc, 1) * common->name_entry_size; + while (count-- > 0) + { + common->optimized_cbracket[GET2(slot, 0)] = 0; + slot += common->name_entry_size; + } + cc += 1 + 2 * IMM2_SIZE; + break; + + case OP_RECURSE: + /* Set its value only once. */ + if (common->recursive_head_ptr == 0) + { + common->recursive_head_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + cc += 1 + LINK_SIZE; + break; + + case OP_CALLOUT: + if (common->capture_last_ptr == 0) + { + common->capture_last_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + cc += 2 + 2 * LINK_SIZE; + break; + + case OP_THEN_ARG: + common->has_then = TRUE; + common->control_head_ptr = 1; + /* Fall through. */ + + case OP_PRUNE_ARG: + common->needs_start_ptr = TRUE; + /* Fall through. */ + + case OP_MARK: + if (common->mark_ptr == 0) + { + common->mark_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + cc += 1 + 2 + cc[1]; + break; + + case OP_THEN: + common->has_then = TRUE; + common->control_head_ptr = 1; + /* Fall through. */ + + case OP_PRUNE: + case OP_SKIP: + common->needs_start_ptr = TRUE; + cc += 1; + break; + + case OP_SKIP_ARG: + common->control_head_ptr = 1; + common->has_skip_arg = TRUE; + cc += 1 + 2 + cc[1]; + break; + + default: + cc = next_opcode(common, cc); + if (cc == NULL) + return FALSE; + break; + } + } +return TRUE; +} + +static int get_class_iterator_size(pcre_uchar *cc) +{ +switch(*cc) + { + case OP_CRSTAR: + case OP_CRPLUS: + return 2; + + case OP_CRMINSTAR: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + return 1; + + case OP_CRRANGE: + case OP_CRMINRANGE: + if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE)) + return 0; + return 2; + + default: + return 0; + } +} + +static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin) +{ +pcre_uchar *end = bracketend(begin); +pcre_uchar *next; +pcre_uchar *next_end; +pcre_uchar *max_end; +pcre_uchar type; +sljit_sw length = end - begin; +int min, max, i; + +/* Detect fixed iterations first. */ +if (end[-(1 + LINK_SIZE)] != OP_KET) + return FALSE; + +/* Already detected repeat. */ +if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0) + return TRUE; + +next = end; +min = 1; +while (1) + { + if (*next != *begin) + break; + next_end = bracketend(next); + if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0) + break; + next = next_end; + min++; + } + +if (min == 2) + return FALSE; + +max = 0; +max_end = next; +if (*next == OP_BRAZERO || *next == OP_BRAMINZERO) + { + type = *next; + while (1) + { + if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin) + break; + next_end = bracketend(next + 2 + LINK_SIZE); + if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0) + break; + next = next_end; + max++; + } + + if (next[0] == type && next[1] == *begin && max >= 1) + { + next_end = bracketend(next + 1); + if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0) + { + for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE) + if (*next_end != OP_KET) + break; + + if (i == max) + { + common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end; + common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO; + /* +2 the original and the last. */ + common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2; + if (min == 1) + return TRUE; + min--; + max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE); + } + } + } + } + +if (min >= 3) + { + common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end; + common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT; + common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min; + return TRUE; + } + +return FALSE; +} + #define CASE_ITERATOR_PRIVATE_DATA_1 \ case OP_MINSTAR: \ case OP_MINPLUS: \ @@ -737,234 +1071,12 @@ switch(*cc) case OP_TYPEUPTO: \ case OP_TYPEMINUPTO: -static int get_class_iterator_size(pcre_uchar *cc) -{ -switch(*cc) - { - case OP_CRSTAR: - case OP_CRPLUS: - return 2; - - case OP_CRMINSTAR: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - return 1; - - case OP_CRRANGE: - case OP_CRMINRANGE: - if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE)) - return 0; - return 2; - - default: - return 0; - } -} - -static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) -{ -int private_data_length = 0; -pcre_uchar *alternative; -pcre_uchar *name; -pcre_uchar *end = NULL; -int space, size, i; -pcre_uint32 bracketlen; - -/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ -while (cc < ccend) - { - space = 0; - size = 0; - bracketlen = 0; - switch(*cc) - { - case OP_SET_SOM: - common->has_set_som = TRUE; - cc += 1; - break; - - case OP_REF: - case OP_REFI: - common->optimized_cbracket[GET2(cc, 1)] = 0; - cc += 1 + IMM2_SIZE; - 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: - private_data_length += sizeof(sljit_sw); - bracketlen = 1 + LINK_SIZE; - break; - - case OP_CBRAPOS: - case OP_SCBRAPOS: - private_data_length += sizeof(sljit_sw); - common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; - bracketlen = 1 + LINK_SIZE + IMM2_SIZE; - break; - - case OP_COND: - case OP_SCOND: - bracketlen = cc[1 + LINK_SIZE]; - if (bracketlen == OP_CREF) - { - bracketlen = GET2(cc, 1 + LINK_SIZE + 1); - common->optimized_cbracket[bracketlen] = 0; - } - else if (bracketlen == OP_NCREF) - { - bracketlen = GET2(cc, 1 + LINK_SIZE + 1); - name = (pcre_uchar *)common->name_table; - alternative = name; - for (i = 0; i < common->name_count; i++) - { - if (GET2(name, 0) == bracketlen) break; - name += common->name_entry_size; - } - SLJIT_ASSERT(i != common->name_count); - - for (i = 0; i < common->name_count; i++) - { - if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0) - common->optimized_cbracket[GET2(alternative, 0)] = 0; - alternative += common->name_entry_size; - } - } - - if (*cc == OP_COND) - { - /* Might be a hidden SCOND. */ - alternative = cc + GET(cc, 1); - if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) - private_data_length += sizeof(sljit_sw); - } - else - private_data_length += sizeof(sljit_sw); - bracketlen = 1 + LINK_SIZE; - break; - - case OP_BRA: - bracketlen = 1 + LINK_SIZE; - break; - - case OP_CBRA: - case OP_SCBRA: - bracketlen = 1 + LINK_SIZE + IMM2_SIZE; - break; - - CASE_ITERATOR_PRIVATE_DATA_1 - space = 1; - size = -2; - break; - - CASE_ITERATOR_PRIVATE_DATA_2A - space = 2; - size = -2; - break; - - CASE_ITERATOR_PRIVATE_DATA_2B - space = 2; - size = -(2 + IMM2_SIZE); - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_1 - space = 1; - size = 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2A - if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) - space = 2; - size = 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2B - if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) - space = 2; - size = 1 + IMM2_SIZE; - break; - - case OP_CLASS: - case OP_NCLASS: - size += 1 + 32 / sizeof(pcre_uchar); - space = get_class_iterator_size(cc + size); - break; - -#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 - case OP_XCLASS: - size = GET(cc, 1); - space = get_class_iterator_size(cc + size); - break; -#endif - - case OP_RECURSE: - /* Set its value only once. */ - if (common->recursive_head == 0) - { - common->recursive_head = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } - cc += 1 + LINK_SIZE; - break; - - case OP_MARK: - if (common->mark_ptr == 0) - { - common->mark_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } - cc += 1 + 2 + cc[1]; - break; - - default: - cc = next_opcode(common, cc); - if (cc == NULL) - return -1; - break; - } - - if (space > 0 && cc >= end) - private_data_length += sizeof(sljit_sw) * space; - - if (size != 0) - { - if (size < 0) - { - cc += -size; -#ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - } - else - cc += size; - } - - if (bracketlen != 0) - { - if (cc >= end) - { - end = bracketend(cc); - if (end[-1 - LINK_SIZE] == OP_KET) - end = NULL; - } - cc += bracketlen; - } - } -return private_data_length; -} - -static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend) +static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend) { pcre_uchar *cc = common->start; pcre_uchar *alternative; pcre_uchar *end = NULL; +int private_data_ptr = *private_data_start; int space, size, bracketlen; while (cc < ccend) @@ -972,8 +1084,30 @@ while (cc < ccend) space = 0; size = 0; bracketlen = 0; + if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE) + return; + + if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND) + if (detect_repeat(common, cc)) + { + /* These brackets are converted to repeats, so no global + based single character repeat is allowed. */ + if (cc >= end) + end = bracketend(cc); + } + switch(*cc) { + case OP_KET: + if (common->private_data_ptrs[cc + 1 - common->start] != 0) + { + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw); + cc += common->private_data_ptrs[cc + 1 - common->start]; + } + cc += 1 + LINK_SIZE; + break; + case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: @@ -1067,6 +1201,8 @@ while (cc < ccend) break; } + /* Character iterators, which are not inside a repeated bracket, + gets a private slot instead of allocating it on the stack. */ if (space > 0 && cc >= end) { common->private_data_ptrs[cc - common->start] = private_data_ptr; @@ -1097,30 +1233,46 @@ while (cc < ccend) cc += bracketlen; } } +*private_data_start = private_data_ptr; } -/* Returns with -1 if no need for frame. */ -static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive) +/* Returns with a frame_types (always < 0) if no need for frame. */ +static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head) { -pcre_uchar *ccend = bracketend(cc); int length = 0; -BOOL possessive = FALSE; +int possessive = 0; +BOOL stack_restore = FALSE; BOOL setsom_found = recursive; BOOL setmark_found = recursive; +/* The last capture is a local variable even for recursions. */ +BOOL capture_last_found = FALSE; -if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) +#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD +SLJIT_ASSERT(common->control_head_ptr != 0); +*needs_control_head = TRUE; +#else +*needs_control_head = FALSE; +#endif + +if (ccend == NULL) { - length = 3; - possessive = TRUE; + ccend = bracketend(cc) - (1 + LINK_SIZE); + if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) + { + possessive = length = (common->capture_last_ptr != 0) ? 5 : 3; + /* This is correct regardless of common->capture_last_ptr. */ + capture_last_found = TRUE; + } + cc = next_opcode(common, cc); } -cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); while (cc < ccend) switch(*cc) { case OP_SET_SOM: SLJIT_ASSERT(common->has_set_som); + stack_restore = TRUE; if (!setsom_found) { length += 2; @@ -1130,16 +1282,22 @@ while (cc < ccend) break; case OP_MARK: + case OP_PRUNE_ARG: + case OP_THEN_ARG: SLJIT_ASSERT(common->mark_ptr != 0); + stack_restore = TRUE; if (!setmark_found) { length += 2; setmark_found = TRUE; } + if (common->control_head_ptr != 0) + *needs_control_head = TRUE; cc += 1 + 2 + cc[1]; break; case OP_RECURSE: + stack_restore = TRUE; if (common->has_set_som && !setsom_found) { length += 2; @@ -1150,6 +1308,11 @@ while (cc < ccend) length += 2; setmark_found = TRUE; } + if (common->capture_last_ptr != 0 && !capture_last_found) + { + length += 2; + capture_last_found = TRUE; + } cc += 1 + LINK_SIZE; break; @@ -1157,31 +1320,105 @@ while (cc < ccend) case OP_CBRAPOS: case OP_SCBRA: case OP_SCBRAPOS: + stack_restore = TRUE; + if (common->capture_last_ptr != 0 && !capture_last_found) + { + length += 2; + capture_last_found = TRUE; + } length += 3; cc += 1 + LINK_SIZE + IMM2_SIZE; break; default: + stack_restore = TRUE; + /* Fall through. */ + + 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_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + + case OP_TYPEEXACT: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSUPTO: + + case OP_CLASS: + case OP_NCLASS: + case OP_XCLASS: + 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 (SLJIT_UNLIKELY(possessive == length)) + return stack_restore ? no_frame : no_stack; if (length > 0) return length + 1; -return -1; +return stack_restore ? no_frame : no_stack; } -static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive) +static void init_frame(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive) { DEFINE_COMPILER; -pcre_uchar *ccend = bracketend(cc); BOOL setsom_found = recursive; BOOL setmark_found = recursive; +/* The last capture is a local variable even for recursions. */ +BOOL capture_last_found = FALSE; int offset; /* >= 1 + shortest item size (2) */ @@ -1189,8 +1426,13 @@ 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); +if (ccend == NULL) + { + ccend = bracketend(cc) - (1 + LINK_SIZE); + if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) + cc = next_opcode(common, cc); + } + SLJIT_ASSERT(cc != NULL); while (cc < ccend) switch(*cc) @@ -1200,7 +1442,7 @@ while (cc < ccend) 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); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0)); stackpos += (int)sizeof(sljit_sw); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); stackpos += (int)sizeof(sljit_sw); @@ -1210,11 +1452,13 @@ while (cc < ccend) break; case OP_MARK: + case OP_PRUNE_ARG: + case OP_THEN_ARG: 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); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr); stackpos += (int)sizeof(sljit_sw); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); stackpos += (int)sizeof(sljit_sw); @@ -1227,7 +1471,7 @@ while (cc < ccend) 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); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0)); stackpos += (int)sizeof(sljit_sw); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); stackpos += (int)sizeof(sljit_sw); @@ -1236,12 +1480,21 @@ while (cc < ccend) 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); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr); stackpos += (int)sizeof(sljit_sw); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); stackpos += (int)sizeof(sljit_sw); setmark_found = TRUE; } + if (common->capture_last_ptr != 0 && !capture_last_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr); + stackpos += (int)sizeof(sljit_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + capture_last_found = TRUE; + } cc += 1 + LINK_SIZE; break; @@ -1249,6 +1502,15 @@ while (cc < ccend) case OP_CBRAPOS: case OP_SCBRA: case OP_SCBRAPOS: + if (common->capture_last_ptr != 0 && !capture_last_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr); + stackpos += (int)sizeof(sljit_sw); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_sw); + capture_last_found = TRUE; + } offset = (GET2(cc, 1 + LINK_SIZE)) << 1; OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); stackpos += (int)sizeof(sljit_sw); @@ -1268,13 +1530,13 @@ while (cc < ccend) break; } -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0); SLJIT_ASSERT(stackpos == STACK(stacktop)); } -static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) +static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head) { -int private_data_length = 2; +int private_data_length = needs_control_head ? 3 : 2; int size; pcre_uchar *alternative; /* Calculate the sum of the private machine words. */ @@ -1283,6 +1545,12 @@ while (cc < ccend) size = 0; switch(*cc) { + case OP_KET: + if (PRIVATE_DATA(cc) != 0) + private_data_length++; + cc += 1 + LINK_SIZE; + break; + case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: @@ -1387,7 +1655,7 @@ return private_data_length; } static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, - BOOL save, int stackptr, int stacktop) + BOOL save, int stackptr, int stacktop, BOOL needs_control_head) { DEFINE_COMPILER; int srcw[2]; @@ -1408,7 +1676,7 @@ stacktop = STACK(stacktop - 1); if (!save) { - stackptr += sizeof(sljit_sw); + stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw); if (stackptr < stacktop) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); @@ -1424,15 +1692,21 @@ if (!save) /* The tmp1next must be TRUE in either way. */ } -while (status != end) +do { count = 0; switch(status) { case start: - SLJIT_ASSERT(save && common->recursive_head != 0); + SLJIT_ASSERT(save && common->recursive_head_ptr != 0); count = 1; - srcw[0] = common->recursive_head; + srcw[0] = common->recursive_head_ptr; + if (needs_control_head) + { + SLJIT_ASSERT(common->control_head_ptr != 0); + count = 2; + srcw[1] = common->control_head_ptr; + } status = loop; break; @@ -1445,6 +1719,15 @@ while (status != end) switch(*cc) { + case OP_KET: + if (PRIVATE_DATA(cc) != 0) + { + count = 1; + srcw[0] = PRIVATE_DATA(cc); + } + cc += 1 + LINK_SIZE; + break; + case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: @@ -1657,6 +1940,7 @@ while (status != end) } } } +while (status != end); if (save) { @@ -1690,6 +1974,39 @@ if (save) SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); } +static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset) +{ +pcre_uchar *end = bracketend(cc); +BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; + +/* Assert captures then. */ +if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) + current_offset = NULL; +/* Conditional block does not. */ +if (*cc == OP_COND || *cc == OP_SCOND) + has_alternatives = FALSE; + +cc = next_opcode(common, cc); +if (has_alternatives) + current_offset = common->then_offsets + (cc - common->start); + +while (cc < end) + { + if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)) + cc = set_then_offsets(common, cc, current_offset); + else + { + if (*cc == OP_ALT && has_alternatives) + current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start); + if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) + *current_offset = 1; + cc = next_opcode(common, cc); + } + } + +return end; +} + #undef CASE_ITERATOR_PRIVATE_DATA_1 #undef CASE_ITERATOR_PRIVATE_DATA_2A #undef CASE_ITERATOR_PRIVATE_DATA_2B @@ -1708,7 +2025,7 @@ 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); + SET_LABEL(list->jump, label); list = list->next; } } @@ -1724,15 +2041,13 @@ if (list_item) } } -static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start) +static void add_stub(compiler_common *common, 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->quit = LABEL(); list_item->next = common->stubs; @@ -1748,23 +2063,33 @@ 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; - } + add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); JUMPTO(SLJIT_JUMP, list_item->quit); list_item = list_item->next; } common->stubs = NULL; } -static SLJIT_INLINE void decrease_call_count(compiler_common *common) +static void add_label_addr(compiler_common *common) +{ +DEFINE_COMPILER; +label_addr_list *label_addr; + +label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list)); +if (label_addr == NULL) + return; +label_addr->label = LABEL(); +label_addr->addr = common->read_only_data_ptr; +label_addr->next = common->label_addrs; +common->label_addrs = label_addr; +common->read_only_data_ptr++; +} + +static SLJIT_INLINE void count_match(compiler_common *common) { DEFINE_COMPILER; -OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1); +OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); } @@ -1781,7 +2106,7 @@ 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)); +add_stub(common, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); } static SLJIT_INLINE void free_stack(compiler_common *common, int size) @@ -1795,18 +2120,20 @@ 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. */ +SLJIT_ASSERT(length > 1); /* TMP1 returns with begin - 1. */ OP2(SLJIT_SUB, SLJIT_SCRATCH_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++) + for (i = 1; i < length; i++) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0); } else { - GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length); + GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1); loop = LABEL(); OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1); @@ -1814,11 +2141,69 @@ else } } +static SLJIT_INLINE void do_reset_match(compiler_common *common, int length) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +int i; + +SLJIT_ASSERT(length > 1); +/* OVECTOR(1) contains the "string begin - 1" constant. */ +if (length > 2) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); +if (length < 8) + { + for (i = 2; i < length; i++) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0); + } +else + { + GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2); + loop = LABEL(); + OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); + OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, loop); + } + +OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0); +if (common->control_head_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base)); +} + +static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg) +{ +while (current != NULL) + { + switch (current[-2]) + { + case type_then_trap: + break; + + case type_mark: + if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0) + return current[-4]; + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + current = (sljit_sw*)current[-1]; + } +return -1; +} + static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) { DEFINE_COMPILER; struct sljit_label *loop; -struct sljit_jump *earlyexit; +struct sljit_jump *early_quit; /* At this point we can freely use all registers. */ OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); @@ -1827,14 +2212,14 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0); if (common->mark_ptr != 0) OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); -OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); +OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count)); if (common->mark_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0); OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START); /* Unlikely, but possible */ -earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0); +early_quit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0); loop = LABEL(); OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0); OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw)); @@ -1845,7 +2230,7 @@ OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1); JUMPTO(SLJIT_C_NOT_ZERO, loop); -JUMPHERE(earlyexit); +JUMPHERE(early_quit); /* Calculate the return value, which is the maximum ovector value. */ if (topbracket > 1) @@ -1867,18 +2252,29 @@ else static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit) { DEFINE_COMPILER; +struct sljit_jump *jump; 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)); +SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0 + && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0)); OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); -OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); -CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit); +OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, real_offset_count)); +CMPTO(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit); /* Store match begin and end. */ OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); + +jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3); +OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0); +#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif +OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0); +JUMPHERE(jump); + OP1(SLJIT_MOV, SLJIT_SCRATCH_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); #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 @@ -2040,7 +2436,7 @@ return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8)); static void check_partial(compiler_common *common, BOOL force) { -/* Checks whether a partial matching is occured. Does not modify registers. */ +/* Checks whether a partial matching is occurred. Does not modify registers. */ DEFINE_COMPILER; struct sljit_jump *jump = NULL; @@ -2055,7 +2451,7 @@ 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); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); else { if (common->partialmatchlabel != NULL) @@ -2068,35 +2464,34 @@ if (jump != NULL) JUMPHERE(jump); } -static struct sljit_jump *check_str_end(compiler_common *common) +static void check_str_end(compiler_common *common, jump_list **end_reached) { /* 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); + { + add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + return; + } 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); + add_jump(compiler, end_reached, 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, 0); + add_jump(compiler, end_reached, JUMP(SLJIT_JUMP)); } else { - return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); + add_jump(compiler, end_reached, 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) @@ -2115,7 +2510,7 @@ 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); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); } else @@ -2128,32 +2523,7 @@ else 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; -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 -struct sljit_jump *jump; -#endif - -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 -if (common->utf) - { -#if defined COMPILE_PCRE8 - jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); -#elif defined COMPILE_PCRE16 - jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); -#endif /* COMPILE_PCRE[8|16] */ - add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); - JUMPHERE(jump); - } -#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -} - -static void peek_char(compiler_common *common) +static void peek_char(compiler_common *common, pcre_uint32 max) { /* Reads the character into TMP1, keeps STR_PTR. Does not check STR_END. TMP2 Destroyed. */ @@ -2162,73 +2532,281 @@ DEFINE_COMPILER; struct sljit_jump *jump; #endif +SLJIT_UNUSED_ARG(max); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (common->utf) { -#if defined COMPILE_PCRE8 + if (max < 128) return; + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); -#elif defined COMPILE_PCRE16 - jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); -#endif /* COMPILE_PCRE[8|16] */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); JUMPHERE(jump); } #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ + +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +if (common->utf) + { + if (max < 0xd800) return; + + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); + jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); + /* TMP2 contains the high surrogate. */ + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + JUMPHERE(jump); + } +#endif } -static void read_char8_type(compiler_common *common) +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + +static BOOL is_char7_bitset(const pcre_uint8 *bitset, BOOL nclass) +{ +/* Tells whether the character codes below 128 are enough +to determine a match. */ +const pcre_uint8 value = nclass ? 0xff : 0; +const pcre_uint8* end = bitset + 32; + +bitset += 16; +do + { + if (*bitset++ != value) + return FALSE; + } +while (bitset < end); +return TRUE; +} + +static void read_char7_type(compiler_common *common, BOOL full_read) +{ +/* Reads the precise character type of a character into TMP1, if the character +is less than 128. Otherwise it returns with zero. Does not check STR_END. The +full_read argument tells whether characters above max are accepted or not. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +SLJIT_ASSERT(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)); + +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + +if (full_read) + { + jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + JUMPHERE(jump); + } +} + +#endif /* SUPPORT_UTF && COMPILE_PCRE8 */ + +static void read_char_range(compiler_common *common, pcre_uint32 min, pcre_uint32 max, BOOL update_str_ptr) +{ +/* Reads the precise value of a character into TMP1, if the character is +between min and max (c >= min && c <= max). Otherwise it returns with a value +outside the range. Does not check STR_END. */ +DEFINE_COMPILER; +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +struct sljit_jump *jump; +#endif +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +struct sljit_jump *jump2; +#endif + +SLJIT_UNUSED_ARG(update_str_ptr); +SLJIT_UNUSED_ARG(min); +SLJIT_UNUSED_ARG(max); +SLJIT_ASSERT(min <= max); + +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)); + +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +if (common->utf) + { + if (max < 128 && !update_str_ptr) return; + + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + if (min >= 0x10000) + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0); + if (update_str_ptr) + OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + 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(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); + if (!update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); + 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); + JUMPHERE(jump2); + if (update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); + } + else if (min >= 0x800 && max <= 0xffff) + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0); + if (update_str_ptr) + OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xf); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + if (!update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + 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); + JUMPHERE(jump2); + if (update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); + } + else if (max >= 0x800) + add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); + else if (max < 128) + { + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + } + else + { + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (!update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + else + OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); + 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); + if (update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); + } + JUMPHERE(jump); + } +#endif + +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +if (common->utf) + { + if (max >= 0x10000) + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); + jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); + /* TMP2 contains the high surrogate. */ + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); + 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_OR, TMP1, 0, TMP1, 0, TMP2, 0); + JUMPHERE(jump); + return; + } + + if (max < 0xd800 && !update_str_ptr) return; + + /* Skip low surrogate if necessary. */ + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); + jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); + if (update_str_ptr) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + if (max >= 0xd800) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000); + JUMPHERE(jump); + } +#endif +} + +static SLJIT_INLINE void read_char(compiler_common *common) +{ +read_char_range(common, 0, READ_CHAR_MAX, TRUE); +} + +static void read_char8_type(compiler_common *common, BOOL update_str_ptr) { /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */ DEFINE_COMPILER; -#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 struct sljit_jump *jump; #endif +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +struct sljit_jump *jump2; +#endif -#ifdef SUPPORT_UTF +SLJIT_UNUSED_ARG(update_str_ptr); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 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)); -#if defined 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)); + if (!update_str_ptr) + { + 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, 0x3f); + 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); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); + jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + JUMPHERE(jump2); + } + else + add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL)); JUMPHERE(jump); -#elif defined 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); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 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); -#elif defined COMPILE_PCRE32 - 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); -#endif /* COMPILE_PCRE[8|16|32] */ return; } -#endif /* SUPPORT_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)); -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#endif /* SUPPORT_UTF && COMPILE_PCRE8 */ + +#if !defined COMPILE_PCRE8 /* 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); -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#if !defined COMPILE_PCRE8 JUMPHERE(jump); #endif + +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +if (common->utf && update_str_ptr) + { + /* Skip low surrogate if necessary. */ + OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800); + jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + JUMPHERE(jump); + } +#endif /* SUPPORT_UTF && COMPILE_PCRE16 */ } static void skip_char_back(compiler_common *common) @@ -2266,28 +2844,35 @@ if (common->utf) 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) +static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch) { /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */ DEFINE_COMPILER; +struct sljit_jump *jump; 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)); + add_jump(compiler, backtracks, JUMP(jumpifmatch ? 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); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); - add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + if (jumpifmatch) + { + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR)); + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); + } + else + { + jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); + JUMPHERE(jump); + } } 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)); + add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); } } @@ -2297,58 +2882,84 @@ else 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. */ +of the character (>= 0xc0). Return char value in TMP1, length 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); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 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); +/* Searching for the first zero. */ +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); 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); +/* Two byte sequence. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2)); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + JUMPHERE(jump); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800); +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); + +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000); +jump = JUMP(SLJIT_C_NOT_ZERO); +/* Three byte sequence. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); /* 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); +JUMPHERE(jump); 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_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 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)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void do_utfreadchar16(compiler_common *common) +{ +/* Fast decoding a UTF-8 character. TMP1 contains the first byte +of the character (>= 0xc0). Return value in TMP1. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); +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); + +/* Searching for the first zero. */ +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); +jump = JUMP(SLJIT_C_NOT_ZERO); +/* Two byte sequence. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 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, 0x400); +OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_NOT_ZERO); +/* This code runs only in 8 bit mode. No need to shift the value. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800); +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); +/* Three byte sequence. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } @@ -2368,53 +2979,27 @@ jump = JUMP(SLJIT_C_NOT_ZERO); 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); +/* The upper 5 bits are known at this point. */ +compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x3); 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_sw)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); -} - -#elif defined 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); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } -#endif /* COMPILE_PCRE[8|16] */ +#endif /* COMPILE_PCRE8 */ #endif /* SUPPORT_UTF */ @@ -2489,7 +3074,7 @@ if (firstline) 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); + read_char_range(common, common->nlmin, common->nlmax, TRUE); check_newlinechar(common, common->nltype, &newline, TRUE); CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); JUMPHERE(end); @@ -2565,37 +3150,66 @@ if (newlinecheck) return mainloop; } -#define MAX_N_CHARS 3 +#define MAX_N_CHARS 16 +#define MAX_N_BYTES 8 -static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline) +static SLJIT_INLINE void add_prefix_byte(pcre_uint8 byte, pcre_uint8 *bytes) { -DEFINE_COMPILER; -struct sljit_label *start; -struct sljit_jump *quit; -pcre_uint32 chars[MAX_N_CHARS * 2]; -pcre_uchar *cc = common->start + 1 + IMM2_SIZE; -int location = 0; -pcre_int32 len, c, bit, caseless; -int must_stop; +pcre_uint8 len = bytes[0]; +int i; -/* We do not support alternatives now. */ -if (*(common->start + GET(common->start, 1)) == OP_ALT) - return FALSE; +if (len == 255) + return; +if (len == 0) + { + bytes[0] = 1; + bytes[1] = byte; + return; + } + +for (i = len; i > 0; i--) + if (bytes[i] == byte) + return; + +if (len >= MAX_N_BYTES - 1) + { + bytes[0] = 255; + return; + } + +len++; +bytes[len] = byte; +bytes[0] = len; +} + +static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars) +{ +/* Recursive function, which scans prefix literals. */ +BOOL last, any, caseless; +int len, repeat, len_save, consumed = 0; +pcre_uint32 chr, mask; +pcre_uchar *alternative, *cc_save, *oc; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +pcre_uchar othercase[8]; +#elif defined SUPPORT_UTF && defined COMPILE_PCRE16 +pcre_uchar othercase[2]; +#else +pcre_uchar othercase[1]; +#endif + +repeat = 1; while (TRUE) { - caseless = 0; - must_stop = 1; - switch(*cc) + last = TRUE; + any = FALSE; + caseless = FALSE; + switch (*cc) { - case OP_CHAR: - must_stop = 0; - cc++; - break; - case OP_CHARI: - caseless = 1; - must_stop = 0; + caseless = TRUE; + case OP_CHAR: + last = FALSE; cc++; break; @@ -2614,125 +3228,546 @@ while (TRUE) cc++; continue; + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + cc = bracketend(cc); + continue; + + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + caseless = TRUE; case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: cc++; break; + case OP_EXACTI: + caseless = TRUE; case OP_EXACT: + repeat = GET2(cc, 1); + last = FALSE; cc += 1 + IMM2_SIZE; break; - case OP_PLUSI: - case OP_MINPLUSI: - case OP_POSPLUSI: - caseless = 1; + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + caseless = TRUE; + case OP_QUERY: + case OP_MINQUERY: + case OP_POSQUERY: + len = 1; + cc++; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); +#endif + max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars); + if (max_chars == 0) + return consumed; + last = FALSE; + break; + + case OP_KET: + cc += 1 + LINK_SIZE; + continue; + + case OP_ALT: + cc += GET(cc, 1); + continue; + + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_BRAPOS: + case OP_CBRA: + case OP_CBRAPOS: + alternative = cc + GET(cc, 1); + while (*alternative == OP_ALT) + { + max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars); + if (max_chars == 0) + return consumed; + alternative += GET(alternative, 1); + } + + if (*cc == OP_CBRA || *cc == OP_CBRAPOS) + cc += IMM2_SIZE; + cc += 1 + LINK_SIZE; + continue; + + case OP_CLASS: +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (common->utf && !is_char7_bitset((const pcre_uint8 *)(cc + 1), FALSE)) return consumed; +#endif + any = TRUE; + cc += 1 + 32 / sizeof(pcre_uchar); + break; + + case OP_NCLASS: +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (common->utf) return consumed; +#endif + any = TRUE; + cc += 1 + 32 / sizeof(pcre_uchar); + break; + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (common->utf) return consumed; +#endif + any = TRUE; + cc += GET(cc, 1); + break; +#endif + + case OP_DIGIT: +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_digit, FALSE)) + return consumed; +#endif + any = TRUE; cc++; break; - case OP_EXACTI: - caseless = 1; + case OP_WHITESPACE: +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_space, FALSE)) + return consumed; +#endif + any = TRUE; + cc++; + break; + + case OP_WORDCHAR: +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_word, FALSE)) + return consumed; +#endif + any = TRUE; + cc++; + break; + + case OP_NOT: + case OP_NOTI: + cc++; + /* Fall through. */ + case OP_NOT_DIGIT: + case OP_NOT_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_ANY: + case OP_ALLANY: +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (common->utf) return consumed; +#endif + any = TRUE; + cc++; + break; + +#ifdef SUPPORT_UCP + case OP_NOTPROP: + case OP_PROP: +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (common->utf) return consumed; +#endif + any = TRUE; + cc += 1 + 2; + break; +#endif + + case OP_TYPEEXACT: + repeat = GET2(cc, 1); cc += 1 + IMM2_SIZE; + continue; + + case OP_NOTEXACT: + case OP_NOTEXACTI: +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (common->utf) return consumed; +#endif + any = TRUE; + repeat = GET2(cc, 1); + cc += 1 + IMM2_SIZE + 1; break; default: - must_stop = 2; - break; + return consumed; } - if (must_stop == 2) - break; + if (any) + { +#if defined COMPILE_PCRE8 + mask = 0xff; +#elif defined COMPILE_PCRE16 + mask = 0xffff; +#elif defined COMPILE_PCRE32 + mask = 0xffffffff; +#else + SLJIT_ASSERT_STOP(); +#endif + + do + { + chars[0] = mask; + chars[1] = mask; + bytes[0] = 255; + + consumed++; + if (--max_chars == 0) + return consumed; + chars += 2; + bytes += MAX_N_BYTES; + } + while (--repeat > 0); + + repeat = 1; + continue; + } len = 1; #ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]); + if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); #endif if (caseless && char_has_othercase(common, cc)) { - caseless = char_get_othercase_bit(common, cc); - if (caseless == 0) - return FALSE; -#ifdef COMPILE_PCRE8 - caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8)); -#else - if ((caseless & 0x100) != 0) - caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9)); +#ifdef SUPPORT_UTF + if (common->utf) + { + GETCHAR(chr, cc); + if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len) + return consumed; + } else - caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9)); #endif + { + chr = *cc; + othercase[0] = TABLE_GET(chr, common->fcc, chr); + } } else - caseless = 0; + caseless = FALSE; - while (len > 0 && location < MAX_N_CHARS * 2) + len_save = len; + cc_save = cc; + while (TRUE) { - c = *cc; - bit = 0; - if (len == (caseless & 0xff)) + oc = othercase; + do { - bit = caseless >> 8; - c |= bit; + chr = *cc; +#ifdef COMPILE_PCRE32 + if (SLJIT_UNLIKELY(chr == NOTACHAR)) + return consumed; +#endif + add_prefix_byte((pcre_uint8)chr, bytes); + + mask = 0; + if (caseless) + { + add_prefix_byte((pcre_uint8)*oc, bytes); + mask = *cc ^ *oc; + chr |= mask; + } + +#ifdef COMPILE_PCRE32 + if (chars[0] == NOTACHAR && chars[1] == 0) +#else + if (chars[0] == NOTACHAR) +#endif + { + chars[0] = chr; + chars[1] = mask; + } + else + { + mask |= chars[0] ^ chr; + chr |= mask; + chars[0] = chr; + chars[1] |= mask; + } + + len--; + consumed++; + if (--max_chars == 0) + return consumed; + chars += 2; + bytes += MAX_N_BYTES; + cc++; + oc++; } + while (len > 0); - chars[location] = c; - chars[location + 1] = bit; + if (--repeat == 0) + break; - len--; - location += 2; - cc++; + len = len_save; + cc = cc_save; } - if (location >= MAX_N_CHARS * 2 || must_stop != 0) + repeat = 1; + if (last) + return consumed; + } +} + +static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit; +pcre_uint32 chars[MAX_N_CHARS * 2]; +pcre_uint8 bytes[MAX_N_CHARS * MAX_N_BYTES]; +pcre_uint8 ones[MAX_N_CHARS]; +int offsets[3]; +pcre_uint32 mask; +pcre_uint8 *byte_set, *byte_set_end; +int i, max, from; +int range_right = -1, range_len = 3 - 1; +sljit_ub *update_table = NULL; +BOOL in_range; + +/* This is even TRUE, if both are NULL. */ +SLJIT_ASSERT(common->read_only_data_ptr == common->read_only_data); + +for (i = 0; i < MAX_N_CHARS; i++) + { + chars[i << 1] = NOTACHAR; + chars[(i << 1) + 1] = 0; + bytes[i * MAX_N_BYTES] = 0; + } + +max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS); + +if (max <= 1) + return FALSE; + +for (i = 0; i < max; i++) + { + mask = chars[(i << 1) + 1]; + ones[i] = ones_in_half_byte[mask & 0xf]; + mask >>= 4; + while (mask != 0) + { + ones[i] += ones_in_half_byte[mask & 0xf]; + mask >>= 4; + } + } + +in_range = FALSE; +from = 0; /* Prevent compiler "uninitialized" warning */ +for (i = 0; i <= max; i++) + { + if (in_range && (i - from) > range_len && (bytes[(i - 1) * MAX_N_BYTES] <= 4)) + { + range_len = i - from; + range_right = i - 1; + } + + if (i < max && bytes[i * MAX_N_BYTES] < 255) + { + if (!in_range) + { + in_range = TRUE; + from = i; + } + } + else if (in_range) + in_range = FALSE; + } + +if (range_right >= 0) + { + /* Since no data is consumed (see the assert in the beginning + of this function), this space can be reallocated. */ + if (common->read_only_data) + SLJIT_FREE(common->read_only_data); + + common->read_only_data_size += 256; + common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size); + if (common->read_only_data == NULL) + return TRUE; + + update_table = (sljit_ub *)common->read_only_data; + common->read_only_data_ptr = (sljit_uw *)(update_table + 256); + memset(update_table, IN_UCHARS(range_len), 256); + + for (i = 0; i < range_len; i++) + { + byte_set = bytes + ((range_right - i) * MAX_N_BYTES); + SLJIT_ASSERT(byte_set[0] > 0 && byte_set[0] < 255); + byte_set_end = byte_set + byte_set[0]; + byte_set++; + while (byte_set <= byte_set_end) + { + if (update_table[*byte_set] > IN_UCHARS(i)) + update_table[*byte_set] = IN_UCHARS(i); + byte_set++; + } + } + } + +offsets[0] = -1; +/* Scan forward. */ +for (i = 0; i < max; i++) + if (ones[i] <= 2) { + offsets[0] = i; break; } -/* At least two characters are required. */ -if (location < 2 * 2) +if (offsets[0] < 0 && range_right < 0) + return FALSE; + +if (offsets[0] >= 0) + { + /* Scan backward. */ + offsets[1] = -1; + for (i = max - 1; i > offsets[0]; i--) + if (ones[i] <= 2 && i != range_right) + { + offsets[1] = i; + break; + } + + /* This case is handled better by fast_forward_first_char. */ + if (offsets[1] == -1 && offsets[0] == 0 && range_right < 0) return FALSE; + offsets[2] = -1; + /* We only search for a middle character if there is no range check. */ + if (offsets[1] >= 0 && range_right == -1) + { + /* Scan from middle. */ + for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++) + if (ones[i] <= 2) + { + offsets[2] = i; + break; + } + + if (offsets[2] == -1) + { + for (i = (offsets[0] + offsets[1]) / 2; i > offsets[0]; i--) + if (ones[i] <= 2) + { + offsets[2] = i; + break; + } + } + } + + SLJIT_ASSERT(offsets[1] == -1 || (offsets[0] < offsets[1])); + SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2])); + + chars[0] = chars[offsets[0] << 1]; + chars[1] = chars[(offsets[0] << 1) + 1]; + if (offsets[2] >= 0) + { + chars[2] = chars[offsets[2] << 1]; + chars[3] = chars[(offsets[2] << 1) + 1]; + } + if (offsets[1] >= 0) + { + chars[4] = chars[offsets[1] << 1]; + chars[5] = chars[(offsets[1] << 1) + 1]; + } + } + +max -= 1; if (firstline) { SLJIT_ASSERT(common->first_line_end != 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1); + OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); + quit = CMP(SLJIT_C_LESS_EQUAL, STR_END, 0, TMP1, 0); + OP1(SLJIT_MOV, STR_END, 0, TMP1, 0); + JUMPHERE(quit); } else - OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1); + OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); + +#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +if (range_right >= 0) + OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table); +#endif start = LABEL(); quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); -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)); -if (chars[1] != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]); -CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start); -if (location > 2 * 2) - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); -if (chars[3] != 0) - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]); -CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start); -if (location > 2 * 2) +SLJIT_ASSERT(range_right >= 0 || offsets[0] >= 0); + +if (range_right >= 0) { - if (chars[5] != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]); - CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start); +#if defined COMPILE_PCRE8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right)); +#else + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1); +#endif + +#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0); +#else + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start); + } + +if (offsets[0] >= 0) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0])); + if (offsets[1] >= 0) + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1])); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + + if (chars[1] != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start); + if (offsets[2] >= 0) + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[2] - 1)); + + if (offsets[1] >= 0) + { + if (chars[5] != 0) + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]); + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start); + } + + if (offsets[2] >= 0) + { + if (chars[3] != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start); + } + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); JUMPHERE(quit); if (firstline) + { + if (range_right >= 0) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + if (range_right >= 0) + { + quit = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); + OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); + JUMPHERE(quit); + } + } else - OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1); + OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); return TRUE; } #undef MAX_N_CHARS +#undef MAX_N_BYTES static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline) { @@ -2838,7 +3873,7 @@ if (common->nltype == NLTYPE_FIXED && common->newline > 255) JUMPHERE(lastchar); if (firstline) - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); return; } @@ -2848,7 +3883,9 @@ firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); skip_char_back(common); loop = LABEL(); -read_char(common); +common->ff_newline_shortcut = loop; + +read_char_range(common, common->nlmin, common->nlmax, TRUE); 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); @@ -2877,12 +3914,15 @@ if (firstline) OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); } -static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline) +static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks); + +static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, pcre_uint8 *start_bits, BOOL firstline) { DEFINE_COMPILER; struct sljit_label *start; struct sljit_jump *quit; -struct sljit_jump *found; +struct sljit_jump *found = NULL; +jump_list *matches = NULL; #ifndef COMPILE_PCRE8 struct sljit_jump *jump; #endif @@ -2901,17 +3941,21 @@ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); if (common->utf) OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); #endif + +if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches)) + { #ifndef COMPILE_PCRE8 -jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255); -JUMPHERE(jump); + 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); + 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_sw)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) @@ -2939,7 +3983,10 @@ if (common->utf) #endif /* COMPILE_PCRE[8|16] */ #endif /* SUPPORT_UTF */ JUMPTO(SLJIT_JUMP, start); -JUMPHERE(found); +if (found != NULL) + JUMPHERE(found); +if (matches != NULL) + set_jumps(matches, LABEL()); JUMPHERE(quit); if (firstline) @@ -3022,7 +4069,9 @@ 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_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0); +jump = JUMP(SLJIT_C_SIG_LESS_EQUAL); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw)); @@ -3030,31 +4079,14 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw)); JUMPTO(SLJIT_JUMP, mainloop); JUMPHERE(jump); -jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); +jump = JUMP(SLJIT_C_SIG_LESS); /* 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_sw)); -OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); -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_sw)); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); - JUMPTO(SLJIT_JUMP, mainloop); - - JUMPHERE(jump); - } - -/* Unknown command. */ +OP1(SLJIT_NEG, TMP2, 0, TMP2, 0); +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); JUMPTO(SLJIT_JUMP, mainloop); } @@ -3063,6 +4095,7 @@ static void check_wordboundary(compiler_common *common) { DEFINE_COMPILER; struct sljit_jump *skipread; +jump_list *skipread_list = NULL; #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF struct sljit_jump *jump; #endif @@ -3120,8 +4153,8 @@ else JUMPHERE(skipread); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); -skipread = check_str_end(common); -peek_char(common); +check_str_end(common, &skipread_list); +peek_char(common, READ_CHAR_MAX); /* Testing char type. This is a code duplication. */ #ifdef SUPPORT_UCP @@ -3161,116 +4194,21 @@ else JUMPHERE(jump); #endif /* COMPILE_PCRE8 */ } -JUMPHERE(skipread); +set_jumps(skipread_list, LABEL()); 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); } -/* - range format: - - ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range). - ranges[1] = first bit (0 or 1) - ranges[2-length] = position of the bit change (when the current bit is not equal to the previous) -*/ - -static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch) +static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks) { DEFINE_COMPILER; -struct sljit_jump *jump; - -if (ranges[0] < 0) - return FALSE; - -switch(ranges[0]) - { - case 1: - if (readch) - read_char(common); - add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); - return TRUE; - - case 2: - if (readch) - read_char(common); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]); - add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); - return TRUE; - - case 4: - if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5]) - { - if (readch) - read_char(common); - if (ranges[1] != 0) - { - add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); - add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4])); - } - else - { - jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]); - add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4])); - JUMPHERE(jump); - } - return TRUE; - } - if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2])) - { - if (readch) - read_char(common); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]); - add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4])); - return TRUE; - } - return FALSE; - - default: - return FALSE; - } -} - -static void get_ctype_ranges(compiler_common *common, int flag, int *ranges) -{ -int i, bit, length; -const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes; - -bit = ctypes[0] & flag; -ranges[0] = -1; -ranges[1] = bit != 0 ? 1 : 0; -length = 0; - -for (i = 1; i < 256; i++) - if ((ctypes[i] & flag) != bit) - { - if (length >= MAX_RANGE_SIZE) - return; - ranges[2 + length] = i; - length++; - bit ^= flag; - } - -if (bit != 0) - { - if (length >= MAX_RANGE_SIZE) - return; - ranges[2 + length] = 256; - length++; - } -ranges[0] = length; -} - -static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks) -{ -int ranges[2 + MAX_RANGE_SIZE]; +int ranges[MAX_RANGE_SIZE]; pcre_uint8 bit, cbit, all; int i, byte, length = 0; bit = bits[0] & 0x1; -ranges[1] = bit; -/* Can be 0 or 255. */ +/* All bits will be zero or one (since bit is zero or one). */ all = -bit; for (i = 0; i < 256; ) @@ -3285,7 +4223,7 @@ for (i = 0; i < 256; ) { if (length >= MAX_RANGE_SIZE) return FALSE; - ranges[2 + length] = i; + ranges[length] = i; length++; bit = cbit; all = -cbit; @@ -3298,12 +4236,117 @@ if (((bit == 0) && nclass) || ((bit == 1) && !nclass)) { if (length >= MAX_RANGE_SIZE) return FALSE; - ranges[2 + length] = 256; + ranges[length] = 256; length++; } -ranges[0] = length; -return check_ranges(common, ranges, backtracks, FALSE); +if (length < 0 || length > 4) + return FALSE; + +bit = bits[0] & 0x1; +if (invert) bit ^= 0x1; + +/* No character is accepted. */ +if (length == 0 && bit == 0) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + +switch(length) + { + case 0: + /* When bit != 0, all characters are accepted. */ + return TRUE; + + case 1: + add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); + return TRUE; + + case 2: + if (ranges[0] + 1 != ranges[1]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); + add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); + } + else + add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); + return TRUE; + + case 3: + if (bit != 0) + { + add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); + if (ranges[0] + 1 != ranges[1]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); + return TRUE; + } + + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[0])); + if (ranges[1] + 1 != ranges[2]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1])); + return TRUE; + + case 4: + if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2]) + && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2] + && is_powerof2(ranges[2] - ranges[0])) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]); + if (ranges[2] + 1 != ranges[3]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]); + add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); + } + else + add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); + return TRUE; + } + + if (bit != 0) + { + i = 0; + if (ranges[0] + 1 != ranges[1]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); + i = ranges[0]; + } + else + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); + + if (ranges[2] + 1 != ranges[3]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i)); + return TRUE; + } + + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); + add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0])); + if (ranges[1] + 1 != ranges[2]) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); + return TRUE; + + default: + SLJIT_ASSERT_STOP(); + return FALSE; + } } static void check_anynewline(compiler_common *common) @@ -3481,7 +4524,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); #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) +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. */ pcre_uint32 c1, c2; @@ -3577,7 +4620,7 @@ do #endif context->length -= IN_UCHARS(1); -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED +#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16) /* Unaligned read is supported. */ if (othercasebit != 0 && othercasechar == cc) @@ -3594,27 +4637,18 @@ do #if defined COMPILE_PCRE8 if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) -#elif defined COMPILE_PCRE16 +#else if (context->ucharptr >= 2 || context->length == 0) -#elif defined COMPILE_PCRE32 - if (1 /* context->ucharptr >= 1 || context->length == 0 */) #endif { -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 if (context->length >= 4) OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#if defined COMPILE_PCRE8 else if (context->length >= 2) OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#if defined COMPILE_PCRE8 else if (context->length >= 1) OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#elif defined COMPILE_PCRE16 - else if (context->length >= 2) - OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* COMPILE_PCRE[8|16] */ -#elif defined COMPILE_PCRE32 - OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* COMPILE_PCRE[8|16|32] */ +#endif /* COMPILE_PCRE8 */ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; switch(context->ucharptr) @@ -3625,7 +4659,6 @@ do add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); break; -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 case 2 / sizeof(pcre_uchar): if (context->oc.asushort != 0) OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); @@ -3640,8 +4673,6 @@ do break; #endif -#endif /* COMPILE_PCRE[8|16] */ - default: SLJIT_ASSERT_STOP(); break; @@ -3651,8 +4682,8 @@ do #else - /* Unaligned read is unsupported. */ - if (context->length > 0) + /* Unaligned read is unsupported or in 32 bit mode. */ + if (context->length >= 1) OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; @@ -3682,20 +4713,20 @@ return cc; #define SET_TYPE_OFFSET(value) \ if ((value) != typeoffset) \ { \ - if ((value) > typeoffset) \ - OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ - else \ + if ((value) < typeoffset) \ OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \ + else \ + OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ } \ typeoffset = (value); #define SET_CHAR_OFFSET(value) \ if ((value) != charoffset) \ { \ - if ((value) > charoffset) \ - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \ + if ((value) < charoffset) \ + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \ else \ - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \ + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \ } \ charoffset = (value); @@ -3703,83 +4734,53 @@ static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, { DEFINE_COMPILER; jump_list *found = NULL; -jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks; -pcre_int32 c, charoffset; -const pcre_uint32 *other_cases; +jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks; +sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX; struct sljit_jump *jump = NULL; pcre_uchar *ccbegin; int compares, invertcmp, numberofcmps; +#if defined SUPPORT_UTF && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16) +BOOL utf = common->utf; +#endif + #ifdef SUPPORT_UCP BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; BOOL charsaved = FALSE; int typereg = TMP1, scriptreg = TMP1; -pcre_int32 typeoffset; +const pcre_uint32 *other_cases; +sljit_uw typeoffset; #endif -/* Although SUPPORT_UTF must be defined, we are - not necessary in utf mode even in 8 bit mode. */ -detect_partial_match(common, backtracks); -read_char(common); - -if ((*cc++ & XCL_MAP) != 0) +/* Scanning the necessary info. */ +cc++; +ccbegin = cc; +compares = 0; +if (cc[-1] & XCL_MAP) { - 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 - - if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list)) - { - 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_sw)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 + min = 0; 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 + cc ++; + GETCHARINCTEST(c, cc); + if (c > max) max = c; + if (c < min) min = c; #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 + cc ++; + GETCHARINCTEST(c, cc); + if (c < min) min = c; + GETCHARINCTEST(c, cc); + if (c > max) max = c; #ifdef SUPPORT_UCP needschar = TRUE; #endif @@ -3789,6 +4790,22 @@ while (*cc != XCL_END) { SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); cc++; + if (*cc == PT_CLIST) + { + other_cases = PRIV(ucd_caseless_sets) + cc[1]; + while (*other_cases != NOTACHAR) + { + if (*other_cases > max) max = *other_cases; + if (*other_cases < min) min = *other_cases; + other_cases++; + } + } + else + { + max = READ_CHAR_MAX; + min = 0; + } + switch(*cc) { case PT_ANY: @@ -3808,11 +4825,15 @@ while (*cc != XCL_END) case PT_SPACE: case PT_PXSPACE: case PT_WORD: + case PT_PXGRAPH: + case PT_PXPRINT: + case PT_PXPUNCT: needstype = TRUE; needschar = TRUE; break; case PT_CLIST: + case PT_UCNC: needschar = TRUE; break; @@ -3825,6 +4846,64 @@ while (*cc != XCL_END) #endif } +/* We are not necessary in utf mode even in 8 bit mode. */ +cc = ccbegin; +detect_partial_match(common, backtracks); +read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0); + +if ((cc[-1] & XCL_HASPROP) == 0) + { + if ((cc[-1] & XCL_MAP) != 0) + { + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); + if (!check_class_ranges(common, (const pcre_uint8 *)cc, (((const pcre_uint8 *)cc)[31] & 0x80) != 0, TRUE, &found)) + { + 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_sw)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, &found, JUMP(SLJIT_C_NOT_ZERO)); + } + + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump); + + cc += 32 / sizeof(pcre_uchar); + } + else + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min); + add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, max - min)); + } + } +else if ((cc[-1] & XCL_MAP) != 0) + { + OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); +#ifdef SUPPORT_UCP + charsaved = TRUE; +#endif + if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list)) + { +#ifdef COMPILE_PCRE8 + SLJIT_ASSERT(common->utf); +#endif + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); + + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)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)); + + JUMPHERE(jump); + } + + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); + cc += 32 / sizeof(pcre_uchar); + } + #ifdef SUPPORT_UCP /* Simple register allocation. TMP1 is preferred if possible. */ if (needstype || needsscript) @@ -3866,7 +4945,6 @@ if (needstype || needsscript) #endif /* Generating code. */ -cc = ccbegin; charoffset = 0; numberofcmps = 0; #ifdef SUPPORT_UCP @@ -3882,70 +4960,50 @@ while (*cc != XCL_END) if (*cc == XCL_SINGLE) { cc ++; -#ifdef SUPPORT_UTF - if (common->utf) - { - GETCHARINC(c, cc); - } - else -#endif - c = *cc++; + GETCHARINCTEST(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); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : 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); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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); + jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); numberofcmps = 0; } } else if (*cc == XCL_RANGE) { cc ++; -#ifdef SUPPORT_UTF - if (common->utf) - { - GETCHARINC(c, cc); - } - else -#endif - c = *cc++; + GETCHARINCTEST(c, cc); SET_CHAR_OFFSET(c); -#ifdef SUPPORT_UTF - if (common->utf) - { - GETCHARINC(c, cc); - } - else -#endif - c = *cc++; + GETCHARINCTEST(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); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : 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); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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); + jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); numberofcmps = 0; } } @@ -3994,16 +5052,15 @@ while (*cc != XCL_END) 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); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9); OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); - if (*cc == PT_SPACE) - JUMPHERE(jump); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); SET_TYPE_OFFSET(ucp_Zl); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); @@ -4012,9 +5069,9 @@ while (*cc != XCL_END) break; case PT_WORD: - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset)); OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); - /* ... fall through */ + /* Fall through. */ case PT_ALNUM: SET_TYPE_OFFSET(ucp_Ll); @@ -4060,24 +5117,102 @@ while (*cc != XCL_END) OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]); OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset)); OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); other_cases += 3; } else { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); } while (*other_cases != NOTACHAR) { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); } jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); break; + + case PT_UCNC: + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + + SET_CHAR_OFFSET(0xa0); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); + SET_CHAR_OFFSET(0); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + break; + + case PT_PXGRAPH: + /* C and Z groups are the farthest two groups. */ + SET_TYPE_OFFSET(ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER); + + jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); + + /* In case of ucp_Cf, we overwrite the result. */ + SET_CHAR_OFFSET(0x2066); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + + JUMPHERE(jump); + jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); + break; + + case PT_PXPRINT: + /* C and Z groups are the farthest two groups. */ + SET_TYPE_OFFSET(ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll); + OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL); + + jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); + + /* In case of ucp_Cf, we overwrite the result. */ + SET_CHAR_OFFSET(0x2066); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); + + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + + JUMPHERE(jump); + jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); + break; + + case PT_PXPUNCT: + SET_TYPE_OFFSET(ucp_Sc); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); + + SET_CHAR_OFFSET(0); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff); + OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); + + SET_TYPE_OFFSET(ucp_Pc); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + break; } cc += 2; } @@ -4103,12 +5238,13 @@ int length; unsigned int c, oc, bit; compare_context context; struct sljit_jump *jump[4]; +jump_list *end_list; #ifdef SUPPORT_UTF struct sljit_label *label; #ifdef SUPPORT_UCP pcre_uchar propdata[5]; #endif -#endif +#endif /* SUPPORT_UTF */ switch(type) { @@ -4133,26 +5269,27 @@ switch(type) case OP_NOT_DIGIT: case OP_DIGIT: /* Digits are usually 0-9, so it is worth to optimize them. */ - if (common->digits[0] == -2) - get_ctype_ranges(common, ctype_digit, common->digits); detect_partial_match(common, backtracks); - /* Flip the starting bit in the negative case. */ - if (type == OP_NOT_DIGIT) - common->digits[1] ^= 1; - if (!check_ranges(common, common->digits, backtracks, TRUE)) - { - 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)); - } - if (type == OP_NOT_DIGIT) - common->digits[1] ^= 1; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE)) + read_char7_type(common, type == OP_NOT_DIGIT); + else +#endif + read_char8_type(common, type == OP_NOT_DIGIT); + /* Flip the starting bit in the negative case. */ + 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); +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE)) + read_char7_type(common, type == OP_NOT_WHITESPACE); + else +#endif + read_char8_type(common, type == OP_NOT_WHITESPACE); 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; @@ -4160,26 +5297,31 @@ switch(type) case OP_NOT_WORDCHAR: case OP_WORDCHAR: detect_partial_match(common, backtracks); - read_char8_type(common); +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE)) + read_char7_type(common, type == OP_NOT_WORDCHAR); + else +#endif + read_char8_type(common, type == OP_NOT_WORDCHAR); 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); + read_char_range(common, common->nlmin, common->nlmax, TRUE); if (common->nltype == NLTYPE_FIXED && common->newline > 255) { jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + end_list = NULL; if (common->mode != JIT_PARTIAL_HARD_COMPILE) - jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); else - jump[1] = check_str_end(common); + check_str_end(common, &end_list); 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]); + set_jumps(end_list, LABEL()); JUMPHERE(jump[0]); } else @@ -4223,7 +5365,7 @@ switch(type) #ifdef SUPPORT_UCP case OP_NOTPROP: case OP_PROP: - propdata[0] = 0; + propdata[0] = XCL_HASPROP; propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; propdata[2] = cc[0]; propdata[3] = cc[1]; @@ -4235,28 +5377,29 @@ switch(type) case OP_ANYNL: detect_partial_match(common, backtracks); - read_char(common); + read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE); jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); /* We don't need to handle soft partial matching case. */ + end_list = NULL; if (common->mode != JIT_PARTIAL_HARD_COMPILE) - jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); else - jump[1] = check_str_end(common); + check_str_end(common, &end_list); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + jump[1] = 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); + jump[2] = JUMP(SLJIT_JUMP); JUMPHERE(jump[0]); check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); + set_jumps(end_list, LABEL()); 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); + read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE); 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; @@ -4264,7 +5407,7 @@ switch(type) case OP_NOT_VSPACE: case OP_VSPACE: detect_partial_match(common, backtracks); - read_char(common); + read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE); 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; @@ -4363,7 +5506,7 @@ switch(type) else { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0); - read_char(common); + read_char_range(common, common->nlmin, common->nlmax, TRUE); 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)); @@ -4411,7 +5554,7 @@ switch(type) else { skip_char_back(common); - read_char(common); + read_char_range(common, common->nlmin, common->nlmax, TRUE); check_newlinechar(common, common->nltype, backtracks, FALSE); } JUMPHERE(jump[0]); @@ -4462,7 +5605,7 @@ switch(type) } else { - peek_char(common); + peek_char(common, common->nlmax); check_newlinechar(common, common->nltype, backtracks, FALSE); } JUMPHERE(jump[0]); @@ -4486,8 +5629,8 @@ switch(type) #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) { @@ -4496,12 +5639,15 @@ switch(type) else #endif c = *cc; + if (type == OP_CHAR || !char_has_othercase(common, cc)) { + read_char_range(common, c, c, FALSE); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); return cc + length; } oc = char_othercase(common, c); + read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE); bit = c ^ oc; if (is_powerof2(bit)) { @@ -4509,11 +5655,9 @@ switch(type) 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); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); - add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); + jump[0] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); + JUMPHERE(jump[0]); return cc + length; case OP_NOT: @@ -4548,21 +5692,21 @@ switch(type) #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)) + { + read_char_range(common, c, c, TRUE); add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); + } else { oc = char_othercase(common, c); + read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE); bit = c ^ oc; if (is_powerof2(bit)) { @@ -4580,36 +5724,49 @@ switch(type) case OP_CLASS: case OP_NCLASS: detect_partial_match(common, backtracks); - read_char(common); - if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks)) + +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255; + read_char_range(common, 0, bit, type == OP_NCLASS); +#else + read_char_range(common, 0, 255, type == OP_NCLASS); +#endif + + if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks)) return cc + 32 / sizeof(pcre_uchar); -#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 +#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); + jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, bit); if (type == OP_CLASS) { add_jump(compiler, backtracks, jump[0]); jump[0] = NULL; } } -#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ +#elif !defined 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_sw)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 */ +#endif + return cc + 32 / sizeof(pcre_uchar); #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 @@ -4714,28 +5871,6 @@ if (context.length > 0) return compile_char1_matchingpath(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)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, 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_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *); static void compile_backtrackingpath(compiler_common *, struct backtrack_common *); @@ -4768,24 +5903,65 @@ static void compile_backtrackingpath(compiler_common *, struct backtrack_common #define BACKTRACK_AS(type) ((type *)backtrack) -static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) +static void compile_dnref_search(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) +{ +/* The OVECTOR offset goes to TMP2. */ +DEFINE_COMPILER; +int count = GET2(cc, 1 + IMM2_SIZE); +pcre_uchar *slot = common->name_table + GET2(cc, 1) * common->name_entry_size; +unsigned int offset; +jump_list *found = NULL; + +SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI); + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); + +count--; +while (count-- > 0) + { + offset = GET2(slot, 0) << 1; + GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); + add_jump(compiler, &found, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0)); + slot += common->name_entry_size; + } + +offset = GET2(slot, 0) << 1; +GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); +if (backtracks != NULL && !common->jscript_compat) + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0)); + +set_jumps(found, LABEL()); +} + +static void compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) { DEFINE_COMPILER; -int offset = GET2(cc, 1) << 1; +BOOL ref = (*cc == OP_REF || *cc == OP_REFI); +int offset = 0; 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 (ref) + { + offset = GET2(cc, 1) << 1; + 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))); + } +else + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); #if defined SUPPORT_UTF && defined SUPPORT_UCP if (common->utf && *cc == OP_REFI) { SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + if (ref) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + else + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + if (withchecks) jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0); @@ -4810,7 +5986,11 @@ if (common->utf && *cc == OP_REFI) 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 (ref) + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0); + else + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); + if (withchecks) jump = JUMP(SLJIT_C_ZERO); @@ -4847,14 +6027,15 @@ if (jump != NULL) else JUMPHERE(jump); } -return cc + 1 + IMM2_SIZE; } static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; +BOOL ref = (*cc == OP_REF || *cc == OP_REFI); backtrack_common *backtrack; pcre_uchar type; +int offset = 0; struct sljit_label *label; struct sljit_jump *zerolength; struct sljit_jump *jump = NULL; @@ -4864,7 +6045,13 @@ BOOL minimize; PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); +if (ref) + offset = GET2(cc, 1) << 1; +else + cc += IMM2_SIZE; type = cc[1 + IMM2_SIZE]; + +SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even); minimize = (type & 0x1) != 0; switch(type) { @@ -4902,25 +6089,52 @@ if (!minimize) if (min == 0) { allocate_stack(common, 2); + if (ref) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); 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_sw)); - zerolength = compile_ref_checks(common, ccbegin, NULL); + /* Handles both invalid and empty cases. Since the minimum repeat, + is zero the invalid case is basically the same as an empty case. */ + if (ref) + zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + else + { + compile_dnref_search(common, ccbegin, NULL); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0); + zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + } /* Restore if not zero length. */ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); } else { allocate_stack(common, 1); + if (ref) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks); + if (ref) + { + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); + zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + } + else + { + compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0); + zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + } } if (min > 1 || max > 1) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); label = LABEL(); + if (!ref) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); if (min > 1 || max > 1) @@ -4951,28 +6165,56 @@ if (!minimize) JUMPHERE(zerolength); BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); - decrease_call_count(common); + count_match(common); return cc; } -allocate_stack(common, 2); +allocate_stack(common, ref ? 2 : 3); +if (ref) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); 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); + /* Handles both invalid and empty cases. Since the minimum repeat, + is zero the invalid case is basically the same as an empty case. */ + if (ref) + zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + else + { + compile_dnref_search(common, ccbegin, NULL); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); + zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + } + /* Length is non-zero, we can match real repeats. */ 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); + { + if (ref) + { + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); + zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + } + else + { + compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); + zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + } + } BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); if (max > 0) add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); +if (!ref) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); @@ -4990,7 +6232,7 @@ if (jump != NULL) JUMPHERE(jump); JUMPHERE(zerolength); -decrease_call_count(common); +count_match(common); return cc; } @@ -5000,9 +6242,21 @@ DEFINE_COMPILER; backtrack_common *backtrack; recurse_entry *entry = common->entries; recurse_entry *prev = NULL; -int start = GET(cc, 1); +sljit_sw start = GET(cc, 1); +pcre_uchar *start_cc; +BOOL needs_control_head; PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); + +/* Inlining simple patterns. */ +if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack) + { + start_cc = common->start + start; + compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack); + BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE; + return cc + 1 + LINK_SIZE; + } + while (entry != NULL) { if (entry->start == start) @@ -5051,10 +6305,111 @@ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_ return cc + 1 + LINK_SIZE; } +static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector) +{ +const pcre_uchar *begin = arguments->begin; +int *offset_vector = arguments->offsets; +int offset_count = arguments->offset_count; +int i; + +if (PUBL(callout) == NULL) + return 0; + +callout_block->version = 2; +callout_block->callout_data = arguments->callout_data; + +/* Offsets in subject. */ +callout_block->subject_length = arguments->end - arguments->begin; +callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin; +callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin; +#if defined COMPILE_PCRE8 +callout_block->subject = (PCRE_SPTR)begin; +#elif defined COMPILE_PCRE16 +callout_block->subject = (PCRE_SPTR16)begin; +#elif defined COMPILE_PCRE32 +callout_block->subject = (PCRE_SPTR32)begin; +#endif + +/* Convert and copy the JIT offset vector to the offset_vector array. */ +callout_block->capture_top = 0; +callout_block->offset_vector = offset_vector; +for (i = 2; i < offset_count; i += 2) + { + offset_vector[i] = jit_ovector[i] - begin; + offset_vector[i + 1] = jit_ovector[i + 1] - begin; + if (jit_ovector[i] >= begin) + callout_block->capture_top = i; + } + +callout_block->capture_top = (callout_block->capture_top >> 1) + 1; +if (offset_count > 0) + offset_vector[0] = -1; +if (offset_count > 1) + offset_vector[1] = -1; +return (*PUBL(callout))(callout_block); +} + +/* Aligning to 8 byte. */ +#define CALLOUT_ARG_SIZE \ + (((int)sizeof(PUBL(callout_block)) + 7) & ~7) + +#define CALLOUT_ARG_OFFSET(arg) \ + (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg)) + +static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; + +PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); + +allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); + +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +SLJIT_ASSERT(common->capture_last_ptr != 0); +OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]); +OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0); + +/* These pointer sized fields temporarly stores internal variables. */ +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0); + +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr)); +OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2)); +OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE)); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0); + +/* Needed to save important temporary registers. */ +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); +OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE); +GET_LOCAL_BASE(SLJIT_SCRATCH_REG3, 0, OVECTOR_START); +sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout)); +OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); +free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); + +/* Check return value. */ +OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); +add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER)); +if (common->forced_quit_label == NULL) + add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS)); +else + JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label); +return cc + 2 + 2 * LINK_SIZE; +} + +#undef CALLOUT_ARG_SIZE +#undef CALLOUT_ARG_OFFSET + static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) { DEFINE_COMPILER; int framesize; +int extrasize; +BOOL needs_control_head; int private_data_ptr; backtrack_common altbacktrack; pcre_uchar *ccbegin; @@ -5064,13 +6419,20 @@ jump_list *tmp = NULL; jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; jump_list **found; /* Saving previous accept variables. */ -struct sljit_label *save_quitlabel = common->quitlabel; -struct sljit_label *save_acceptlabel = common->acceptlabel; +BOOL save_local_exit = common->local_exit; +BOOL save_positive_assert = common->positive_assert; +then_trap_backtrack *save_then_trap = common->then_trap; +struct sljit_label *save_quit_label = common->quit_label; +struct sljit_label *save_accept_label = common->accept_label; jump_list *save_quit = common->quit; +jump_list *save_positive_assert_quit = common->positive_assert_quit; jump_list *save_accept = common->accept; struct sljit_jump *jump; struct sljit_jump *brajump = NULL; +/* Assert captures then. */ +common->then_trap = NULL; + if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) { SLJIT_ASSERT(!conditional); @@ -5079,7 +6441,7 @@ if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) } private_data_ptr = PRIVATE_DATA(cc); SLJIT_ASSERT(private_data_ptr != 0); -framesize = get_framesize(common, cc, FALSE); +framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); backtrack->framesize = framesize; backtrack->private_data_ptr = private_data_ptr; opcode = *cc; @@ -5098,27 +6460,56 @@ if (bra == OP_BRAMINZERO) if (framesize < 0) { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); - allocate_stack(common, 1); + extrasize = needs_control_head ? 2 : 1; + if (framesize == no_frame) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); + allocate_stack(common, extrasize); + if (needs_control_head) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + if (needs_control_head) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + } } else { - allocate_stack(common, framesize + 2); + extrasize = needs_control_head ? 3 : 2; + allocate_stack(common, framesize + extrasize); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1)); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); + if (needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); 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); + if (needs_control_head) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0); + } + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE); } memset(&altbacktrack, 0, sizeof(backtrack_common)); -common->quitlabel = NULL; -common->quit = NULL; +if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + /* Negative assert is stronger than positive assert. */ + common->local_exit = TRUE; + common->quit_label = NULL; + common->quit = NULL; + common->positive_assert = FALSE; + } +else + common->positive_assert = TRUE; +common->positive_assert_quit = NULL; + while (1) { - common->acceptlabel = NULL; + common->accept_label = NULL; common->accept = NULL; altbacktrack.top = NULL; altbacktrack.topbacktracks = NULL; @@ -5130,45 +6521,64 @@ while (1) compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { - common->quitlabel = save_quitlabel; - common->acceptlabel = save_acceptlabel; - common->quit = save_quit; + if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + common->local_exit = save_local_exit; + common->quit_label = save_quit_label; + common->quit = save_quit; + } + common->positive_assert = save_positive_assert; + common->then_trap = save_then_trap; + common->accept_label = save_accept_label; + common->positive_assert_quit = save_positive_assert_quit; common->accept = save_accept; return NULL; } - common->acceptlabel = LABEL(); + common->accept_label = LABEL(); if (common->accept != NULL) - set_jumps(common->accept, common->acceptlabel); + set_jumps(common->accept, common->accept_label); /* Reset stack. */ if (framesize < 0) - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - else { + { + if (framesize == no_frame) + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + else + free_stack(common, extrasize); + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); + } + else + { if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional) { /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); } else { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw)); 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); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0); else if (bra == OP_BRAZERO) { if (framesize < 0) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); else { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); } OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); @@ -5185,9 +6595,16 @@ while (1) compile_backtrackingpath(common, altbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { - common->quitlabel = save_quitlabel; - common->acceptlabel = save_acceptlabel; - common->quit = save_quit; + if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + common->local_exit = save_local_exit; + common->quit_label = save_quit_label; + common->quit = save_quit; + } + common->positive_assert = save_positive_assert; + common->then_trap = save_then_trap; + common->accept_label = save_accept_label; + common->positive_assert_quit = save_positive_assert_quit; common->accept = save_accept; return NULL; } @@ -5199,9 +6616,33 @@ while (1) ccbegin = cc; cc += GET(cc, 1); } + +if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + SLJIT_ASSERT(common->positive_assert_quit == NULL); + /* Makes the check less complicated below. */ + common->positive_assert_quit = common->quit; + } + /* None of them matched. */ -if (common->quit != NULL) - set_jumps(common->quit, LABEL()); +if (common->positive_assert_quit != NULL) + { + jump = JUMP(SLJIT_JUMP); + set_jumps(common->positive_assert_quit, LABEL()); + SLJIT_ASSERT(framesize != no_stack); + if (framesize < 0) + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw)); + else + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); + } + JUMPHERE(jump); + } + +if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1)); if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) { @@ -5212,22 +6653,26 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) 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); + if (extrasize == 2) + free_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } else - free_stack(common, framesize + 2); + free_stack(common, extrasize); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1)); + /* The topmost item should be 0. */ + if (bra == OP_BRAZERO) + { + free_stack(common, framesize + extrasize - 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else + free_stack(common, framesize + extrasize); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); } jump = JUMP(SLJIT_JUMP); @@ -5239,10 +6684,14 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) 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); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); /* 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_sw)); + if (extrasize == 2) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } else if (bra == OP_BRAMINZERO) { OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); @@ -5255,21 +6704,30 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) { /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw)); } else { /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw)); - 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 (extrasize == 2) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (bra == OP_BRAMINZERO) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); + } } } if (bra == OP_BRAZERO) { backtrack->matchingpath = LABEL(); - sljit_set_label(jump, backtrack->matchingpath); + SET_LABEL(jump, backtrack->matchingpath); } else if (bra == OP_BRAMINZERO) { @@ -5291,22 +6749,26 @@ else { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); if (bra != OP_BRA) + { + if (extrasize == 2) + free_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } else - free_stack(common, 1); + free_stack(common, extrasize); } else { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1)); /* The topmost item should be 0. */ if (bra != OP_BRA) { - free_stack(common, framesize + 1); + free_stack(common, framesize + extrasize - 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } else - free_stack(common, framesize + 2); + free_stack(common, framesize + extrasize); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); } @@ -5326,121 +6788,89 @@ else } } -common->quitlabel = save_quitlabel; -common->acceptlabel = save_acceptlabel; -common->quit = save_quit; +if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + common->local_exit = save_local_exit; + common->quit_label = save_quit_label; + common->quit = save_quit; + } +common->positive_assert = save_positive_assert; +common->then_trap = save_then_trap; +common->accept_label = save_accept_label; +common->positive_assert_quit = save_positive_assert_quit; common->accept = save_accept; return cc + 1 + LINK_SIZE; } -static sljit_sw SLJIT_CALL do_searchovector(sljit_uw refno, sljit_sw* locals, pcre_uchar *name_table) +static SLJIT_INLINE void match_once_common(compiler_common *common, pcre_uchar ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head) { -int condition = FALSE; -pcre_uchar *slotA = name_table; -pcre_uchar *slotB; -sljit_sw name_count = locals[LOCALS0 / sizeof(sljit_sw)]; -sljit_sw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)]; -sljit_sw no_capture; -int i; +DEFINE_COMPILER; +int stacksize; -locals += refno & 0xff; -refno >>= 8; -no_capture = locals[1]; - -for (i = 0; i < name_count; i++) +if (framesize < 0) { - 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) + if (framesize == no_frame) + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + else { - 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; + stacksize = needs_control_head ? 1 : 0; + if (ket != OP_KET || has_alternatives) + stacksize++; + free_stack(common, stacksize); } - /* Scan up for duplicates */ - if (!condition) + if (needs_control_head) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0); + + /* 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) { - 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; - } + /* Move the STR_PTR to the private_data_ptr. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); } } -return condition; +else + { + stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1; + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw)); + if (needs_control_head) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0); + + 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)); + } + } +if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0); } -static sljit_sw SLJIT_CALL do_searchgroups(sljit_uw recno, sljit_uw* locals, pcre_uchar *name_table) +static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr) { -int condition = FALSE; -pcre_uchar *slotA = name_table; -pcre_uchar *slotB; -sljit_uw name_count = locals[LOCALS0 / sizeof(sljit_sw)]; -sljit_uw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)]; -sljit_uw group_num = locals[POSSESSIVE0 / sizeof(sljit_sw)]; -sljit_uw i; +DEFINE_COMPILER; -for (i = 0; i < name_count; i++) +if (common->capture_last_ptr != 0) { - if (GET2(slotA, 0) == recno) break; - slotA += name_entry_size; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); + stacksize++; } - -if (i < name_count) +if (common->optimized_cbracket[offset >> 1] == 0) { - /* 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; - } - } + 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(stacksize), TMP1, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0); + 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); + stacksize += 2; } -return condition; +return stacksize; } /* @@ -5504,17 +6934,21 @@ backtrack_common *backtrack; pcre_uchar opcode; int private_data_ptr = 0; int offset = 0; -int stacksize; +int i, stacksize; +int repeat_ptr = 0, repeat_length = 0; +int repeat_type = 0, repeat_count = 0; pcre_uchar *ccbegin; pcre_uchar *matchingpath; +pcre_uchar *slot; pcre_uchar bra = OP_BRA; pcre_uchar ket; assert_backtrack *assert; BOOL has_alternatives; +BOOL needs_control_head = FALSE; struct sljit_jump *jump; struct sljit_jump *skip; -struct sljit_label *rmaxlabel = NULL; -struct sljit_jump *braminzerojump = NULL; +struct sljit_label *rmax_label = NULL; +struct sljit_jump *braminzero = NULL; PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); @@ -5527,35 +6961,36 @@ if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) opcode = *cc; ccbegin = cc; -matchingpath = ccbegin + 1 + LINK_SIZE; +matchingpath = bracketend(cc) - 1 - LINK_SIZE; +ket = *matchingpath; +if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0) + { + repeat_ptr = PRIVATE_DATA(matchingpath); + repeat_length = PRIVATE_DATA(matchingpath + 1); + repeat_type = PRIVATE_DATA(matchingpath + 2); + repeat_count = PRIVATE_DATA(matchingpath + 3); + SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0); + if (repeat_type == OP_UPTO) + ket = OP_KETRMAX; + if (repeat_type == OP_MINUPTO) + ket = OP_KETRMIN; + } if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) { /* Drop this bracket_backtrack. */ parent->top = backtrack->prev; - return bracketend(cc); + return matchingpath + 1 + LINK_SIZE + repeat_length; } -ket = *(bracketend(cc) - 1 - LINK_SIZE); +matchingpath = ccbegin + 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 = (*matchingpath == OP_RREF) ? FALSE : TRUE; - if (*matchingpath == OP_NRREF) - { - stacksize = GET2(matchingpath, 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 != (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); - } - } +if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND)) + has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) ? FALSE : TRUE; if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) opcode = OP_SCOND; @@ -5586,12 +7021,12 @@ else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) SLJIT_ASSERT(private_data_ptr != 0); BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; if (opcode == OP_ONCE) - BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE); + BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head); } /* Instructions before the first alternative. */ stacksize = 0; -if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) +if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) stacksize++; if (bra == OP_BRAZERO) stacksize++; @@ -5600,7 +7035,7 @@ if (stacksize > 0) allocate_stack(common, stacksize); stacksize = 0; -if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) +if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); stacksize++; @@ -5616,7 +7051,7 @@ if (bra == OP_BRAMINZERO) if (ket != OP_KETRMIN) { free_stack(common, 1); - braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); } else { @@ -5631,13 +7066,13 @@ if (bra == OP_BRAMINZERO) if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) { /* When we come from outside, private_data_ptr contains the previous STR_PTR. */ - braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); } else { /* Except when the whole stack frame must be saved. */ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); + braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); } JUMPHERE(skip); } @@ -5650,77 +7085,106 @@ if (bra == OP_BRAMINZERO) } } +if (repeat_type != 0) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, repeat_count); + if (repeat_type == OP_EXACT) + rmax_label = LABEL(); + } + if (ket == OP_KETRMIN) BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); if (ket == OP_KETRMAX) { - rmaxlabel = LABEL(); - if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA) - BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel; + rmax_label = LABEL(); + if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0) + BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label; } /* Handling capturing brackets and alternatives. */ if (opcode == OP_ONCE) { + stacksize = 0; + if (needs_control_head) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); + stacksize++; + } + if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) { - /* Neither capturing brackets nor recursions are not found in the block. */ + /* Neither capturing brackets nor recursions are found in the block. */ if (ket == OP_KETRMIN) { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - 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), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); - } - else if (ket == OP_KETRMAX || has_alternatives) - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + stacksize += 2; + if (!needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); } else - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); + { + if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); + if (ket == OP_KETRMAX || has_alternatives) + stacksize++; + } + + if (stacksize > 0) + allocate_stack(common, stacksize); + + stacksize = 0; + if (needs_control_head) + { + stacksize++; + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } + + if (ket == OP_KETRMIN) + { + if (needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame) + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0); + } + else if (ket == OP_KETRMAX || has_alternatives) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); } else { - if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) + if (ket != OP_KET || has_alternatives) + stacksize++; + + stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1; + allocate_stack(common, stacksize); + + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw)); + + stacksize = needs_control_head ? 1 : 0; + if (ket != OP_KET || has_alternatives) { - allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - 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(STACK_TOP), STACK(stacksize), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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); + stacksize++; + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); } else { - allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - 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), private_data_ptr, 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); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); } + init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE); } } else if (opcode == OP_CBRA || opcode == OP_SCBRA) { /* Saving the previous values. */ - if (common->optimized_cbracket[offset >> 1] == 0) - { - 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, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); - } - else + if (common->optimized_cbracket[offset >> 1] != 0) { SLJIT_ASSERT(private_data_ptr == OVECTOR(offset)); allocate_stack(common, 2); @@ -5730,6 +7194,13 @@ else if (opcode == OP_CBRA || opcode == OP_SCBRA) 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, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } } else if (opcode == OP_SBRA || opcode == OP_SCOND) { @@ -5756,46 +7227,72 @@ if (opcode == OP_COND || opcode == OP_SCOND) CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); matchingpath += 1 + IMM2_SIZE; } - else if (*matchingpath == OP_NCREF) + else if (*matchingpath == OP_DNCREF) { SLJIT_ASSERT(has_alternatives); - stacksize = GET2(matchingpath, 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_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw))); - GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0); - OP1(SLJIT_MOV, SLJIT_SCRATCH_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_SCRATCH_REG1, 0, SLJIT_IMM, 0)); - - JUMPHERE(jump); - matchingpath += 1 + IMM2_SIZE; + i = GET2(matchingpath, 1 + IMM2_SIZE); + slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0); + slot += common->name_entry_size; + i--; + while (i-- > 0) + { + OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0); + OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0); + slot += common->name_entry_size; + } + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_C_ZERO)); + matchingpath += 1 + 2 * IMM2_SIZE; } - else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF) + else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) { /* Never has other case. */ BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; + SLJIT_ASSERT(!has_alternatives); - stacksize = GET2(matchingpath, 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 == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); - - if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL) + if (*matchingpath == OP_RREF) { - SLJIT_ASSERT(!has_alternatives); + stacksize = GET2(matchingpath, 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 == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + if (stacksize != 0) matchingpath += 1 + IMM2_SIZE; + } + else + { + if (common->currententry == NULL || common->currententry->start == 0) + stacksize = 0; else + { + stacksize = GET2(matchingpath, 1 + IMM2_SIZE); + slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; + i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + while (stacksize > 0) + { + if ((int)GET2(slot, 0) == i) + break; + slot += common->name_entry_size; + stacksize--; + } + } + + if (stacksize != 0) + matchingpath += 1 + 2 * IMM2_SIZE; + } + + /* The stacksize == 0 is a common "else" case. */ + if (stacksize == 0) { if (*cc == OP_ALT) { @@ -5805,24 +7302,6 @@ if (opcode == OP_COND || opcode == OP_SCOND) else matchingpath = cc; } - } - else - { - SLJIT_ASSERT(has_alternatives); - - stacksize = GET2(matchingpath, 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_SCRATCH_REG1, 0, SLJIT_IMM, stacksize); - GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0); - OP1(SLJIT_MOV, SLJIT_SCRATCH_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_SCRATCH_REG1, 0, SLJIT_IMM, 0)); - matchingpath += 1 + IMM2_SIZE; - } } else { @@ -5843,34 +7322,24 @@ 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), private_data_ptr); - /* 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 private_data_ptr. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_sw)); - 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)); - } - } - } + match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); stacksize = 0; +if (repeat_type == OP_MINUPTO) + { + /* We need to preserve the counter. TMP2 will be used below. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr); + stacksize++; + } if (ket != OP_KET || bra != OP_BRA) stacksize++; +if (offset != 0) + { + if (common->capture_last_ptr != 0) + stacksize++; + if (common->optimized_cbracket[offset >> 1] == 0) + stacksize += 2; + } if (has_alternatives && opcode != OP_ONCE) stacksize++; @@ -5878,17 +7347,25 @@ if (stacksize > 0) allocate_stack(common, stacksize); stacksize = 0; -if (ket != OP_KET) +if (repeat_type == OP_MINUPTO) { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + /* TMP2 was set above. */ + OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1); stacksize++; } -else if (bra != OP_BRA) + +if (ket != OP_KET || bra != OP_BRA) { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + 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 (offset != 0) + stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); + if (has_alternatives) { if (opcode != OP_ONCE) @@ -5898,36 +7375,58 @@ if (has_alternatives) } /* Must be after the matchingpath label. */ -if (offset != 0) +if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0) { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0)); 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 (repeat_type != 0) + { + if (has_alternatives) + BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, rmax_label); + /* Drop STR_PTR for greedy plus quantifier. */ + if (opcode != OP_ONCE) + free_stack(common, 1); + } + else if (opcode == OP_ONCE || opcode >= OP_SBRA) { if (has_alternatives) BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); /* Checking zero-length iteration. */ if (opcode != OP_ONCE) { - CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel); + CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmax_label); /* 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); + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label); } else - JUMPTO(SLJIT_JUMP, rmaxlabel); + JUMPTO(SLJIT_JUMP, rmax_label); BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); } +if (repeat_type == OP_EXACT) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, rmax_label); + } +else if (repeat_type == OP_UPTO) + { + /* We need to preserve the counter. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } + if (bra == OP_BRAZERO) BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL(); @@ -5935,9 +7434,9 @@ if (bra == OP_BRAMINZERO) { /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath); - if (braminzerojump != NULL) + if (braminzero != NULL) { - JUMPHERE(braminzerojump); + JUMPHERE(braminzero); /* 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. */ @@ -5953,13 +7452,17 @@ if (bra == OP_BRAMINZERO) } if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) - decrease_call_count(common); + count_match(common); /* Skip the other alternatives. */ while (*cc == OP_ALT) cc += GET(cc, 1); cc += 1 + LINK_SIZE; -return cc; + +/* Temporarily encoding the needs_control_head in framesize. */ +if (opcode == OP_ONCE) + BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0); +return cc + repeat_length; } static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) @@ -5969,12 +7472,13 @@ backtrack_common *backtrack; pcre_uchar opcode; int private_data_ptr; int cbraprivptr = 0; +BOOL needs_control_head; int framesize; int stacksize; int offset = 0; BOOL zero = FALSE; pcre_uchar *ccbegin = NULL; -int stack; +int stack; /* Also contains the offset of control head. */ struct sljit_label *loop = NULL; struct jump_list *emptymatch = NULL; @@ -6012,59 +7516,104 @@ switch(opcode) break; } -framesize = get_framesize(common, cc, FALSE); +framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; if (framesize < 0) { - stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1; + if (offset != 0) + { + stacksize = 2; + if (common->capture_last_ptr != 0) + stacksize++; + } + else + stacksize = 1; + + if (needs_control_head) + stacksize++; if (!zero) stacksize++; + BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; allocate_stack(common, stacksize); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); + if (framesize == no_frame) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); - if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + stack = 0; + if (offset != 0) { + stack = 2; 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); + if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + if (needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); + if (common->capture_last_ptr != 0) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); + stack = 3; + } } else + { + if (needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + stack = 1; + } + if (needs_control_head) + stack++; if (!zero) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1); + if (needs_control_head) + { + stack--; + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0); + } } else { stacksize = framesize + 1; if (!zero) stacksize++; - if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) + if (needs_control_head) + stacksize++; + if (offset == 0) stacksize++; BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; - allocate_stack(common, stacksize); + allocate_stack(common, stacksize); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); + if (needs_control_head) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); + stack = 0; if (!zero) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1); + stack = 1; + } + if (needs_control_head) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0); stack++; } - if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) + if (offset == 0) { 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); + init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE); + stack -= 1 + (offset == 0); } -if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) +if (offset != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); loop = LABEL(); @@ -6080,13 +7629,16 @@ while (*cc != OP_KETRPOS) if (framesize < 0) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + if (framesize == no_frame) + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + if (offset != 0) { 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); + if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); } else @@ -6104,12 +7656,14 @@ while (*cc != OP_KETRPOS) } else { - if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + if (offset != 0) { OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw)); 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); + if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); } else @@ -6132,6 +7686,10 @@ while (*cc != OP_KETRPOS) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } } + + if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); + JUMPTO(SLJIT_JUMP, loop); flush_stubs(common); @@ -6142,14 +7700,14 @@ while (*cc != OP_KETRPOS) if (framesize < 0) { - if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + if (offset != 0) 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) + if (offset != 0) { /* Last alternative. */ if (*cc == OP_KETRPOS) @@ -6168,6 +7726,8 @@ while (*cc != OP_KETRPOS) ccbegin = cc + 1 + LINK_SIZE; } +/* We don't have to restore the control head in case of a failed match. */ + backtrack->topbacktracks = NULL; if (!zero) { @@ -6179,11 +7739,11 @@ if (!zero) /* None of them matched. */ set_jumps(emptymatch, LABEL()); -decrease_call_count(common); +count_match(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) +static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *max, int *min, pcre_uchar **end) { int class_len; @@ -6219,7 +7779,7 @@ else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) } else { - SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS); + SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS); *type = *opcode; cc++; class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0); @@ -6230,18 +7790,24 @@ else if (end != NULL) *end = cc + class_len; } + else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY) + { + *opcode -= OP_CRPOSSTAR - OP_POSSTAR; + 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); + SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE); + *max = GET2(cc, (class_len + IMM2_SIZE)); + *min = GET2(cc, class_len); - if (*arg2 == 0) + if (*min == 0) { - SLJIT_ASSERT(*arg1 != 0); - *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO; + SLJIT_ASSERT(*max != 0); + *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : (*opcode == OP_CRMINRANGE ? OP_MINUPTO : OP_POSUPTO); } - if (*arg1 == *arg2) + if (*max == *min) *opcode = OP_EXACT; if (end != NULL) @@ -6252,7 +7818,7 @@ else if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO) { - *arg1 = GET2(cc, 0); + *max = GET2(cc, 0); cc += IMM2_SIZE; } @@ -6281,7 +7847,7 @@ DEFINE_COMPILER; backtrack_common *backtrack; pcre_uchar opcode; pcre_uchar type; -int arg1 = -1, arg2 = -1; +int max = -1, min = -1; pcre_uchar* end; jump_list *nomatch = NULL; struct sljit_jump *jump = NULL; @@ -6294,9 +7860,9 @@ int tmp_base, tmp_offset; PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); -cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end); +cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, &end); -switch (type) +switch(type) { case OP_NOT_DIGIT: case OP_DIGIT: @@ -6365,10 +7931,10 @@ switch(opcode) { 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); + if (opcode == OP_CRRANGE && min > 0) + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label); + if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0)) + jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); } @@ -6395,7 +7961,7 @@ switch(opcode) OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); if (opcode <= OP_PLUS) JUMPTO(SLJIT_JUMP, label); - else if (opcode == OP_CRRANGE && arg1 == 0) + else if (opcode == OP_CRRANGE && max == 0) { OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1); JUMPTO(SLJIT_JUMP, label); @@ -6405,11 +7971,11 @@ switch(opcode) OP1(SLJIT_MOV, TMP1, 0, base, offset1); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, base, offset1, TMP1, 0); - CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 1, label); } set_jumps(nomatch, LABEL()); if (opcode == OP_CRRANGE) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1)); + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, min + 1)); OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); } BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); @@ -6447,7 +8013,7 @@ switch(opcode) break; case OP_EXACT: - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1); + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); label = LABEL(); compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); @@ -6460,7 +8026,7 @@ switch(opcode) if (opcode == OP_POSPLUS) compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); if (opcode == OP_POSUPTO) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, max); OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); label = LABEL(); compile_char1_matchingpath(common, type, cc, &nomatch); @@ -6484,12 +8050,40 @@ switch(opcode) OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); break; + case OP_CRPOSRANGE: + /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */ + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, label); + + if (max != 0) + { + SLJIT_ASSERT(max - min > 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, max - min); + } + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + if (max == 0) + JUMPTO(SLJIT_JUMP, label); + else + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, label); + } + set_jumps(nomatch, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); + break; + default: SLJIT_ASSERT_STOP(); break; } -decrease_call_count(common); +count_match(common); return end; } @@ -6498,7 +8092,7 @@ static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common DEFINE_COMPILER; backtrack_common *backtrack; -PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); +PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); if (*cc == OP_FAIL) { @@ -6506,33 +8100,33 @@ if (*cc == OP_FAIL) return cc + 1; } -if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL) +if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty) { /* No need to check notempty conditions. */ - if (common->acceptlabel == NULL) + if (common->accept_label == NULL) add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); else - JUMPTO(SLJIT_JUMP, common->acceptlabel); + JUMPTO(SLJIT_JUMP, common->accept_label); return cc + 1; } -if (common->acceptlabel == NULL) +if (common->accept_label == 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); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->accept_label); 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) +if (common->accept_label == 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); + CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); -if (common->acceptlabel == NULL) +if (common->accept_label == 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); + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label); add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); return cc + 1; } @@ -6556,10 +8150,86 @@ if (!optimized_cbracket) return cc + 1 + IMM2_SIZE; } +static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +pcre_uchar opcode = *cc; +pcre_uchar *ccend = cc + 1; + +if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG) + ccend += 2 + cc[1]; + +PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); + +if (opcode == OP_SKIP) + { + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + return ccend; + } + +if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(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); + } + +return ccend; +} + +static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP }; + +static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +BOOL needs_control_head; +int size; + +PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); +common->then_trap = BACKTRACK_AS(then_trap_backtrack); +BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; +BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start); +BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head); + +size = BACKTRACK_AS(then_trap_backtrack)->framesize; +size = 3 + (size < 0 ? 0 : size); + +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); +allocate_stack(common, size); +if (size > 3) + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw)); +else + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0); + +size = BACKTRACK_AS(then_trap_backtrack)->framesize; +if (size >= 0) + init_frame(common, cc, ccend, size - 1, 0, FALSE); +} + static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; +BOOL has_then_trap = FALSE; +then_trap_backtrack *save_then_trap = NULL; + +SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS)); + +if (common->has_then && common->then_offsets[cc - common->start] != 0) + { + SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0); + has_then_trap = TRUE; + save_then_trap = common->then_trap; + /* Tail item on backtrack. */ + compile_then_trap_matchingpath(common, cc, ccend, parent); + } while (cc < ccend) { @@ -6685,7 +8355,7 @@ while (cc < ccend) case OP_CLASS: case OP_NCLASS: - if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE) + if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE) cc = compile_iterator_matchingpath(common, cc, parent); else cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); @@ -6693,7 +8363,7 @@ while (cc < ccend) #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 case OP_XCLASS: - if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE) + if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) cc = compile_iterator_matchingpath(common, cc, parent); else cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); @@ -6702,16 +8372,35 @@ while (cc < ccend) case OP_REF: case OP_REFI: - if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE) + if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE) cc = compile_ref_iterator_matchingpath(common, cc, parent); else - cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + { + compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + cc += 1 + IMM2_SIZE; + } + break; + + case OP_DNREF: + case OP_DNREFI: + if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE) + cc = compile_ref_iterator_matchingpath(common, cc, parent); + else + { + compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + cc += 1 + 2 * IMM2_SIZE; + } break; case OP_RECURSE: cc = compile_recurse_matchingpath(common, cc, parent); break; + case OP_CALLOUT: + cc = compile_callout_matchingpath(common, cc, parent); + break; + case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: @@ -6736,7 +8425,7 @@ while (cc < ccend) } BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); if (cc[1] > OP_ASSERTBACK_NOT) - decrease_call_count(common); + count_match(common); break; case OP_ONCE: @@ -6772,18 +8461,32 @@ while (cc < ccend) 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); + allocate_stack(common, common->has_skip_arg ? 5 : 1); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(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); + if (common->has_skip_arg) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + } cc += 1 + 2 + cc[1]; break; + case OP_PRUNE: + case OP_PRUNE_ARG: + case OP_SKIP: + case OP_SKIP_ARG: + case OP_THEN: + case OP_THEN_ARG: case OP_COMMIT: - PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); - cc += 1; + cc = compile_control_verb_matchingpath(common, cc, parent); break; case OP_FAIL: @@ -6807,6 +8510,15 @@ while (cc < ccend) if (cc == NULL) return; } + +if (has_then_trap) + { + /* Head item on backtrack. */ + PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); + BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; + BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap; + common->then_trap = save_then_trap; + } SLJIT_ASSERT(cc == ccend); } @@ -6831,7 +8543,7 @@ DEFINE_COMPILER; pcre_uchar *cc = current->cc; pcre_uchar opcode; pcre_uchar type; -int arg1 = -1, arg2 = -1; +int max = -1, min = -1; struct sljit_label *label = NULL; struct sljit_jump *jump = NULL; jump_list *jumplist = NULL; @@ -6840,7 +8552,7 @@ int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LO int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); -cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL); +cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, NULL); switch(opcode) { @@ -6859,7 +8571,7 @@ switch(opcode) else { if (opcode == OP_UPTO) - arg2 = 0; + min = 0; if (opcode <= OP_PLUS) { OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); @@ -6869,7 +8581,7 @@ switch(opcode) { OP1(SLJIT_MOV, TMP1, 0, base, offset1); OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1); + jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, min + 1); OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1); } skip_char_back(common); @@ -6914,12 +8626,12 @@ switch(opcode) OP1(SLJIT_MOV, base, offset1, TMP1, 0); if (opcode == OP_CRMINRANGE) - CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min + 1, label); - if (opcode == OP_CRMINRANGE && arg1 == 0) + if (opcode == OP_CRMINRANGE && max == 0) JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); else - CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 2, CURRENT_AS(iterator_backtrack)->matchingpath); set_jumps(jumplist, LABEL()); if (private_data_ptr == 0) @@ -6954,6 +8666,7 @@ switch(opcode) case OP_EXACT: case OP_POSPLUS: + case OP_CRPOSRANGE: set_jumps(current->topbacktracks, LABEL()); break; @@ -6968,15 +8681,18 @@ switch(opcode) } } -static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; pcre_uchar *cc = current->cc; +BOOL ref = (*cc == OP_REF || *cc == OP_REFI); pcre_uchar type; -type = cc[1 + IMM2_SIZE]; +type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE]; + if ((type & 0x1) == 0) { + /* Maximize case. */ set_jumps(current->topbacktracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); @@ -6987,14 +8703,18 @@ if ((type & 0x1) == 0) 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)->matchingpath); set_jumps(current->topbacktracks, LABEL()); -free_stack(common, 2); +free_stack(common, ref ? 2 : 3); } -static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; +if (CURRENT_AS(recurse_backtrack)->inlined_pattern) + compile_backtrackingpath(common, current->top); set_jumps(current->topbacktracks, LABEL()); +if (CURRENT_AS(recurse_backtrack)->inlined_pattern) + return; if (common->has_set_som && common->mark_ptr != 0) { @@ -7082,24 +8802,25 @@ if (bra == OP_BRAZERO) static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; -int opcode; +int opcode, stacksize, alt_count, alt_max; int offset = 0; int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr; -int stacksize; -int count; +int repeat_ptr = 0, repeat_type = 0, repeat_count = 0; 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; +BOOL needs_control_head = FALSE; struct sljit_jump *brazero = NULL; +struct sljit_jump *alt1 = NULL; +struct sljit_jump *alt2 = NULL; struct sljit_jump *once = NULL; struct sljit_jump *cond = NULL; -struct sljit_label *rminlabel = NULL; +struct sljit_label *rmin_label = NULL; +struct sljit_label *exact_label = NULL; if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) { @@ -7108,8 +8829,20 @@ if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) } opcode = *cc; +ccbegin = bracketend(cc) - 1 - LINK_SIZE; +ket = *ccbegin; +if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0) + { + repeat_ptr = PRIVATE_DATA(ccbegin); + repeat_type = PRIVATE_DATA(ccbegin + 2); + repeat_count = PRIVATE_DATA(ccbegin + 3); + SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0); + if (repeat_type == OP_UPTO) + ket = OP_KETRMAX; + if (repeat_type == OP_MINUPTO) + ket = OP_KETRMIN; + } 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)) @@ -7121,6 +8854,26 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) opcode = OP_ONCE; +alt_max = has_alternatives ? no_alternatives(ccbegin) : 0; + +/* Decoding the needs_control_head in framesize. */ +if (opcode == OP_ONCE) + { + needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0; + CURRENT_AS(bracket_backtrack)->u.framesize >>= 1; + } + +if (ket != OP_KET && repeat_type != 0) + { + /* TMP1 is used in OP_KETRMIN below. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + if (repeat_type == OP_UPTO) + OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0, SLJIT_IMM, 1); + else + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0); + } + if (ket == OP_KETRMAX) { if (bra == OP_BRAZERO) @@ -7135,7 +8888,15 @@ 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) + if (repeat_type != 0) + { + /* TMP1 was set a few lines above. */ + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + /* Drop STR_PTR for non-greedy plus quantifier. */ + if (opcode != OP_ONCE) + free_stack(common, 1); + } + else if (opcode >= OP_SBRA || opcode == OP_ONCE) { /* Checking zero-length iteration. */ if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) @@ -7145,13 +8906,16 @@ else if (ket == OP_KETRMIN) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath); } + /* Drop STR_PTR for non-greedy plus quantifier. */ if (opcode != OP_ONCE) free_stack(common, 1); } else JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); } - rminlabel = LABEL(); + rmin_label = LABEL(); + if (repeat_type != 0) + OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1); } else if (bra == OP_BRAZERO) { @@ -7159,6 +8923,34 @@ else if (bra == OP_BRAZERO) free_stack(common, 1); brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); } +else if (repeat_type == OP_EXACT) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1); + exact_label = LABEL(); + } + +if (offset != 0) + { + if (common->capture_last_ptr != 0) + { + SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0); + 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), common->capture_last_ptr, TMP1, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); + free_stack(common, 3); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0); + } + else if (common->optimized_cbracket[offset >> 1] == 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + free_stack(common, 2); + 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); + } + } if (SLJIT_UNLIKELY(opcode == OP_ONCE)) { @@ -7177,44 +8969,27 @@ else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND) 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); + alt_max = 2; + alt1 = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); } } -else if (*cc == OP_ALT) +else if (has_alternatives) { - /* 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 + + if (alt_max > 4) { - /* 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); + /* Table jump if alt_max is greater than 4. */ + sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)common->read_only_data_ptr); + add_label_addr(common); + } + else + { + if (alt_max == 4) + alt2 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); + alt1 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); } - while (*cc == OP_ALT); - - cc = ccbegin + GET(ccbegin, 1); } COMPILE_BACKTRACKINGPATH(current->top); @@ -7249,73 +9024,69 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) if (has_alternatives) { - count = 1; + alt_count = sizeof(sljit_uw); do { current->top = NULL; current->topbacktracks = NULL; current->nextbacktracks = NULL; + /* Conditional blocks always have an additional alternative, even if it is empty. */ if (*cc == OP_ALT) { ccprev = cc + 1 + LINK_SIZE; cc += GET(cc, 1); if (opcode != OP_COND && opcode != OP_SCOND) { - if (private_data_ptr != 0 && opcode != OP_ONCE) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + if (opcode != OP_ONCE) + { + if (private_data_ptr != 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } else - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); } compile_matchingpath(common, ccprev, cc, current); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return; } - /* Instructions after the current alternative is succesfully matched. */ + /* Instructions after the current alternative is successfully matched. */ /* There is a similar code in compile_bracket_matchingpath. */ if (opcode == OP_ONCE) - { - if (CURRENT_AS(bracket_backtrack)->u.framesize < 0) - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - /* 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 private_data_ptr. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); - } - } - else - { - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_sw)); - 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)); - } - } - } + match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); stacksize = 0; - if (opcode != OP_ONCE) + if (repeat_type == OP_MINUPTO) + { + /* We need to preserve the counter. TMP2 will be used below. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr); stacksize++; + } if (ket != OP_KET || bra != OP_BRA) stacksize++; + if (offset != 0) + { + if (common->capture_last_ptr != 0) + stacksize++; + if (common->optimized_cbracket[offset >> 1] == 0) + stacksize += 2; + } + if (opcode != OP_ONCE) + 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_sw)); - } - } + if (stacksize > 0) + allocate_stack(common, stacksize); stacksize = 0; + if (repeat_type == OP_MINUPTO) + { + /* TMP2 was set above. */ + OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1); + stacksize++; + } + if (ket != OP_KET || bra != OP_BRA) { if (ket != OP_KET) @@ -7325,23 +9096,41 @@ if (has_alternatives) stacksize++; } - if (opcode != OP_ONCE) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++); - if (offset != 0) + stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); + + if (opcode != OP_ONCE) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count); + + if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0) { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */ + SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0)); 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)->alternative_matchingpath); if (opcode != OP_ONCE) { - SLJIT_ASSERT(jumplist); - JUMPHERE(jumplist->jump); - jumplist = jumplist->next; + if (alt_max > 4) + add_label_addr(common); + else + { + if (alt_count != 2 * sizeof(sljit_uw)) + { + JUMPHERE(alt1); + if (alt_max == 3 && alt_count == sizeof(sljit_uw)) + alt2 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); + } + else + { + JUMPHERE(alt2); + if (alt_max == 4) + alt1 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw)); + } + } + alt_count += sizeof(sljit_uw); } COMPILE_BACKTRACKINGPATH(current->top); @@ -7350,14 +9139,12 @@ if (has_alternatives) 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->private_data_ptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); @@ -7374,17 +9161,7 @@ if (has_alternatives) if (offset != 0) { /* Using both tmp register is better for instruction scheduling. */ - if (common->optimized_cbracket[offset >> 1] == 0) - { - 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, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); - free_stack(common, 3); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); - } - else + if (common->optimized_cbracket[offset >> 1] != 0) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); @@ -7392,6 +9169,12 @@ if (offset != 0) 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); } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); + } } else if (opcode == OP_SBRA || opcode == OP_SCOND) { @@ -7401,17 +9184,19 @@ else if (opcode == OP_SBRA || opcode == OP_SCOND) else if (opcode == OP_ONCE) { cc = ccbegin + GET(ccbegin, 1); + stacksize = needs_control_head ? 1 : 0; + 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); + stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1); } else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) { /* The STR_PTR must be released. */ - free_stack(common, 1); + stacksize++; } + free_stack(common, stacksize); JUMPHERE(once); /* Restore previous private_data_ptr */ @@ -7426,11 +9211,18 @@ else if (opcode == OP_ONCE) } } -if (ket == OP_KETRMAX) +if (repeat_type == OP_EXACT) + { + OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0); + CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label); + } +else 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)->recursive_matchingpath); if (bra == OP_BRAZERO) { @@ -7449,7 +9241,7 @@ else if (ket == OP_KETRMIN) 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); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label); if (opcode == OP_ONCE) free_stack(common, bra == OP_BRAMINZERO ? 2 : 1); else if (bra == OP_BRAMINZERO) @@ -7463,7 +9255,7 @@ else if (bra == OP_BRAZERO) } } -static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; int offset; @@ -7477,7 +9269,11 @@ if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) 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); + if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); + if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0); } set_jumps(current->topbacktracks, LABEL()); free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); @@ -7498,7 +9294,7 @@ if (current->topbacktracks) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw)); } -static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current) { assert_backtrack backtrack; @@ -7522,9 +9318,103 @@ else SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); } +static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +pcre_uchar opcode = *current->cc; +struct sljit_label *loop; +struct sljit_jump *jump; + +if (opcode == OP_THEN || opcode == OP_THEN_ARG) + { + if (common->then_trap != NULL) + { + SLJIT_ASSERT(common->control_head_ptr != 0); + + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start); + jump = JUMP(SLJIT_JUMP); + + loop = LABEL(); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw)); + JUMPHERE(jump); + CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop); + CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop); + add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP)); + return; + } + else if (common->positive_assert) + { + add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP)); + return; + } + } + +if (common->local_exit) + { + if (common->quit_label == NULL) + add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); + else + JUMPTO(SLJIT_JUMP, common->quit_label); + return; + } + +if (opcode == OP_SKIP_ARG) + { + SLJIT_ASSERT(common->control_head_ptr != 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2)); + sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); + + OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); + add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1)); + return; + } + +if (opcode == OP_SKIP) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); +else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0); +add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP)); +} + +static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +int size; + +if (CURRENT_AS(then_trap_backtrack)->then_trap) + { + common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap; + return; + } + +size = CURRENT_AS(then_trap_backtrack)->framesize; +size = 3 + (size < 0 ? 0 : size); + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3)); +free_stack(common, size); +jump = JUMP(SLJIT_JUMP); + +set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL()); +/* STACK_TOP is set by THEN. */ +if (CURRENT_AS(then_trap_backtrack)->framesize >= 0) + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); +free_stack(common, 3); + +JUMPHERE(jump); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0); +} + static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; +then_trap_backtrack *save_then_trap = common->then_trap; while (current) { @@ -7613,6 +9503,8 @@ while (current) case OP_REF: case OP_REFI: + case OP_DNREF: + case OP_DNREFI: compile_ref_iterator_backtrackingpath(common, current); break; @@ -7658,31 +9550,52 @@ while (current) break; case OP_MARK: - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - free_stack(common, 1); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0)); + if (common->has_skip_arg) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, common->has_skip_arg ? 5 : 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); + if (common->has_skip_arg) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0); + break; + + case OP_THEN: + case OP_THEN_ARG: + case OP_PRUNE: + case OP_PRUNE_ARG: + case OP_SKIP: + case OP_SKIP_ARG: + compile_control_verb_backtrackingpath(common, current); break; case OP_COMMIT: - OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); - if (common->quitlabel == NULL) + if (!common->local_exit) + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); + if (common->quit_label == NULL) add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); else - JUMPTO(SLJIT_JUMP, common->quitlabel); + JUMPTO(SLJIT_JUMP, common->quit_label); break; + case OP_CALLOUT: case OP_FAIL: case OP_ACCEPT: case OP_ASSERT_ACCEPT: set_jumps(current->topbacktracks, LABEL()); break; + case OP_THEN_TRAP: + /* A virtual opcode for then traps. */ + compile_then_trap_backtrackingpath(common, current); + break; + default: SLJIT_ASSERT_STOP(); break; } current = current->prev; } +common->then_trap = save_then_trap; } static SLJIT_INLINE void compile_recurse(compiler_common *common) @@ -7691,39 +9604,43 @@ 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 private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend); -int framesize = get_framesize(common, cc, TRUE); +BOOL needs_control_head; +int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head); +int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head); int alternativesize; -BOOL needsframe; +BOOL needs_frame; backtrack_common altbacktrack; -struct sljit_label *save_quitlabel = common->quitlabel; -jump_list *save_quit = common->quit; struct sljit_jump *jump; +/* Recurse captures then. */ +common->then_trap = NULL; + SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); -needsframe = framesize >= 0; -if (!needsframe) +needs_frame = framesize >= 0; +if (!needs_frame) framesize = 0; alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; -SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0); +SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0); common->currententry->entry = LABEL(); set_jumps(common->currententry->calls, common->currententry->entry); sljit_emit_fast_enter(compiler, TMP2, 0); allocate_stack(common, private_data_size + framesize + alternativesize); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0); -copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + 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); +copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); +if (needs_control_head) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0); +if (needs_frame) + init_frame(common, cc, NULL, 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->quitlabel = NULL; -common->acceptlabel = NULL; +common->quit_label = NULL; +common->accept_label = NULL; common->quit = NULL; common->accept = NULL; altbacktrack.cc = ccbegin; @@ -7738,21 +9655,13 @@ while (1) compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - { - common->quitlabel = save_quitlabel; - common->quit = save_quit; return; - } add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); compile_backtrackingpath(common, altbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) - { - common->quitlabel = save_quitlabel; - common->quit = save_quit; return; - } set_jumps(altbacktrack.topbacktracks, LABEL()); if (*cc != OP_ALT) @@ -7761,16 +9670,29 @@ while (1) altbacktrack.cc = cc + 1 + LINK_SIZE; cc += GET(cc, 1); } -/* None of them matched. */ -if (common->quit != NULL) - set_jumps(common->quit, LABEL()); +/* None of them matched. */ OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); jump = JUMP(SLJIT_JUMP); +if (common->quit != NULL) + { + set_jumps(common->quit, LABEL()); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr); + if (needs_frame) + { + OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); + } + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); + common->quit = NULL; + add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); + } + set_jumps(common->accept, LABEL()); -OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head); -if (needsframe) +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr); +if (needs_frame) { OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); @@ -7779,15 +9701,25 @@ if (needsframe) OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); JUMPHERE(jump); -copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize); +if (common->quit != NULL) + set_jumps(common->quit, LABEL()); +copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); free_stack(common, private_data_size + framesize + alternativesize); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); -OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0); +if (needs_control_head) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP1, 0); + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0); + } +else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0); + } sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); - -common->quitlabel = save_quitlabel; -common->quit = save_quit; } #undef COMPILE_BACKTRACKINGPATH @@ -7807,12 +9739,18 @@ 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; +sljit_uw total_length; +label_addr_list *label_addr; +struct sljit_label *mainloop_label = NULL; +struct sljit_label *continue_match_label; +struct sljit_label *empty_match_found_label = NULL; +struct sljit_label *empty_match_backtrack_label = NULL; +struct sljit_label *reset_match_label; +struct sljit_label *quit_label; struct sljit_jump *jump; +struct sljit_jump *minlength_check_failed = NULL; struct sljit_jump *reqbyte_notfound = NULL; -struct sljit_jump *empty_match; +struct sljit_jump *empty_match = NULL; SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0); study = extra->study_data; @@ -7825,9 +9763,13 @@ 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->read_only_data = NULL; +common->read_only_data_size = 0; +common->read_only_data_ptr = NULL; common->fcc = tables + fcc_offset; common->lcc = (sljit_sw)(tables + lcc_offset); common->mode = mode; +common->might_be_empty = study->minlength == 0; common->nltype = NLTYPE_FIXED; switch(re->options & PCRE_NEWLINE_BITS) { @@ -7848,6 +9790,8 @@ switch(re->options & PCRE_NEWLINE_BITS) case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; default: return; } +common->nlmax = READ_CHAR_MAX; +common->nlmin = 0; if ((re->options & PCRE_BSR_ANYCRLF) != 0) common->bsr_nltype = NLTYPE_ANYCRLF; else if ((re->options & PCRE_BSR_UNICODE) != 0) @@ -7860,10 +9804,11 @@ else common->bsr_nltype = NLTYPE_ANY; #endif } +common->bsr_nlmax = READ_CHAR_MAX; +common->bsr_nlmin = 0; common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; common->ctypes = (sljit_sw)(tables + ctypes_offset); -common->digits[0] = -2; -common->name_table = (sljit_sw)((pcre_uchar *)re + re->name_table_offset); +common->name_table = ((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; @@ -7873,19 +9818,49 @@ common->utf = (re->options & PCRE_UTF8) != 0; #ifdef SUPPORT_UCP common->use_ucp = (re->options & PCRE_UCP) != 0; #endif +if (common->utf) + { + if (common->nltype == NLTYPE_ANY) + common->nlmax = 0x2029; + else if (common->nltype == NLTYPE_ANYCRLF) + common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL; + else + { + /* We only care about the first newline character. */ + common->nlmax = common->newline & 0xff; + } + + if (common->nltype == NLTYPE_FIXED) + common->nlmin = common->newline & 0xff; + else + common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL; + + if (common->bsr_nltype == NLTYPE_ANY) + common->bsr_nlmax = 0x2029; + else + common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL; + common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL; + } #endif /* SUPPORT_UTF */ -ccend = bracketend(rootbacktrack.cc); +ccend = bracketend(common->start); /* Calculate the local space size on the stack. */ -common->ovector_start = CALL_LIMIT + sizeof(sljit_sw); +common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw); common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1); if (!common->optimized_cbracket) return; +#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1 +memset(common->optimized_cbracket, 0, re->top_bracket + 1); +#else memset(common->optimized_cbracket, 1, re->top_bracket + 1); +#endif -SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); -private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend); -if (private_data_size < 0) +SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); +#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2 +common->capture_last_ptr = common->ovector_start; +common->ovector_start += sizeof(sljit_sw); +#endif +if (!check_opcode_types(common, common->start, ccend)) { SLJIT_FREE(common->optimized_cbracket); return; @@ -7904,7 +9879,12 @@ if (mode != JIT_COMPILE) if (mode == JIT_PARTIAL_SOFT_COMPILE) { common->hit_start = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); + common->ovector_start += 2 * sizeof(sljit_sw); + } + else + { + SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE); + common->needs_start_ptr = TRUE; } } if ((re->options & PCRE_FIRSTLINE) != 0) @@ -7912,33 +9892,81 @@ if ((re->options & PCRE_FIRSTLINE) != 0) common->first_line_end = common->ovector_start; common->ovector_start += sizeof(sljit_sw); } +#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD +common->control_head_ptr = 1; +#endif +if (common->control_head_ptr != 0) + { + common->control_head_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } +if (common->needs_start_ptr && common->has_set_som) + { + /* Saving the real start pointer is necessary. */ + common->start_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } +else + common->needs_start_ptr = FALSE; /* Aligning ovector to even number of sljit words. */ if ((common->ovector_start & sizeof(sljit_sw)) != 0) common->ovector_start += sizeof(sljit_sw); +if (common->start_ptr == 0) + common->start_ptr = OVECTOR(0); + +/* Capturing brackets cannot be optimized if callouts are allowed. */ +if (common->capture_last_ptr != 0) + memset(common->optimized_cbracket, 0, re->top_bracket + 1); + SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); -common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); -private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw); -if (private_data_size > SLJIT_MAX_LOCAL_SIZE) - { - SLJIT_FREE(common->optimized_cbracket); - return; - } -common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); +common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); + +total_length = ccend - common->start; +common->private_data_ptrs = (sljit_si *)SLJIT_MALLOC(total_length * (sizeof(sljit_si) + (common->has_then ? 1 : 0))); if (!common->private_data_ptrs) { SLJIT_FREE(common->optimized_cbracket); return; } -memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); -set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend); +memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_si)); + +private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); +set_private_data_ptrs(common, &private_data_size, ccend); +if (private_data_size > SLJIT_MAX_LOCAL_SIZE) + { + SLJIT_FREE(common->private_data_ptrs); + SLJIT_FREE(common->optimized_cbracket); + return; + } + +if (common->has_then) + { + common->then_offsets = (pcre_uint8 *)(common->private_data_ptrs + total_length); + memset(common->then_offsets, 0, total_length); + set_then_offsets(common, common->start, NULL); + } + +if (common->read_only_data_size > 0) + { + common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size); + if (common->read_only_data == NULL) + { + SLJIT_FREE(common->optimized_cbracket); + SLJIT_FREE(common->private_data_ptrs); + return; + } + common->read_only_data_ptr = common->read_only_data; + } compiler = sljit_create_compiler(); if (!compiler) { SLJIT_FREE(common->optimized_cbracket); SLJIT_FREE(common->private_data_ptrs); + if (common->read_only_data) + SLJIT_FREE(common->read_only_data); return; } common->compiler = compiler; @@ -7956,96 +9984,142 @@ 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_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match)); 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); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH, TMP1, 0); if (mode == JIT_PARTIAL_SOFT_COMPILE) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0); +if (common->control_head_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, 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); + mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); + continue_match_label = LABEL(); /* Forward search if possible. */ if ((re->options & PCRE_NO_START_OPTIMIZE) == 0) { if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0)) - { /* Do nothing */ } + { + /* If read_only_data is reallocated, we might have an allocation failure. */ + if (common->read_only_data_size > 0 && common->read_only_data == NULL) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->optimized_cbracket); + SLJIT_FREE(common->private_data_ptrs); + return; + } + } else 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); + fast_forward_start_bits(common, study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); } } +else + continue_match_label = LABEL(); + +if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) + { + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength)); + minlength_check_failed = CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 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); +OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH); +if (common->capture_last_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1); + +if (common->needs_start_ptr) + { + SLJIT_ASSERT(common->start_ptr != OVECTOR(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr, STR_PTR, 0); + } +else + SLJIT_ASSERT(common->start_ptr == OVECTOR(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); + jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start + sizeof(sljit_sw), 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_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack); +compile_matchingpath(common, common->start, ccend, &rootbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); SLJIT_FREE(common->optimized_cbracket); SLJIT_FREE(common->private_data_ptrs); + if (common->read_only_data) + SLJIT_FREE(common->read_only_data); return; } -empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); -empty_match_found = LABEL(); +if (common->might_be_empty) + { + empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); + empty_match_found_label = LABEL(); + } -common->acceptlabel = LABEL(); +common->accept_label = LABEL(); if (common->accept != NULL) - set_jumps(common->accept, common->acceptlabel); + set_jumps(common->accept, common->accept_label); /* This means we have a match. Update the ovector. */ copy_ovector(common, re->top_bracket + 1); -common->quitlabel = LABEL(); +common->quit_label = common->forced_quit_label = LABEL(); if (common->quit != NULL) - set_jumps(common->quit, common->quitlabel); + set_jumps(common->quit, common->quit_label); +if (common->forced_quit != NULL) + set_jumps(common->forced_quit, common->forced_quit_label); +if (minlength_check_failed != NULL) + SET_LABEL(minlength_check_failed, common->forced_quit_label); 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->quitlabel); + return_with_partial_match(common, common->quit_label); } -empty_match_backtrack = LABEL(); +if (common->might_be_empty) + empty_match_backtrack_label = LABEL(); compile_backtrackingpath(common, rootbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); SLJIT_FREE(common->optimized_cbracket); SLJIT_FREE(common->private_data_ptrs); + if (common->read_only_data) + SLJIT_FREE(common->read_only_data); return; } SLJIT_ASSERT(rootbacktrack.prev == NULL); +reset_match_label = LABEL(); 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); + jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); 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); @@ -8053,34 +10127,28 @@ if (mode == JIT_PARTIAL_SOFT_COMPILE) } /* Check we have remaining characters. */ -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); +if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_FIRSTLINE) != 0) + { + SLJIT_ASSERT(common->first_line_end != 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); + } + +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr); if ((re->options & PCRE_ANCHORED) == 0) { - if ((re->options & PCRE_FIRSTLINE) == 0) + if (common->ff_newline_shortcut != NULL) { - 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); + if ((re->options & PCRE_FIRSTLINE) == 0) + CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut); + /* There cannot be more newlines here. */ } 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); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 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); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL); - JUMPTO(SLJIT_C_ZERO, mainloop); - } + if ((re->options & PCRE_FIRSTLINE) == 0) + CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label); else - CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop); + CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label); } } @@ -8089,24 +10157,29 @@ 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); + CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); -JUMPTO(SLJIT_JUMP, common->quitlabel); +JUMPTO(SLJIT_JUMP, common->quit_label); 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); +if (common->might_be_empty) + { + 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_label); + 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_label); + 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_label); + JUMPTO(SLJIT_JUMP, empty_match_backtrack_label); + } common->currententry = common->entries; +common->local_exit = TRUE; +quit_label = common->quit_label; while (common->currententry != NULL) { /* Might add new entries. */ @@ -8116,11 +10189,15 @@ while (common->currententry != NULL) sljit_free_compiler(compiler); SLJIT_FREE(common->optimized_cbracket); SLJIT_FREE(common->private_data_ptrs); + if (common->read_only_data) + SLJIT_FREE(common->read_only_data); return; } flush_stubs(common); common->currententry = common->currententry->next; } +common->local_exit = FALSE; +common->quit_label = quit_label; /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ /* This is a (really) rare case. */ @@ -8146,12 +10223,12 @@ sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); 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->quitlabel); +JUMPTO(SLJIT_JUMP, common->quit_label); /* Call limit reached. */ set_jumps(common->calllimit, LABEL()); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); -JUMPTO(SLJIT_JUMP, common->quitlabel); +JUMPTO(SLJIT_JUMP, common->quit_label); if (common->revertframes != NULL) { @@ -8188,15 +10265,26 @@ if (common->caselesscmp != NULL) set_jumps(common->caselesscmp, LABEL()); do_caselesscmp(common); } +if (common->reset_match != NULL) + { + set_jumps(common->reset_match, LABEL()); + do_reset_match(common, (re->top_bracket + 1) * 2); + CMPTO(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label); + OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); + JUMPTO(SLJIT_JUMP, reset_match_label); + } #ifdef SUPPORT_UTF -#ifndef COMPILE_PCRE32 +#ifdef COMPILE_PCRE8 if (common->utfreadchar != NULL) { set_jumps(common->utfreadchar, LABEL()); do_utfreadchar(common); } -#endif /* !COMPILE_PCRE32 */ -#ifdef COMPILE_PCRE8 +if (common->utfreadchar16 != NULL) + { + set_jumps(common->utfreadchar16, LABEL()); + do_utfreadchar16(common); + } if (common->utfreadtype8 != NULL) { set_jumps(common->utfreadtype8, LABEL()); @@ -8212,13 +10300,25 @@ if (common->getucd != NULL) } #endif +SLJIT_ASSERT(common->read_only_data + (common->read_only_data_size >> SLJIT_WORD_SHIFT) == common->read_only_data_ptr); SLJIT_FREE(common->optimized_cbracket); SLJIT_FREE(common->private_data_ptrs); + executable_func = sljit_generate_code(compiler); executable_size = sljit_get_generated_code_size(compiler); +label_addr = common->label_addrs; +while (label_addr != NULL) + { + *label_addr->addr = sljit_get_label_addr(label_addr->label); + label_addr = label_addr->next; + } sljit_free_compiler(compiler); if (executable_func == NULL) + { + if (common->read_only_data) + SLJIT_FREE(common->read_only_data); return; + } /* Reuse the function descriptor if possible. */ if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) @@ -8238,17 +10338,21 @@ else if (functions == NULL) { /* This case is highly unlikely since we just recently - freed a lot of memory. Although not impossible. */ + freed a lot of memory. Not impossible though. */ sljit_free_code(executable_func); + if (common->read_only_data) + SLJIT_FREE(common->read_only_data); return; } memset(functions, 0, sizeof(executable_functions)); functions->top_bracket = (re->top_bracket + 1) * 2; + functions->limit_match = (re->flags & PCRE_MLSET) != 0 ? re->limit_match : 0; extra->executable_jit = functions; extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; } functions->executable_funcs[mode] = executable_func; +functions->read_only_data[mode] = common->read_only_data; functions->executable_sizes[mode] = executable_size; } @@ -8272,7 +10376,7 @@ return convert_executable_func.call_executable_func(arguments); int PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject, - int length, int start_offset, int options, int *offsets, int offsetcount) + int length, int start_offset, int options, int *offsets, int offset_count) { executable_functions *functions = (executable_functions *)extra_data->executable_jit; union { @@ -8280,7 +10384,7 @@ union { jit_function call_executable_func; } convert_executable_func; jit_arguments arguments; -int maxoffsetcount; +int max_offset_count; int retval; int mode = JIT_COMPILE; @@ -8298,25 +10402,29 @@ 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.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit); +if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match) + arguments.limit_match = functions->limit_match; 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; +arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL; +arguments.real_offset_count = offset_count; -/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of +/* pcre_exec() rounds offset_count 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 = functions->top_bracket; -if (offsetcount > maxoffsetcount) - offsetcount = maxoffsetcount; -arguments.offsetcount = offsetcount; +if (offset_count != 2) + offset_count = ((offset_count - (offset_count % 3)) * 2) / 3; +max_offset_count = functions->top_bracket; +if (offset_count > max_offset_count) + offset_count = max_offset_count; +arguments.offset_count = offset_count; if (functions->callback) arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata); @@ -8331,7 +10439,7 @@ else retval = convert_executable_func.call_executable_func(&arguments); } -if (retval * 2 > offsetcount) +if (retval * 2 > offset_count) retval = 0; if ((extra_data->flags & PCRE_EXTRA_MARK) != 0) *(extra_data->mark) = arguments.mark_ptr; @@ -8343,17 +10451,17 @@ return retval; PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data, PCRE_SPTR subject, int length, int start_offset, int options, - int *offsets, int offsetcount, pcre_jit_stack *stack) + int *offsets, int offset_count, pcre_jit_stack *stack) #elif defined COMPILE_PCRE16 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, PCRE_SPTR16 subject, int length, int start_offset, int options, - int *offsets, int offsetcount, pcre16_jit_stack *stack) + int *offsets, int offset_count, pcre16_jit_stack *stack) #elif defined COMPILE_PCRE32 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data, PCRE_SPTR32 subject, int length, int start_offset, int options, - int *offsets, int offsetcount, pcre32_jit_stack *stack) + int *offsets, int offset_count, pcre32_jit_stack *stack) #endif { pcre_uchar *subject_ptr = (pcre_uchar *)subject; @@ -8363,7 +10471,7 @@ union { jit_function call_executable_func; } convert_executable_func; jit_arguments arguments; -int maxoffsetcount; +int max_offset_count; int retval; int mode = JIT_COMPILE; @@ -8387,30 +10495,34 @@ arguments.begin = subject_ptr; arguments.end = subject_ptr + 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.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit); +if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match) + arguments.limit_match = functions->limit_match; 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; +arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL; +arguments.real_offset_count = offset_count; -/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of +/* pcre_exec() rounds offset_count 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 = functions->top_bracket; -if (offsetcount > maxoffsetcount) - offsetcount = maxoffsetcount; -arguments.offsetcount = offsetcount; +if (offset_count != 2) + offset_count = ((offset_count - (offset_count % 3)) * 2) / 3; +max_offset_count = functions->top_bracket; +if (offset_count > max_offset_count) + offset_count = max_offset_count; +arguments.offset_count = offset_count; convert_executable_func.executable_func = functions->executable_funcs[mode]; retval = convert_executable_func.call_executable_func(&arguments); -if (retval * 2 > offsetcount) +if (retval * 2 > offset_count) retval = 0; if ((extra_data->flags & PCRE_EXTRA_MARK) != 0) *(extra_data->mark) = arguments.mark_ptr; @@ -8427,6 +10539,8 @@ for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) { if (functions->executable_funcs[i] != NULL) sljit_free_code(functions->executable_funcs[i]); + if (functions->read_only_data[i] != NULL) + SLJIT_FREE(functions->read_only_data[i]); } SLJIT_FREE(functions); } @@ -8504,6 +10618,20 @@ if (extra != NULL && } } +#if defined COMPILE_PCRE8 +PCRE_EXP_DECL void +pcre_jit_free_unused_memory(void) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DECL void +pcre16_jit_free_unused_memory(void) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DECL void +pcre32_jit_free_unused_memory(void) +#endif +{ +sljit_free_unused_memory_exec(); +} + #else /* SUPPORT_JIT */ /* These are dummy functions to avoid linking errors when JIT support is not @@ -8555,6 +10683,19 @@ pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void (void)userdata; } +#if defined COMPILE_PCRE8 +PCRE_EXP_DECL void +pcre_jit_free_unused_memory(void) +#elif defined COMPILE_PCRE16 +PCRE_EXP_DECL void +pcre16_jit_free_unused_memory(void) +#elif defined COMPILE_PCRE32 +PCRE_EXP_DECL void +pcre32_jit_free_unused_memory(void) +#endif +{ +} + #endif /* End of pcre_jit_compile.c */ diff --git a/tools/pcre/pcre_jit_test.c b/tools/pcre/pcre_jit_test.c index e8a297c9..a40913ef 100644 --- a/tools/pcre/pcre_jit_test.c +++ b/tools/pcre/pcre_jit_test.c @@ -75,9 +75,14 @@ POSSIBILITY OF SUCH DAMAGE. \xe1\xbf\xb8 = 0x1ff8 = 8184 \xf0\x90\x90\x80 = 0x10400 = 66560 \xf0\x90\x90\xa8 = 0x10428 = 66600 + \xc7\x84 = 0x1c4 = 452 + \xc7\x85 = 0x1c5 = 453 + \xc7\x86 = 0x1c6 = 454 + Mark property: \xcc\x8d = 0x30d = 781 Special: + \xc2\x80 = 0x80 = 128 (lowest 2 byte character) \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) @@ -126,6 +131,7 @@ int main(void) #define F_DIFF 0x080000 #define F_FORCECONV 0x100000 #define F_PROPERTY 0x200000 +#define F_STUDY 0x400000 struct regression_test_case { int flags; @@ -307,6 +313,17 @@ static struct regression_test_case regression_test_cases[] = { { 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" }, + /* Bracket repeats with limit. */ + { MUA, 0, "(?:(ab){2}){5}M", "abababababababababababM" }, + { MUA, 0, "(?:ab|abab){1,5}M", "abababababababababababM" }, + { MUA, 0, "(?>ab|abab){1,5}M", "abababababababababababM" }, + { MUA, 0, "(?:ab|abab){1,5}?M", "abababababababababababM" }, + { MUA, 0, "(?>ab|abab){1,5}?M", "abababababababababababM" }, + { MUA, 0, "(?:(ab){1,4}?){1,3}?M", "abababababababababababababM" }, + { MUA, 0, "(?:(ab){1,4}){1,3}abababababababababababM", "ababababababababababababM" }, + { MUA, 0 | F_NOMATCH, "(?:(ab){1,4}){1,3}abababababababababababM", "abababababababababababM" }, + { MUA, 0, "(ab){4,6}?M", "abababababababM" }, + /* Basic character sets. */ { MUA, 0, "(?:\\s)+(?:\\S)+", "ab \t\xc3\xa9\xe6\x92\xad " }, { MUA, 0, "(\\w)*(k)(\\W)?\?", "abcdef abck11" }, @@ -314,6 +331,22 @@ static struct regression_test_case regression_test_cases[] = { { 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" }, + { MUA, 0, "x[bcef]+", "xaxdxecbfg" }, + { MUA, 0, "x[bcdghij]+", "xaxexfxdgbjk" }, + { MUA, 0, "x[^befg]+", "xbxexacdhg" }, + { MUA, 0, "x[^bcdl]+", "xlxbxaekmd" }, + { MUA, 0, "x[^bcdghi]+", "xbxdxgxaefji" }, + { MUA, 0, "x[B-Fb-f]+", "xaxAxgxbfBFG" }, + { CMUA, 0, "\\x{e9}+", "#\xf0\x90\x90\xa8\xc3\xa8\xc3\xa9\xc3\x89\xc3\x88" }, + { CMUA, 0, "[^\\x{e9}]+", "\xc3\xa9#\xf0\x90\x90\xa8\xc3\xa8\xc3\x88\xc3\x89" }, + { MUA, 0, "[\\x02\\x7e]+", "\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x02\x7e\x7f" }, + { MUA, 0, "[^\\x02\\x7e]+", "\x02\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x7f\x7e" }, + { MUA, 0, "[\\x{81}-\\x{7fe}]+", "#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xc2\x81\xdf\xbe\xdf\xbf" }, + { MUA, 0, "[^\\x{81}-\\x{7fe}]+", "\xc2\x81#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xdf\xbf\xdf\xbe" }, + { MUA, 0, "[\\x{801}-\\x{fffe}]+", "#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xe0\xa0\x81\xef\xbf\xbe\xef\xbf\xbf" }, + { MUA, 0, "[^\\x{801}-\\x{fffe}]+", "\xe0\xa0\x81#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xef\xbf\xbf\xef\xbf\xbe" }, + { MUA, 0, "[\\x{10001}-\\x{10fffe}]+", "#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf0\x90\x80\x81\xf4\x8f\xbf\xbe\xf4\x8f\xbf\xbf" }, + { MUA, 0, "[^\\x{10001}-\\x{10fffe}]+", "\xf0\x90\x80\x81#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf4\x8f\xbf\xbf\xf4\x8f\xbf\xbe" }, /* Unicode properties. */ { MUAP, 0, "[1-5\xc3\xa9\\w]", "\xc3\xa1_" }, @@ -359,6 +392,10 @@ static struct regression_test_case regression_test_cases[] = { { 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##...." }, + { MUA | PCRE_NO_UTF8_CHECK, 1, "^.a", "\n\x80\nxa" }, + { MUA, 1, "^", "\r\n" }, + { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 1 | F_NOMATCH, "^", "\r\n" }, + { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 1, "^", "\r\na" }, /* Any character except newline or any newline. */ { PCRE_NEWLINE_CRLF, 0, ".", "\r" }, @@ -489,6 +526,22 @@ static struct regression_test_case regression_test_cases[] = { { 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" }, + { MUA | PCRE_DUPNAMES, 0 | F_NOMATCH, "\\k{1,3}(?aa)(?bb)", "aabb" }, + { MUA | PCRE_DUPNAMES | PCRE_JAVASCRIPT_COMPAT, 0, "\\k{1,3}(?aa)(?bb)", "aabb" }, + { MUA | PCRE_DUPNAMES | PCRE_JAVASCRIPT_COMPAT, 0, "\\k*(?aa)(?bb)", "aabb" }, + { MUA | PCRE_DUPNAMES, 0, "(?aa)(?bb)\\k{0,3}aaaaaa", "aabbaaaaaa" }, + { MUA | PCRE_DUPNAMES, 0, "(?aa)(?bb)\\k{2,5}bb", "aabbaaaabb" }, + { MUA | PCRE_DUPNAMES, 0, "(?:(?aa)|(?bb))\\k{0,3}m", "aaaaaaaabbbbaabbbbm" }, + { MUA | PCRE_DUPNAMES, 0 | F_NOMATCH, "\\k{1,3}?(?aa)(?bb)", "aabb" }, + { MUA | PCRE_DUPNAMES | PCRE_JAVASCRIPT_COMPAT, 0, "\\k{1,3}?(?aa)(?bb)", "aabb" }, + { MUA | PCRE_DUPNAMES, 0, "\\k*?(?aa)(?bb)", "aabb" }, + { MUA | PCRE_DUPNAMES, 0, "(?:(?aa)|(?bb))\\k{0,3}?m", "aaaaaabbbbbbaabbbbbbbbbbm" }, + { MUA | PCRE_DUPNAMES, 0, "(?:(?aa)|(?bb))\\k*?m", "aaaaaabbbbbbaabbbbbbbbbbm" }, + { MUA | PCRE_DUPNAMES, 0, "(?:(?aa)|(?bb))\\k{2,3}?", "aaaabbbbaaaabbbbbbbbbb" }, + { CMUA | PCRE_DUPNAMES, 0, "(?:(?AA)|(?BB))\\k{0,3}M", "aaaaaaaabbbbaabbbbm" }, + { CMUA | PCRE_DUPNAMES, 0, "(?:(?AA)|(?BB))\\k{1,3}M", "aaaaaaaabbbbaabbbbm" }, + { CMUA | PCRE_DUPNAMES, 0, "(?:(?AA)|(?BB))\\k{0,3}?M", "aaaaaabbbbbbaabbbbbbbbbbm" }, + { CMUA | PCRE_DUPNAMES, 0, "(?:(?AA)|(?BB))\\k{2,3}?", "aaaabbbbaaaabbbbbbbbbb" }, /* Assertions. */ { MUA, 0, "(?=xx|yy|zz)\\w{4}", "abczzdefg" }, @@ -572,6 +625,7 @@ static struct regression_test_case regression_test_cases[] = { { MUA, 0, "(?Pa)?(?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" }, + { MUA, 0, "((?:a|aa)(?(1)aaa))x", "aax" }, /* Set start of match. */ { MUA, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" }, @@ -600,6 +654,7 @@ static struct regression_test_case regression_test_cases[] = { { 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" }, { PCRE_FIRSTLINE | PCRE_NEWLINE_LF | PCRE_DOTALL, 0 | F_NOMATCH, "ab.", "ab" }, + { MUA | PCRE_FIRSTLINE, 1 | F_NOMATCH, "^[a-d0-9]", "\nxx\nd" }, /* Recurse. */ { MUA, 0, "(a)(?1)", "aa" }, @@ -627,6 +682,10 @@ static struct regression_test_case regression_test_cases[] = { { 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" }, + { MUA, 0, "((?(R)a|(?1)){3})", "XaaaaaaaaaX" }, + { MUA, 0, "((?:(?(R)a|(?1))){3})", "XaaaaaaaaaX" }, + { MUA, 0, "((?(R)a|(?1)){1,3})aaaaaa", "aaaaaaaaXaaaaaaaaa" }, + { MUA, 0, "((?(R)a|(?1)){1,3}?)M", "aaaM" }, /* 16 bit specific tests. */ { CMA, 0 | F_FORCECONV, "\xc3\xa1", "\xc3\x81\xc3\xa1" }, @@ -682,17 +741,65 @@ static struct regression_test_case regression_test_cases[] = { { 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 | F_NOMATCH | F_STUDY, "(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" }, + { MUA, 0 | F_NOMATCH | F_STUDY, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" }, + { MUA, 0 | F_NOMATCH | F_STUDY, "(*:mark)m", "a" }, /* (*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" }, + { MUA, 0 | F_NOMATCH, "(a(*COMMIT)b)++", "abac" }, + { MUA, 0 | F_NOMATCH, "((a)(*COMMIT)b)++", "abac" }, + { MUA, 0 | F_NOMATCH, "(?=a(*COMMIT)b)ab|ad", "ad" }, + + /* (*PRUNE) verb. */ + { MUA, 0, "aa\\K(*PRUNE)b", "aaab" }, + { MUA, 0, "aa(*PRUNE:bb)b|a", "aa" }, + { MUA, 0, "(a)(a)(*PRUNE)b|(a)", "aa" }, + { MUA, 0, "(a)(a)(a)(a)(a)(a)(a)(a)(*PRUNE)b|(a)", "aaaaaaaa" }, + { MUA | PCRE_PARTIAL_SOFT, 0, "a(*PRUNE)a|", "a" }, + { MUA | PCRE_PARTIAL_SOFT, 0, "a(*PRUNE)a|m", "a" }, + { MUA, 0 | F_NOMATCH, "(?=a(*PRUNE)b)ab|ad", "ad" }, + { MUA, 0, "a(*COMMIT)(*PRUNE)d|bc", "abc" }, + { MUA, 0, "(?=a(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, + { MUA, 0 | F_NOMATCH, "(*COMMIT)(?=a(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, + { MUA, 0, "(?=(a)(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, + { MUA, 0 | F_NOMATCH, "(*COMMIT)(?=(a)(*COMMIT)b)a(*PRUNE)c|bc", "abc" }, + { MUA, 0, "(a(*COMMIT)b){0}a(?1)(*PRUNE)c|bc", "abc" }, + { MUA, 0 | F_NOMATCH, "(a(*COMMIT)b){0}a(*COMMIT)(?1)(*PRUNE)c|bc", "abc" }, + { MUA, 0, "(a(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, + { MUA, 0 | F_NOMATCH, "(*COMMIT)(a(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, + { MUA, 0, "((a)(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, + { MUA, 0 | F_NOMATCH, "(*COMMIT)((a)(*COMMIT)b)++(*PRUNE)d|c", "ababc" }, + { MUA, 0, "(?>a(*COMMIT)b)*abab(*PRUNE)d|ba", "ababab" }, + { MUA, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)*abab(*PRUNE)d|ba", "ababab" }, + { MUA, 0, "(?>a(*COMMIT)b)+abab(*PRUNE)d|ba", "ababab" }, + { MUA, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)+abab(*PRUNE)d|ba", "ababab" }, + { MUA, 0, "(?>a(*COMMIT)b)?ab(*PRUNE)d|ba", "aba" }, + { MUA, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)?ab(*PRUNE)d|ba", "aba" }, + { MUA, 0, "(?>a(*COMMIT)b)*?n(*PRUNE)d|ba", "abababn" }, + { MUA, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)*?n(*PRUNE)d|ba", "abababn" }, + { MUA, 0, "(?>a(*COMMIT)b)+?n(*PRUNE)d|ba", "abababn" }, + { MUA, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)+?n(*PRUNE)d|ba", "abababn" }, + { MUA, 0, "(?>a(*COMMIT)b)??n(*PRUNE)d|bn", "abn" }, + { MUA, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)??n(*PRUNE)d|bn", "abn" }, + + /* (*SKIP) verb. */ + { MUA, 0 | F_NOMATCH, "(?=a(*SKIP)b)ab|ad", "ad" }, + + /* (*THEN) verb. */ + { MUA, 0, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcaabcaabcaabcnacm" }, + { MUA, 0 | F_NOMATCH, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcm" }, + { MUA, 0, "((?:a(*THEN)|aab)c|a+)+m", "aabcaabcnmaabcaabcm" }, + { MUA, 0, "((?:a|aab)(*THEN)c|a+)+m", "aam" }, + { MUA, 0, "((?:a(*COMMIT)|aab)(*THEN)c|a+)+m", "aam" }, + { MUA, 0, "(?(?=a(*THEN)b)ab|ad)", "ad" }, + { MUA, 0, "(?(?!a(*THEN)b)ad|add)", "add" }, + { MUA, 0 | F_NOMATCH, "(?(?=a)a(*THEN)b|ad)", "ad" }, + { MUA, 0, "(?!(?(?=a)ab|b(*THEN)d))bn|bnn", "bnn" }, /* Deep recursion. */ { MUA, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " }, @@ -878,7 +985,7 @@ static int convert_utf8_to_utf16(const char *input, PCRE_UCHAR16 *output, int *o if (offsetmap) *offsetmap++ = (int)(iptr - (unsigned char*)input); - if (!(*iptr & 0x80)) + if (*iptr < 0xc0) c = *iptr++; else if (!(*iptr & 0x20)) { c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f); @@ -950,7 +1057,7 @@ static int convert_utf8_to_utf32(const char *input, PCRE_UCHAR32 *output, int *o if (offsetmap) *offsetmap++ = (int)(iptr - (unsigned char*)input); - if (!(*iptr & 0x80)) + if (*iptr < 0xc0) c = *iptr++; else if (!(*iptr & 0x20)) { c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f); @@ -1011,7 +1118,7 @@ static int regression_tests(void) const char *error; char *cpu_info; int i, err_offs; - int is_successful, is_ascii_pattern, is_ascii_input; + int is_successful, is_ascii; int total = 0; int successful = 0; int successful_row = 0; @@ -1092,13 +1199,9 @@ static int regression_tests(void) 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); - } + is_ascii = 0; + if (!(current->start_offset & F_PROPERTY)) + is_ascii = check_ascii(current->pattern) && check_ascii(current->input); if (current->flags & PCRE_PARTIAL_SOFT) study_mode = PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE; @@ -1130,7 +1233,7 @@ static int regression_tests(void) re8 = NULL; } extra8->flags |= PCRE_EXTRA_MARK; - } else if (((utf && ucp) || is_ascii_pattern) && !(current->start_offset & F_NO8)) + } else if (((utf && ucp) || is_ascii) && !(current->start_offset & F_NO8)) printf("\n8 bit: Cannot compile pattern \"%s\": %s\n", current->pattern, error); #endif #ifdef SUPPORT_PCRE16 @@ -1161,7 +1264,7 @@ static int regression_tests(void) re16 = NULL; } extra16->flags |= PCRE_EXTRA_MARK; - } else if (((utf && ucp) || is_ascii_pattern) && !(current->start_offset & F_NO16)) + } else if (((utf && ucp) || is_ascii) && !(current->start_offset & F_NO16)) printf("\n16 bit: Cannot compile pattern \"%s\": %s\n", current->pattern, error); #endif #ifdef SUPPORT_PCRE32 @@ -1192,7 +1295,7 @@ static int regression_tests(void) re32 = NULL; } extra32->flags |= PCRE_EXTRA_MARK; - } else if (((utf && ucp) || is_ascii_pattern) && !(current->start_offset & F_NO32)) + } else if (((utf && ucp) || is_ascii) && !(current->start_offset & F_NO32)) printf("\n32 bit: Cannot compile pattern \"%s\": %s\n", current->pattern, error); #endif @@ -1224,15 +1327,19 @@ static int regression_tests(void) if ((counter & 0x1) != 0) { setstack8(extra8); return_value8[0] = 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); + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector8_1, 32); } else return_value8[0] = pcre_jit_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, getstack8()); + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector8_1, 32, getstack8()); memset(&dummy_extra8, 0, sizeof(pcre_extra)); dummy_extra8.flags = PCRE_EXTRA_MARK; + if (current->start_offset & F_STUDY) { + dummy_extra8.flags |= PCRE_EXTRA_STUDY_DATA; + dummy_extra8.study_data = extra8->study_data; + } dummy_extra8.mark = &mark8_2; return_value8[1] = 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); + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector8_2, 32); } #endif @@ -1254,15 +1361,19 @@ static int regression_tests(void) if ((counter & 0x1) != 0) { setstack16(extra16); return_value16[0] = pcre16_exec(re16, extra16, regtest_buf16, 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); + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector16_1, 32); } else return_value16[0] = pcre16_jit_exec(re16, extra16, regtest_buf16, 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, getstack16()); + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector16_1, 32, getstack16()); memset(&dummy_extra16, 0, sizeof(pcre16_extra)); dummy_extra16.flags = PCRE_EXTRA_MARK; + if (current->start_offset & F_STUDY) { + dummy_extra16.flags |= PCRE_EXTRA_STUDY_DATA; + dummy_extra16.study_data = extra16->study_data; + } dummy_extra16.mark = &mark16_2; return_value16[1] = pcre16_exec(re16, &dummy_extra16, regtest_buf16, 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); + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector16_2, 32); } #endif @@ -1284,20 +1395,24 @@ static int regression_tests(void) if ((counter & 0x1) != 0) { setstack32(extra32); return_value32[0] = pcre32_exec(re32, extra32, regtest_buf32, length32, current->start_offset & OFFSET_MASK, - current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector32_1, 32); + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector32_1, 32); } else return_value32[0] = pcre32_jit_exec(re32, extra32, regtest_buf32, length32, current->start_offset & OFFSET_MASK, - current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector32_1, 32, getstack32()); + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector32_1, 32, getstack32()); memset(&dummy_extra32, 0, sizeof(pcre32_extra)); dummy_extra32.flags = PCRE_EXTRA_MARK; + if (current->start_offset & F_STUDY) { + dummy_extra32.flags |= PCRE_EXTRA_STUDY_DATA; + dummy_extra32.study_data = extra32->study_data; + } dummy_extra32.mark = &mark32_2; return_value32[1] = pcre32_exec(re32, &dummy_extra32, regtest_buf32, length32, current->start_offset & OFFSET_MASK, - current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector32_2, 32); + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector32_2, 32); } #endif /* printf("[%d-%d-%d|%d-%d|%d-%d|%d-%d]%s", - return_value8[0], return_value16[0], + return_value8[0], return_value16[0], return_value32[0], ovector8_1[0], ovector8_1[1], ovector16_1[0], ovector16_1[1], ovector32_1[0], ovector32_1[1], @@ -1488,7 +1603,7 @@ static int regression_tests(void) if (is_successful) { #ifdef SUPPORT_PCRE8 - if (!(current->start_offset & F_NO8) && ((utf && ucp) || is_ascii_input)) { + if (!(current->start_offset & F_NO8) && ((utf && ucp) || is_ascii)) { if (return_value8[0] < 0 && !(current->start_offset & F_NOMATCH)) { printf("8 bit: Test should match: [%d] '%s' @ '%s'\n", total, current->pattern, current->input); @@ -1503,7 +1618,7 @@ static int regression_tests(void) } #endif #ifdef SUPPORT_PCRE16 - if (!(current->start_offset & F_NO16) && ((utf && ucp) || is_ascii_input)) { + if (!(current->start_offset & F_NO16) && ((utf && ucp) || is_ascii)) { if (return_value16[0] < 0 && !(current->start_offset & F_NOMATCH)) { printf("16 bit: Test should match: [%d] '%s' @ '%s'\n", total, current->pattern, current->input); @@ -1518,7 +1633,7 @@ static int regression_tests(void) } #endif #ifdef SUPPORT_PCRE32 - if (!(current->start_offset & F_NO32) && ((utf && ucp) || is_ascii_input)) { + if (!(current->start_offset & F_NO32) && ((utf && ucp) || is_ascii)) { if (return_value32[0] < 0 && !(current->start_offset & F_NOMATCH)) { printf("32 bit: Test should match: [%d] '%s' @ '%s'\n", total, current->pattern, current->input); diff --git a/tools/pcre/pcre_maketables.c b/tools/pcre/pcre_maketables.c index 610a6695..a44a6eaa 100644 --- a/tools/pcre/pcre_maketables.c +++ b/tools/pcre/pcre_maketables.c @@ -98,13 +98,17 @@ for (i = 0; i < 256; i++) *p++ = tolower(i); for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i); /* Then the character class tables. Don't try to be clever and save effort on -exclusive ones - in some locales things may be different. Note that the table -for "space" includes everything "isspace" gives, including VT in the default -locale. This makes it work for the POSIX class [:space:]. Note also that it is -possible for a character to be alnum or alpha without being lower or upper, -such as "male and female ordinals" (\xAA and \xBA) in the fr_FR locale (at -least under Debian Linux's locales as of 12/2005). So we must test for alnum -specially. */ +exclusive ones - in some locales things may be different. + +Note that the table for "space" includes everything "isspace" gives, including +VT in the default locale. This makes it work for the POSIX class [:space:]. +From release 8.34 is is also correct for Perl space, because Perl added VT at +release 5.18. + +Note also that it is possible for a character to be alnum or alpha without +being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the +fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must +test for alnum specially. */ memset(p, 0, cbit_length); for (i = 0; i < 256; i++) @@ -123,14 +127,15 @@ for (i = 0; i < 256; i++) } p += cbit_length; -/* Finally, the character type table. In this, we exclude VT from the white -space chars, because Perl doesn't recognize it as such for \s and for comments -within regexes. */ +/* Finally, the character type table. In this, we used to exclude VT from the +white space chars, because Perl didn't recognize it as such for \s and for +comments within regexes. However, Perl changed at release 5.18, so PCRE changed +at release 8.34. */ for (i = 0; i < 256; i++) { int x = 0; - if (i != CHAR_VT && isspace(i)) x += ctype_space; + if (isspace(i)) x += ctype_space; if (isalpha(i)) x += ctype_letter; if (isdigit(i)) x += ctype_digit; if (isxdigit(i)) x += ctype_xdigit; diff --git a/tools/pcre/pcre_printint.c b/tools/pcre/pcre_printint.c index 10b57542..60dcb55e 100644 --- a/tools/pcre/pcre_printint.c +++ b/tools/pcre/pcre_printint.c @@ -425,10 +425,19 @@ for(;;) break; case OP_CREF: - case OP_NCREF: fprintf(f, "%3d %s", GET2(code,1), priv_OP_names[*code]); break; + case OP_DNCREF: + { + pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) + + IMM2_SIZE; + fprintf(f, " %s Cond ref <", flag); + print_puchar(f, entry); + fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); + } + break; + case OP_RREF: c = GET2(code, 1); if (c == RREF_ANY) @@ -437,12 +446,14 @@ for(;;) 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); + case OP_DNRREF: + { + pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) + + IMM2_SIZE; + fprintf(f, " %s Cond recurse <", flag); + print_puchar(f, entry); + fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); + } break; case OP_DEF: @@ -598,6 +609,20 @@ for(;;) ccode = code + priv_OP_lengths[*code]; goto CLASS_REF_REPEAT; + case OP_DNREFI: + flag = "/i"; + /* Fall through */ + case OP_DNREF: + { + pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) + + IMM2_SIZE; + fprintf(f, " %s \\k<", flag); + print_puchar(f, entry); + fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); + } + 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)); @@ -608,9 +633,9 @@ for(;;) print_prop(f, code, " ", ""); 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. */ + /* OP_XCLASS cannot occur in 8-bit, non-UTF 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: @@ -619,7 +644,9 @@ for(;;) int i; unsigned int min, max; BOOL printmap; + BOOL invertmap = FALSE; pcre_uint8 *map; + pcre_uint8 inverted_map[32]; fprintf(f, " ["); @@ -628,7 +655,12 @@ for(;;) extra = GET(code, 1); ccode = code + LINK_SIZE + 1; printmap = (*ccode & XCL_MAP) != 0; - if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^"); + if ((*ccode & XCL_NOT) != 0) + { + invertmap = (*ccode & XCL_HASPROP) == 0; + fprintf(f, "^"); + } + ccode++; } else { @@ -641,6 +673,12 @@ for(;;) if (printmap) { map = (pcre_uint8 *)ccode; + if (invertmap) + { + for (i = 0; i < 32; i++) inverted_map[i] = ~map[i]; + map = inverted_map; + } + for (i = 0; i < 256; i++) { if ((map[i/8] & (1 << (i&7))) != 0) @@ -671,26 +709,51 @@ for(;;) pcre_uchar ch; while ((ch = *ccode++) != XCL_END) { - if (ch == XCL_PROP) - { - unsigned int ptype = *ccode++; - unsigned int pvalue = *ccode++; - fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue)); - } - else if (ch == XCL_NOTPROP) - { - unsigned int ptype = *ccode++; - unsigned int pvalue = *ccode++; - fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue)); - } - else + BOOL not = FALSE; + const char *notch = ""; + + switch(ch) { + case XCL_NOTPROP: + not = TRUE; + notch = "^"; + /* Fall through */ + + case XCL_PROP: + { + unsigned int ptype = *ccode++; + unsigned int pvalue = *ccode++; + + switch(ptype) + { + case PT_PXGRAPH: + fprintf(f, "[:%sgraph:]", notch); + break; + + case PT_PXPRINT: + fprintf(f, "[:%sprint:]", notch); + break; + + case PT_PXPUNCT: + fprintf(f, "[:%spunct:]", notch); + break; + + default: + fprintf(f, "\\%c{%s}", (not? 'P':'p'), + get_ucpname(ptype, pvalue)); + break; + } + } + break; + + default: ccode += 1 + print_char(f, ccode, utf); if (ch == XCL_RANGE) { fprintf(f, "-"); ccode += 1 + print_char(f, ccode, utf); } + break; } } } @@ -710,17 +773,22 @@ for(;;) case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: fprintf(f, "%s", priv_OP_names[*ccode]); extra += priv_OP_lengths[*ccode]; break; case OP_CRRANGE: case OP_CRMINRANGE: + case OP_CRPOSRANGE: min = GET2(ccode,1); max = GET2(ccode,1 + IMM2_SIZE); if (max == 0) fprintf(f, "{%u,}", min); else fprintf(f, "{%u,%u}", min, max); if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); + else if (*ccode == OP_CRPOSRANGE) fprintf(f, "+"); extra += priv_OP_lengths[*ccode]; break; diff --git a/tools/pcre/pcre_string_utils.c b/tools/pcre/pcre_string_utils.c index 94a51260..25eacc85 100644 --- a/tools/pcre/pcre_string_utils.c +++ b/tools/pcre/pcre_string_utils.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -38,8 +38,8 @@ 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(). */ +/* This module contains internal functions for comparing and finding the length +of strings for different data item sizes. */ #ifdef HAVE_CONFIG_H @@ -54,7 +54,7 @@ class. It is used by both pcre_exec() and pcre_def_exec(). */ * Compare string utilities * *************************************************/ -/* The following two functions compares two strings. Basically an strcmp +/* The following two functions compares two strings. Basically a strcmp for non 8 bit characters. Arguments: @@ -91,8 +91,8 @@ pcre_uchar c2; while (*str1 != '\0' || *str2 != '\0') { - c1 = RAWUCHARINC(str1); - c2 = RAWUCHARINC(str2); + c1 = UCHAR21INC(str1); + c2 = UCHAR21INC(str2); if (c1 != c2) return ((c1 > c2) << 1) - 1; } @@ -131,7 +131,7 @@ pcre_uchar c2; while (*str1 != '\0' || *ustr2 != '\0') { - c1 = RAWUCHARINC(str1); + c1 = UCHAR21INC(str1); c2 = (pcre_uchar)*ustr2++; if (c1 != c2) return ((c1 > c2) << 1) - 1; diff --git a/tools/pcre/pcre_study.c b/tools/pcre/pcre_study.c index 12d2a668..ab9510e2 100644 --- a/tools/pcre/pcre_study.c +++ b/tools/pcre/pcre_study.c @@ -66,8 +66,9 @@ string of that length that matches. In UTF8 mode, the result is in characters rather than bytes. Arguments: + re compiled pattern block code pointer to start of group (the bracket) - startcode pointer to start of the whole pattern + startcode pointer to start of the whole pattern's code options the compiling options int RECURSE depth @@ -78,8 +79,8 @@ Returns: the minimum length */ static int -find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options, - int recurse_depth) +find_minlength(const REAL_PCRE *re, const pcre_uchar *code, + const pcre_uchar *startcode, int options, int recurse_depth) { int length = -1; /* PCRE_UTF16 has the same value as PCRE_UTF8. */ @@ -129,7 +130,7 @@ for (;;) case OP_SBRAPOS: case OP_ONCE: case OP_ONCE_NC: - d = find_minlength(cc, startcode, options, recurse_depth); + d = find_minlength(re, cc, startcode, options, recurse_depth); if (d < 0) return d; branchlength += d; do cc += GET(cc, 1); while (*cc == OP_ALT); @@ -175,9 +176,9 @@ for (;;) case OP_REVERSE: case OP_CREF: - case OP_NCREF: + case OP_DNCREF: case OP_RREF: - case OP_NRREF: + case OP_DNRREF: case OP_DEF: case OP_CALLOUT: case OP_SOD: @@ -341,6 +342,7 @@ for (;;) { case OP_CRPLUS: case OP_CRMINPLUS: + case OP_CRPOSPLUS: branchlength++; /* Fall through */ @@ -348,11 +350,14 @@ for (;;) case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSQUERY: cc++; break; case OP_CRRANGE: case OP_CRMINRANGE: + case OP_CRPOSRANGE: branchlength += GET2(cc,1); cc += 1 + 2 * IMM2_SIZE; break; @@ -375,7 +380,38 @@ for (;;) matches an empty string (by default it causes a matching failure), so in that case we must set the minimum length to zero. */ - case OP_REF: + case OP_DNREF: /* Duplicate named pattern back reference */ + case OP_DNREFI: + if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) + { + int count = GET2(cc, 1+IMM2_SIZE); + pcre_uchar *slot = (pcre_uchar *)re + + re->name_table_offset + GET2(cc, 1) * re->name_entry_size; + d = INT_MAX; + while (count-- > 0) + { + ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(slot, 0)); + if (cs == NULL) return -2; + do ce += GET(ce, 1); while (*ce == OP_ALT); + if (cc > cs && cc < ce) + { + d = 0; + had_recurse = TRUE; + break; + } + else + { + int dd = find_minlength(re, cs, startcode, options, recurse_depth); + if (dd < d) d = dd; + } + slot += re->name_entry_size; + } + } + else d = 0; + cc += 1 + 2*IMM2_SIZE; + goto REPEAT_BACK_REFERENCE; + + case OP_REF: /* Single back reference */ case OP_REFI: if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) { @@ -389,7 +425,7 @@ for (;;) } else { - d = find_minlength(cs, startcode, options, recurse_depth); + d = find_minlength(re, cs, startcode, options, recurse_depth); } } else d = 0; @@ -397,24 +433,29 @@ for (;;) /* Handle repeated back references */ + REPEAT_BACK_REFERENCE: switch (*cc) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSQUERY: min = 0; cc++; break; case OP_CRPLUS: case OP_CRMINPLUS: + case OP_CRPOSPLUS: min = 1; cc++; break; case OP_CRRANGE: case OP_CRMINRANGE: + case OP_CRPOSRANGE: min = GET2(cc, 1); cc += 1 + 2 * IMM2_SIZE; break; @@ -437,7 +478,8 @@ for (;;) had_recurse = TRUE; else { - branchlength += find_minlength(cs, startcode, options, recurse_depth + 1); + branchlength += find_minlength(re, cs, startcode, options, + recurse_depth + 1); } cc += 1 + LINK_SIZE; break; @@ -778,6 +820,10 @@ do case OP_COND: case OP_CREF: case OP_DEF: + case OP_DNCREF: + case OP_DNREF: + case OP_DNREFI: + case OP_DNRREF: case OP_DOLL: case OP_DOLLM: case OP_END: @@ -786,7 +832,6 @@ do case OP_EXTUNI: case OP_FAIL: case OP_MARK: - case OP_NCREF: case OP_NOT: case OP_NOTEXACT: case OP_NOTEXACTI: @@ -818,7 +863,6 @@ do case OP_NOTUPTOI: case OP_NOT_HSPACE: case OP_NOT_VSPACE: - case OP_NRREF: case OP_PROP: case OP_PRUNE: case OP_PRUNE_ARG: @@ -835,9 +879,6 @@ do 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. */ @@ -1183,24 +1224,16 @@ do set_type_bits(start_bits, cbit_digit, table_limit, cd); break; - /* The cbit_space table has vertical tab as whitespace; we have to - ensure it gets set as not whitespace. Luckily, the code value is the - same (0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate - bit. */ + /* The cbit_space table has vertical tab as whitespace; we no longer + have to play fancy tricks because Perl added VT to its whitespace at + release 5.18. PCRE added it at release 8.34. */ case OP_NOT_WHITESPACE: set_nottype_bits(start_bits, cbit_space, table_limit, cd); - start_bits[1] |= 0x08; break; - /* The cbit_space table has vertical tab as whitespace; we have to - avoid setting it. Luckily, the code value is the same (0x0b) in ASCII - and EBCDIC, so we can just adjust the appropriate bit. */ - case OP_WHITESPACE: - c = start_bits[1]; /* Save in case it was already set */ set_type_bits(start_bits, cbit_space, table_limit, cd); - start_bits[1] = (start_bits[1] & ~0x08) | c; break; case OP_NOT_WORDCHAR: @@ -1221,6 +1254,16 @@ do with a value >= 0xc4 is a potentially valid starter because it starts a character with a value > 255. */ +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + if ((tcode[1 + LINK_SIZE] & XCL_HASPROP) != 0) + return SSB_FAIL; + /* All bits are set. */ + if ((tcode[1 + LINK_SIZE] & XCL_MAP) == 0 && (tcode[1 + LINK_SIZE] & XCL_NOT) != 0) + return SSB_FAIL; +#endif + /* Fall through */ + case OP_NCLASS: #if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (utf) @@ -1237,8 +1280,21 @@ do case OP_CLASS: { pcre_uint8 *map; - tcode++; - map = (pcre_uint8 *)tcode; +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + map = NULL; + if (*tcode == OP_XCLASS) + { + if ((tcode[1 + LINK_SIZE] & XCL_MAP) != 0) + map = (pcre_uint8 *)(tcode + 1 + LINK_SIZE + 1); + tcode += GET(tcode, 1); + } + else +#endif + { + tcode++; + map = (pcre_uint8 *)tcode; + tcode += 32 / sizeof(pcre_uchar); + } /* 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 @@ -1246,42 +1302,49 @@ do value is > 127. In fact, there are only two possible starting bytes for characters in the range 128 - 255. */ -#if defined SUPPORT_UTF && defined COMPILE_PCRE8 - if (utf) - { - for (c = 0; c < 16; c++) start_bits[c] |= map[c]; - for (c = 128; c < 256; c++) - { - 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 */ - c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ - } - } - } - else +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + if (map != NULL) #endif { - /* In non-UTF-8 mode, the two bit maps are completely compatible. */ - for (c = 0; c < 32; c++) start_bits[c] |= map[c]; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (utf) + { + for (c = 0; c < 16; c++) start_bits[c] |= map[c]; + for (c = 128; c < 256; c++) + { + 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 */ + c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ + } + } + } + else +#endif + { + /* 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. For a zero minimum repeat, continue; otherwise stop processing. */ - tcode += 32 / sizeof(pcre_uchar); switch (*tcode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSQUERY: tcode++; break; case OP_CRRANGE: case OP_CRMINRANGE: + case OP_CRPOSRANGE: if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE; else try_next = FALSE; break; @@ -1346,6 +1409,7 @@ pcre_uchar *code; compile_data compile_block; const REAL_PCRE *re = (const REAL_PCRE *)external_re; + *errorptr = NULL; if (re == NULL || re->magic_number != MAGIC_NUMBER) @@ -1422,7 +1486,7 @@ if ((re->options & PCRE_ANCHORED) == 0 && /* Find the minimum length of subject string. */ -switch(min = find_minlength(code, code, re->options, 0)) +switch(min = find_minlength(re, code, code, re->options, 0)) { case -2: *errorptr = "internal error: missing capturing bracket"; return NULL; case -3: *errorptr = "internal error: opcode not recognized"; return NULL; diff --git a/tools/pcre/pcre_tables.c b/tools/pcre/pcre_tables.c index 34ee0488..f38ab52c 100644 --- a/tools/pcre/pcre_tables.c +++ b/tools/pcre/pcre_tables.c @@ -346,6 +346,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Xan0 STR_X STR_a STR_n "\0" #define STRING_Xps0 STR_X STR_p STR_s "\0" #define STRING_Xsp0 STR_X STR_s STR_p "\0" +#define STRING_Xuc0 STR_X STR_u STR_c "\0" #define STRING_Xwd0 STR_X STR_w STR_d "\0" #define STRING_Yi0 STR_Y STR_i "\0" #define STRING_Z0 STR_Z "\0" @@ -493,6 +494,7 @@ const char PRIV(utt_names)[] = STRING_Xan0 STRING_Xps0 STRING_Xsp0 + STRING_Xuc0 STRING_Xwd0 STRING_Yi0 STRING_Z0 @@ -640,12 +642,13 @@ const ucp_type_table PRIV(utt)[] = { { 1011, PT_ALNUM, 0 }, { 1015, PT_PXSPACE, 0 }, { 1019, PT_SPACE, 0 }, - { 1023, PT_WORD, 0 }, - { 1027, PT_SC, ucp_Yi }, - { 1030, PT_GC, ucp_Z }, - { 1032, PT_PC, ucp_Zl }, - { 1035, PT_PC, ucp_Zp }, - { 1038, PT_PC, ucp_Zs } + { 1023, PT_UCNC, 0 }, + { 1027, PT_WORD, 0 }, + { 1031, PT_SC, ucp_Yi }, + { 1034, PT_GC, ucp_Z }, + { 1036, PT_PC, ucp_Zl }, + { 1039, PT_PC, ucp_Zp }, + { 1042, PT_PC, ucp_Zs } }; const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table); diff --git a/tools/pcre/pcre_ucd.c b/tools/pcre/pcre_ucd.c index 56f31a1e..46ea70c4 100644 --- a/tools/pcre/pcre_ucd.c +++ b/tools/pcre/pcre_ucd.c @@ -20,7 +20,7 @@ needed. */ /* Unicode character database. */ /* This file was autogenerated by the MultiStage2.py script. */ -/* Total size: 65696 bytes, block size: 128. */ +/* Total size: 65688 bytes, block size: 128. */ /* The tables herein are needed only when UCP support is built into PCRE. This module should not be referenced otherwise, so @@ -79,7 +79,7 @@ const pcre_uint32 PRIV(ucd_caseless_sets)[] = { #ifndef PCRE_INCLUDED -const ucd_record PRIV(ucd_records)[] = { /* 5024 bytes, record size 8 */ +const ucd_record PRIV(ucd_records)[] = { /* 5016 bytes, record size 8 */ { 9, 0, 2, 0, 0, }, /* 0 */ { 9, 0, 1, 0, 0, }, /* 1 */ { 9, 0, 0, 0, 0, }, /* 2 */ @@ -422,7 +422,7 @@ const ucd_record PRIV(ucd_records)[] = { /* 5024 bytes, record size 8 */ { 37, 21, 12, 0, 0, }, /* 339 */ { 37, 17, 12, 0, 0, }, /* 340 */ { 37, 12, 3, 0, 0, }, /* 341 */ - { 37, 29, 12, 0, 0, }, /* 342 */ + { 37, 1, 2, 0, 0, }, /* 342 */ { 37, 13, 12, 0, 0, }, /* 343 */ { 37, 7, 12, 0, 0, }, /* 344 */ { 37, 6, 12, 0, 0, }, /* 345 */ @@ -598,116 +598,115 @@ const ucd_record PRIV(ucd_records)[] = { /* 5024 bytes, record size 8 */ { 83, 10, 5, 0, 0, }, /* 515 */ { 83, 7, 12, 0, 0, }, /* 516 */ { 83, 21, 12, 0, 0, }, /* 517 */ - { 83, 6, 12, 0, 0, }, /* 518 */ - { 83, 13, 12, 0, 0, }, /* 519 */ - { 67, 7, 12, 0, 0, }, /* 520 */ - { 67, 12, 3, 0, 0, }, /* 521 */ - { 67, 10, 5, 0, 0, }, /* 522 */ - { 67, 13, 12, 0, 0, }, /* 523 */ - { 67, 21, 12, 0, 0, }, /* 524 */ - { 38, 6, 12, 0, 0, }, /* 525 */ - { 91, 7, 12, 0, 0, }, /* 526 */ - { 91, 12, 3, 0, 0, }, /* 527 */ - { 91, 6, 12, 0, 0, }, /* 528 */ - { 91, 21, 12, 0, 0, }, /* 529 */ - { 86, 7, 12, 0, 0, }, /* 530 */ - { 86, 10, 5, 0, 0, }, /* 531 */ - { 86, 12, 3, 0, 0, }, /* 532 */ - { 86, 21, 12, 0, 0, }, /* 533 */ - { 86, 6, 12, 0, 0, }, /* 534 */ - { 86, 13, 12, 0, 0, }, /* 535 */ - { 23, 7, 9, 0, 0, }, /* 536 */ - { 23, 7, 10, 0, 0, }, /* 537 */ - { 9, 4, 2, 0, 0, }, /* 538 */ - { 9, 3, 12, 0, 0, }, /* 539 */ - { 25, 25, 12, 0, 0, }, /* 540 */ - { 0, 24, 12, 0, 0, }, /* 541 */ - { 9, 6, 3, 0, 0, }, /* 542 */ - { 35, 7, 12, 0, 0, }, /* 543 */ - { 19, 14, 12, 0, 0, }, /* 544 */ - { 19, 15, 12, 0, 0, }, /* 545 */ - { 19, 26, 12, 0, 0, }, /* 546 */ - { 70, 7, 12, 0, 0, }, /* 547 */ - { 66, 7, 12, 0, 0, }, /* 548 */ - { 41, 7, 12, 0, 0, }, /* 549 */ - { 41, 15, 12, 0, 0, }, /* 550 */ - { 18, 7, 12, 0, 0, }, /* 551 */ - { 18, 14, 12, 0, 0, }, /* 552 */ - { 59, 7, 12, 0, 0, }, /* 553 */ - { 59, 21, 12, 0, 0, }, /* 554 */ - { 42, 7, 12, 0, 0, }, /* 555 */ - { 42, 21, 12, 0, 0, }, /* 556 */ - { 42, 14, 12, 0, 0, }, /* 557 */ - { 13, 9, 12, 0, 40, }, /* 558 */ - { 13, 5, 12, 0, -40, }, /* 559 */ - { 46, 7, 12, 0, 0, }, /* 560 */ - { 44, 7, 12, 0, 0, }, /* 561 */ - { 44, 13, 12, 0, 0, }, /* 562 */ - { 11, 7, 12, 0, 0, }, /* 563 */ - { 80, 7, 12, 0, 0, }, /* 564 */ - { 80, 21, 12, 0, 0, }, /* 565 */ - { 80, 15, 12, 0, 0, }, /* 566 */ - { 65, 7, 12, 0, 0, }, /* 567 */ - { 65, 15, 12, 0, 0, }, /* 568 */ - { 65, 21, 12, 0, 0, }, /* 569 */ - { 71, 7, 12, 0, 0, }, /* 570 */ - { 71, 21, 12, 0, 0, }, /* 571 */ - { 97, 7, 12, 0, 0, }, /* 572 */ - { 96, 7, 12, 0, 0, }, /* 573 */ - { 30, 7, 12, 0, 0, }, /* 574 */ - { 30, 12, 3, 0, 0, }, /* 575 */ - { 30, 15, 12, 0, 0, }, /* 576 */ - { 30, 21, 12, 0, 0, }, /* 577 */ - { 87, 7, 12, 0, 0, }, /* 578 */ - { 87, 15, 12, 0, 0, }, /* 579 */ - { 87, 21, 12, 0, 0, }, /* 580 */ - { 77, 7, 12, 0, 0, }, /* 581 */ - { 77, 21, 12, 0, 0, }, /* 582 */ - { 82, 7, 12, 0, 0, }, /* 583 */ - { 82, 15, 12, 0, 0, }, /* 584 */ - { 81, 7, 12, 0, 0, }, /* 585 */ - { 81, 15, 12, 0, 0, }, /* 586 */ - { 88, 7, 12, 0, 0, }, /* 587 */ - { 0, 15, 12, 0, 0, }, /* 588 */ - { 93, 10, 5, 0, 0, }, /* 589 */ - { 93, 12, 3, 0, 0, }, /* 590 */ - { 93, 7, 12, 0, 0, }, /* 591 */ - { 93, 21, 12, 0, 0, }, /* 592 */ - { 93, 15, 12, 0, 0, }, /* 593 */ - { 93, 13, 12, 0, 0, }, /* 594 */ - { 84, 12, 3, 0, 0, }, /* 595 */ - { 84, 10, 5, 0, 0, }, /* 596 */ - { 84, 7, 12, 0, 0, }, /* 597 */ - { 84, 21, 12, 0, 0, }, /* 598 */ - { 84, 1, 2, 0, 0, }, /* 599 */ - { 100, 7, 12, 0, 0, }, /* 600 */ - { 100, 13, 12, 0, 0, }, /* 601 */ - { 95, 12, 3, 0, 0, }, /* 602 */ - { 95, 7, 12, 0, 0, }, /* 603 */ - { 95, 10, 5, 0, 0, }, /* 604 */ - { 95, 13, 12, 0, 0, }, /* 605 */ - { 95, 21, 12, 0, 0, }, /* 606 */ - { 99, 12, 3, 0, 0, }, /* 607 */ - { 99, 10, 5, 0, 0, }, /* 608 */ - { 99, 7, 12, 0, 0, }, /* 609 */ - { 99, 21, 12, 0, 0, }, /* 610 */ - { 99, 13, 12, 0, 0, }, /* 611 */ - { 101, 7, 12, 0, 0, }, /* 612 */ - { 101, 12, 3, 0, 0, }, /* 613 */ - { 101, 10, 5, 0, 0, }, /* 614 */ - { 101, 13, 12, 0, 0, }, /* 615 */ - { 62, 7, 12, 0, 0, }, /* 616 */ - { 62, 14, 12, 0, 0, }, /* 617 */ - { 62, 21, 12, 0, 0, }, /* 618 */ - { 79, 7, 12, 0, 0, }, /* 619 */ - { 98, 7, 12, 0, 0, }, /* 620 */ - { 98, 10, 5, 0, 0, }, /* 621 */ - { 98, 12, 3, 0, 0, }, /* 622 */ - { 98, 6, 12, 0, 0, }, /* 623 */ - { 9, 10, 3, 0, 0, }, /* 624 */ - { 19, 12, 3, 0, 0, }, /* 625 */ - { 9, 26, 11, 0, 0, }, /* 626 */ - { 26, 26, 12, 0, 0, }, /* 627 */ + { 83, 13, 12, 0, 0, }, /* 518 */ + { 67, 7, 12, 0, 0, }, /* 519 */ + { 67, 12, 3, 0, 0, }, /* 520 */ + { 67, 10, 5, 0, 0, }, /* 521 */ + { 67, 13, 12, 0, 0, }, /* 522 */ + { 67, 21, 12, 0, 0, }, /* 523 */ + { 38, 6, 12, 0, 0, }, /* 524 */ + { 91, 7, 12, 0, 0, }, /* 525 */ + { 91, 12, 3, 0, 0, }, /* 526 */ + { 91, 6, 12, 0, 0, }, /* 527 */ + { 91, 21, 12, 0, 0, }, /* 528 */ + { 86, 7, 12, 0, 0, }, /* 529 */ + { 86, 10, 5, 0, 0, }, /* 530 */ + { 86, 12, 3, 0, 0, }, /* 531 */ + { 86, 21, 12, 0, 0, }, /* 532 */ + { 86, 6, 12, 0, 0, }, /* 533 */ + { 86, 13, 12, 0, 0, }, /* 534 */ + { 23, 7, 9, 0, 0, }, /* 535 */ + { 23, 7, 10, 0, 0, }, /* 536 */ + { 9, 4, 2, 0, 0, }, /* 537 */ + { 9, 3, 12, 0, 0, }, /* 538 */ + { 25, 25, 12, 0, 0, }, /* 539 */ + { 0, 24, 12, 0, 0, }, /* 540 */ + { 9, 6, 3, 0, 0, }, /* 541 */ + { 35, 7, 12, 0, 0, }, /* 542 */ + { 19, 14, 12, 0, 0, }, /* 543 */ + { 19, 15, 12, 0, 0, }, /* 544 */ + { 19, 26, 12, 0, 0, }, /* 545 */ + { 70, 7, 12, 0, 0, }, /* 546 */ + { 66, 7, 12, 0, 0, }, /* 547 */ + { 41, 7, 12, 0, 0, }, /* 548 */ + { 41, 15, 12, 0, 0, }, /* 549 */ + { 18, 7, 12, 0, 0, }, /* 550 */ + { 18, 14, 12, 0, 0, }, /* 551 */ + { 59, 7, 12, 0, 0, }, /* 552 */ + { 59, 21, 12, 0, 0, }, /* 553 */ + { 42, 7, 12, 0, 0, }, /* 554 */ + { 42, 21, 12, 0, 0, }, /* 555 */ + { 42, 14, 12, 0, 0, }, /* 556 */ + { 13, 9, 12, 0, 40, }, /* 557 */ + { 13, 5, 12, 0, -40, }, /* 558 */ + { 46, 7, 12, 0, 0, }, /* 559 */ + { 44, 7, 12, 0, 0, }, /* 560 */ + { 44, 13, 12, 0, 0, }, /* 561 */ + { 11, 7, 12, 0, 0, }, /* 562 */ + { 80, 7, 12, 0, 0, }, /* 563 */ + { 80, 21, 12, 0, 0, }, /* 564 */ + { 80, 15, 12, 0, 0, }, /* 565 */ + { 65, 7, 12, 0, 0, }, /* 566 */ + { 65, 15, 12, 0, 0, }, /* 567 */ + { 65, 21, 12, 0, 0, }, /* 568 */ + { 71, 7, 12, 0, 0, }, /* 569 */ + { 71, 21, 12, 0, 0, }, /* 570 */ + { 97, 7, 12, 0, 0, }, /* 571 */ + { 96, 7, 12, 0, 0, }, /* 572 */ + { 30, 7, 12, 0, 0, }, /* 573 */ + { 30, 12, 3, 0, 0, }, /* 574 */ + { 30, 15, 12, 0, 0, }, /* 575 */ + { 30, 21, 12, 0, 0, }, /* 576 */ + { 87, 7, 12, 0, 0, }, /* 577 */ + { 87, 15, 12, 0, 0, }, /* 578 */ + { 87, 21, 12, 0, 0, }, /* 579 */ + { 77, 7, 12, 0, 0, }, /* 580 */ + { 77, 21, 12, 0, 0, }, /* 581 */ + { 82, 7, 12, 0, 0, }, /* 582 */ + { 82, 15, 12, 0, 0, }, /* 583 */ + { 81, 7, 12, 0, 0, }, /* 584 */ + { 81, 15, 12, 0, 0, }, /* 585 */ + { 88, 7, 12, 0, 0, }, /* 586 */ + { 0, 15, 12, 0, 0, }, /* 587 */ + { 93, 10, 5, 0, 0, }, /* 588 */ + { 93, 12, 3, 0, 0, }, /* 589 */ + { 93, 7, 12, 0, 0, }, /* 590 */ + { 93, 21, 12, 0, 0, }, /* 591 */ + { 93, 15, 12, 0, 0, }, /* 592 */ + { 93, 13, 12, 0, 0, }, /* 593 */ + { 84, 12, 3, 0, 0, }, /* 594 */ + { 84, 10, 5, 0, 0, }, /* 595 */ + { 84, 7, 12, 0, 0, }, /* 596 */ + { 84, 21, 12, 0, 0, }, /* 597 */ + { 84, 1, 2, 0, 0, }, /* 598 */ + { 100, 7, 12, 0, 0, }, /* 599 */ + { 100, 13, 12, 0, 0, }, /* 600 */ + { 95, 12, 3, 0, 0, }, /* 601 */ + { 95, 7, 12, 0, 0, }, /* 602 */ + { 95, 10, 5, 0, 0, }, /* 603 */ + { 95, 13, 12, 0, 0, }, /* 604 */ + { 95, 21, 12, 0, 0, }, /* 605 */ + { 99, 12, 3, 0, 0, }, /* 606 */ + { 99, 10, 5, 0, 0, }, /* 607 */ + { 99, 7, 12, 0, 0, }, /* 608 */ + { 99, 21, 12, 0, 0, }, /* 609 */ + { 99, 13, 12, 0, 0, }, /* 610 */ + { 101, 7, 12, 0, 0, }, /* 611 */ + { 101, 12, 3, 0, 0, }, /* 612 */ + { 101, 10, 5, 0, 0, }, /* 613 */ + { 101, 13, 12, 0, 0, }, /* 614 */ + { 62, 7, 12, 0, 0, }, /* 615 */ + { 62, 14, 12, 0, 0, }, /* 616 */ + { 62, 21, 12, 0, 0, }, /* 617 */ + { 79, 7, 12, 0, 0, }, /* 618 */ + { 98, 7, 12, 0, 0, }, /* 619 */ + { 98, 10, 5, 0, 0, }, /* 620 */ + { 98, 12, 3, 0, 0, }, /* 621 */ + { 98, 6, 12, 0, 0, }, /* 622 */ + { 9, 10, 3, 0, 0, }, /* 623 */ + { 19, 12, 3, 0, 0, }, /* 624 */ + { 9, 26, 11, 0, 0, }, /* 625 */ + { 26, 26, 12, 0, 0, }, /* 626 */ }; const pcre_uint8 PRIV(ucd_stage1)[] = { /* 8704 bytes */ @@ -1380,7 +1379,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ /* block 12 */ 185,185,185,185,185,109,186,186,186,187,187,188, 4,187,189,189, -190,190,190,190,190,190,190,190,190,190,190, 4,109,109,187, 4, +190,190,190,190,190,190,190,190,190,190,190, 4,185,109,187, 4, 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, 102,191,191,191,191,191,191,191,191,191,191,104,104,104,104,104, @@ -1760,7 +1759,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ /* block 50 */ 360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, -360,360,360,360,360,360,360,361,361,362,362,362,109,109,363,363, +360,360,360,360,360,360,360,361,361,362,362,361,109,109,363,363, 364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364, 364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364, 364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364, @@ -1885,7 +1884,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 21, 25, 4, 4, 4, 4, 15, 15, 4, 4, 4, 8, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 15, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, - 22, 22, 22, 22, 22,426,426,426,426,426, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22,426, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,101,109,109, 23, 23, 23, 23, 23, 23, 8, 8, 8, 6, 7,101, /* block 63 */ @@ -1929,7 +1928,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* block 67 */ - 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 6, 7, 6, 7, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 19, 19, 19, 19, 19, 19, 19, 6, 7, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, @@ -2353,30 +2352,30 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516, 516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516, 516,516,516,514,515,515,514,514,514,514,515,515,514,515,515,515, -515,517,517,517,517,517,517,517,517,517,517,517,517,517,109,518, -519,519,519,519,519,519,519,519,519,519,109,109,109,109,517,517, +515,517,517,517,517,517,517,517,517,517,517,517,517,517,109,102, +518,518,518,518,518,518,518,518,518,518,109,109,109,109,517,517, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 110 */ -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,521,521,521,521,521,521,522, -522,521,521,522,522,521,521,109,109,109,109,109,109,109,109,109, -520,520,520,521,520,520,520,520,520,520,520,520,521,522,109,109, -523,523,523,523,523,523,523,523,523,523,109,109,524,524,524,524, +519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, +519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, +519,519,519,519,519,519,519,519,519,520,520,520,520,520,520,521, +521,520,520,521,521,520,520,109,109,109,109,109,109,109,109,109, +519,519,519,520,519,519,519,519,519,519,519,519,520,521,109,109, +522,522,522,522,522,522,522,522,522,522,109,109,523,523,523,523, 295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295, -525,295,295,295,295,295,295,301,301,301,295,296,109,109,109,109, +524,295,295,295,295,295,295,301,301,301,295,296,109,109,109,109, /* block 111 */ -526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526, -526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526, -526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526, -527,526,527,527,527,526,526,527,527,526,526,526,526,526,527,527, -526,527,526,109,109,109,109,109,109,109,109,109,109,109,109,109, -109,109,109,109,109,109,109,109,109,109,109,526,526,528,529,529, -530,530,530,530,530,530,530,530,530,530,530,531,532,532,531,531, -533,533,530,534,534,531,532,109,109,109,109,109,109,109,109,109, +525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525, +525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525, +525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525, +526,525,526,526,526,525,525,526,526,525,525,525,525,525,526,526, +525,526,525,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,525,525,527,528,528, +529,529,529,529,529,529,529,529,529,529,529,530,531,531,530,530, +532,532,529,533,533,530,531,109,109,109,109,109,109,109,109,109, /* block 112 */ 109,308,308,308,308,308,308,109,109,308,308,308,308,308,308,109, @@ -2393,85 +2392,85 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, -530,530,530,531,531,532,531,531,532,531,531,533,531,532,109,109, -535,535,535,535,535,535,535,535,535,535,109,109,109,109,109,109, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,530,530,531,530,530,531,530,530,532,530,531,109,109, +534,534,534,534,534,534,534,534,534,534,109,109,109,109,109,109, /* block 114 */ -536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, /* block 115 */ -537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537, +536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536, /* block 116 */ -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, /* block 117 */ -537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537, +536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536, /* block 118 */ -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, /* block 119 */ -537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537, +536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536, /* block 120 */ -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, /* block 121 */ -537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537, -537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, -537,537,537,537,109,109,109,109,109,109,109,109,109,109,109,109, +536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536, +536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, +536,536,536,536,109,109,109,109,109,109,109,109,109,109,109,109, 306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306, 306,306,306,306,306,306,306,109,109,109,109,307,307,307,307,307, 307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307, @@ -2479,24 +2478,24 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 307,307,307,307,307,307,307,307,307,307,307,307,109,109,109,109, /* block 122 */ -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, /* block 123 */ -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, /* block 124 */ 475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, @@ -2521,7 +2520,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ /* block 126 */ 33, 33, 33, 33, 33, 33, 33,109,109,109,109,109,109,109,109,109, 109,109,109,178,178,178,178,178,109,109,109,109,109,184,181,184, -184,184,184,184,184,184,184,184,184,540,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,539,184,184,184,184,184,184, 184,184,184,184,184,184,184,109,184,184,184,184,184,109,184,109, 184,184,109,184,184,109,184,184,184,184,184,184,184,184,184,184, 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, @@ -2532,8 +2531,8 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, -191,191,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +191,191,540,540,540,540,540,540,540,540,540,540,540,540,540,540, +540,540,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,191,191,191,191,191,191,191,191,191,191,191,191,191, 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, @@ -2600,7 +2599,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ /* block 134 */ 469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469, -469,469,469,469,469,469,469,469,469,469,469,469,469,469,542,542, +469,469,469,469,469,469,469,469,469,469,469,469,469,469,541,541, 472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, 472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,109, 109,109,472,472,472,472,472,472,109,109,472,472,472,472,472,472, @@ -2609,37 +2608,37 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 426,426,426,426,426,426,426,426,426, 22, 22, 22, 19, 19,109,109, /* block 135 */ -543,543,543,543,543,543,543,543,543,543,543,543,109,543,543,543, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, -543,543,543,543,543,543,543,109,543,543,543,543,543,543,543,543, -543,543,543,543,543,543,543,543,543,543,543,109,543,543,109,543, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,109,109, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,109,109, +542,542,542,542,542,542,542,542,542,542,542,542,109,542,542,542, +542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542, +542,542,542,542,542,542,542,109,542,542,542,542,542,542,542,542, +542,542,542,542,542,542,542,542,542,542,542,109,542,542,109,542, +542,542,542,542,542,542,542,542,542,542,542,542,542,542,109,109, +542,542,542,542,542,542,542,542,542,542,542,542,542,542,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 136 */ -543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, -543,543,543,543,543,543,543,543,543,543,543,109,109,109,109,109, +542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542, +542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542, +542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542, +542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542, +542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542, +542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542, +542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542, +542,542,542,542,542,542,542,542,542,542,542,109,109,109,109,109, /* block 137 */ 4, 4, 4,109,109,109,109, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,109,109,109, 19, 19, 19, 19, 19, 19, 19, 19, 19, -544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, -544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, -544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, -544,544,544,544,544,545,545,545,545,546,546,546,546,546,546,546, +543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, +543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, +543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, +543,543,543,543,543,544,544,544,544,545,545,545,545,545,545,545, /* block 138 */ -546,546,546,546,546,546,546,546,546,546,545,109,109,109,109,109, +545,545,545,545,545,545,545,545,545,545,544,109,109,109,109,109, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, @@ -2649,49 +2648,49 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,104,109,109, /* block 139 */ +546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546, +546,546,546,546,546,546,546,546,546,546,546,546,546,109,109,109, 547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547, -547,547,547,547,547,547,547,547,547,547,547,547,547,109,109,109, -548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548, -548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548, -548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548, -548,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547, +547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547, +547,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 140 */ -549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549, -549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,109, -550,550,550,550,109,109,109,109,109,109,109,109,109,109,109,109, -551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551, -551,552,551,551,551,551,551,551,551,551,552,109,109,109,109,109, +548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548, +548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,109, +549,549,549,549,109,109,109,109,109,109,109,109,109,109,109,109, +550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550, +550,551,550,550,550,550,550,550,550,550,551,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 141 */ -553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, -553,553,553,553,553,553,553,553,553,553,553,553,553,553,109,554, -555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555, -555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555, -555,555,555,555,109,109,109,109,555,555,555,555,555,555,555,555, -556,557,557,557,557,557,109,109,109,109,109,109,109,109,109,109, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,109,553, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,109,109,109,109,554,554,554,554,554,554,554,554, +555,556,556,556,556,556,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 142 */ +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,558,558,558,558,558,558,558,558, 558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, 558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, -558,558,558,558,558,558,558,558,559,559,559,559,559,559,559,559, 559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, 559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, -560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, -560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, -560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, /* block 143 */ -561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, -561,561,561,561,561,561,561,561,561,561,561,561,561,561,109,109, -562,562,562,562,562,562,562,562,562,562,109,109,109,109,109,109, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,109,109, +561,561,561,561,561,561,561,561,561,561,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, @@ -2699,61 +2698,61 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 144 */ -563,563,563,563,563,563,109,109,563,109,563,563,563,563,563,563, +562,562,562,562,562,562,109,109,562,109,562,562,562,562,562,562, +562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, +562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, +562,562,562,562,562,562,109,562,562,109,109,109,562,109,109,562, 563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563,563,563,563,563,563,109,563,563,109,109,109,563,109,109,563, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,109,565,566,566,566,566,566,566,566,566, +563,563,563,563,563,563,109,564,565,565,565,565,565,565,565,565, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 145 */ -567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567, -567,567,567,567,567,567,568,568,568,568,568,568,109,109,109,569, -570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570, -570,570,570,570,570,570,570,570,570,570,109,109,109,109,109,571, +566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566, +566,566,566,566,566,566,567,567,567,567,567,567,109,109,109,568, +569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, +569,569,569,569,569,569,569,569,569,569,109,109,109,109,109,570, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 146 */ +571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571, +571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571, 572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, -572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, -573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, -573,573,573,573,573,573,573,573,109,109,109,109,109,109,573,573, +572,572,572,572,572,572,572,572,109,109,109,109,109,109,572,572, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 147 */ -574,575,575,575,109,575,575,109,109,109,109,109,575,575,575,575, -574,574,574,574,109,574,574,574,109,574,574,574,574,574,574,574, -574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574, -574,574,574,574,109,109,109,109,575,575,575,109,109,109,109,575, -576,576,576,576,576,576,576,576,109,109,109,109,109,109,109,109, -577,577,577,577,577,577,577,577,577,109,109,109,109,109,109,109, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,579,579,580, +573,574,574,574,109,574,574,109,109,109,109,109,574,574,574,574, +573,573,573,573,109,573,573,573,109,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,109,109,109,109,574,574,574,109,109,109,109,574, +575,575,575,575,575,575,575,575,109,109,109,109,109,109,109,109, +576,576,576,576,576,576,576,576,576,109,109,109,109,109,109,109, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,578,578,579, /* block 148 */ -581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, -581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, -581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, -581,581,581,581,581,581,109,109,109,582,582,582,582,582,582,582, -583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583, -583,583,583,583,583,583,109,109,584,584,584,584,584,584,584,584, -585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585, -585,585,585,109,109,109,109,109,586,586,586,586,586,586,586,586, +580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, +580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, +580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, +580,580,580,580,580,580,109,109,109,581,581,581,581,581,581,581, +582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582, +582,582,582,582,582,582,109,109,583,583,583,583,583,583,583,583, +584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, +584,584,584,109,109,109,109,109,585,585,585,585,585,585,585,585, /* block 149 */ -587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, -587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, -587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, -587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, -587,587,587,587,587,587,587,587,587,109,109,109,109,109,109,109, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, @@ -2765,103 +2764,103 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, -588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588, -588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,109, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,109, /* block 151 */ -589,590,589,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,590,590,590,590,590,590,590,590, -590,590,590,590,590,590,590,592,592,592,592,592,592,592,109,109, -109,109,593,593,593,593,593,593,593,593,593,593,593,593,593,593, -593,593,593,593,593,593,594,594,594,594,594,594,594,594,594,594, +588,589,588,590,590,590,590,590,590,590,590,590,590,590,590,590, +590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590, +590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590, +590,590,590,590,590,590,590,590,589,589,589,589,589,589,589,589, +589,589,589,589,589,589,589,591,591,591,591,591,591,591,109,109, +109,109,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,593,593,593,593,593,593,593,593,593,593, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 152 */ -595,595,596,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -596,596,596,595,595,595,595,596,596,595,595,598,598,599,598,598, -598,598,109,109,109,109,109,109,109,109,109,109,109,109,109,109, -600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600, -600,600,600,600,600,600,600,600,600,109,109,109,109,109,109,109, -601,601,601,601,601,601,601,601,601,601,109,109,109,109,109,109, +594,594,595,596,596,596,596,596,596,596,596,596,596,596,596,596, +596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596, +596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596, +595,595,595,594,594,594,594,595,595,594,594,597,597,598,597,597, +597,597,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599, +599,599,599,599,599,599,599,599,599,109,109,109,109,109,109,109, +600,600,600,600,600,600,600,600,600,600,109,109,109,109,109,109, /* block 153 */ -602,602,602,603,603,603,603,603,603,603,603,603,603,603,603,603, -603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603, -603,603,603,603,603,603,603,602,602,602,602,602,604,602,602,602, -602,602,602,602,602,109,605,605,605,605,605,605,605,605,605,605, -606,606,606,606,109,109,109,109,109,109,109,109,109,109,109,109, +601,601,601,602,602,602,602,602,602,602,602,602,602,602,602,602, +602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602, +602,602,602,602,602,602,602,601,601,601,601,601,603,601,601,601, +601,601,601,601,601,109,604,604,604,604,604,604,604,604,604,604, +605,605,605,605,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 154 */ -607,607,608,609,609,609,609,609,609,609,609,609,609,609,609,609, -609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609, -609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609, -609,609,609,608,608,608,607,607,607,607,607,607,607,607,607,608, -608,609,609,609,609,610,610,610,610,109,109,109,109,109,109,109, -611,611,611,611,611,611,611,611,611,611,109,109,109,109,109,109, +606,606,607,608,608,608,608,608,608,608,608,608,608,608,608,608, +608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608, +608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608, +608,608,608,607,607,607,606,606,606,606,606,606,606,606,606,607, +607,608,608,608,608,609,609,609,609,109,109,109,109,109,109,109, +610,610,610,610,610,610,610,610,610,610,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 155 */ -612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612, -612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612, -612,612,612,612,612,612,612,612,612,612,612,613,614,613,614,614, -613,613,613,613,613,613,614,613,109,109,109,109,109,109,109,109, -615,615,615,615,615,615,615,615,615,615,109,109,109,109,109,109, +611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611, +611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611, +611,611,611,611,611,611,611,611,611,611,611,612,613,612,613,613, +612,612,612,612,612,612,613,612,109,109,109,109,109,109,109,109, +614,614,614,614,614,614,614,614,614,614,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 156 */ -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, /* block 157 */ -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,109, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, +615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 158 */ -617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617, -617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617, -617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617, -617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617, -617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617, -617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617, -617,617,617,109,109,109,109,109,109,109,109,109,109,109,109,109, -618,618,618,618,109,109,109,109,109,109,109,109,109,109,109,109, +616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, +616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, +616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, +616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, +616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, +616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616, +616,616,616,109,109,109,109,109,109,109,109,109,109,109,109,109, +617,617,617,617,109,109,109,109,109,109,109,109,109,109,109,109, /* block 159 */ -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, /* block 160 */ -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,109, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, +618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, @@ -2889,18 +2888,18 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 163 */ +619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, +619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, +619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, +619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, +619,619,619,619,619,109,109,109,109,109,109,109,109,109,109,109, +619,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, 620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, -620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, -620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, -620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, -620,620,620,620,620,109,109,109,109,109,109,109,109,109,109,109, -620,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621, -621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621, -621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,109, +620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,109, /* block 164 */ -109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,622, -622,622,622,623,623,623,623,623,623,623,623,623,623,623,623,623, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,621, +621,621,621,622,622,622,622,622,622,622,622,622,622,622,622,622, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, @@ -2935,8 +2934,8 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19,624,395,104,104,104, 19, 19, 19,395,624,624, -624,624,624, 22, 22, 22, 22, 22, 22, 22, 22,104,104,104,104,104, + 19, 19, 19, 19, 19,623,395,104,104,104, 19, 19, 19,395,623,623, +623,623,623, 22, 22, 22, 22, 22, 22, 22, 22,104,104,104,104,104, /* block 168 */ 104,104,104, 19, 19,104,104,104,104,104,104,104, 19, 19, 19, 19, @@ -2949,11 +2948,11 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, /* block 169 */ -546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546, -546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546, -546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546, -546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546, -546,546,625,625,625,546,109,109,109,109,109,109,109,109,109,109, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,624,624,624,545,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, @@ -3105,11 +3104,11 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, -109,109,109,109,109,109,626,626,626,626,626,626,626,626,626,626, -626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626, +109,109,109,109,109,109,625,625,625,625,625,625,625,625,625,625, +625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625, /* block 185 */ -627, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,109, +626, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,109, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109, @@ -3279,14 +3278,14 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */ 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, /* block 202 */ -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,109,109, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,109,109, }; diff --git a/tools/pcre/pcre_valid_utf8.c b/tools/pcre/pcre_valid_utf8.c index a4159275..3b0f6464 100644 --- a/tools/pcre/pcre_valid_utf8.c +++ b/tools/pcre/pcre_valid_utf8.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2013 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -92,7 +92,7 @@ PCRE_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur) PCRE_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur) PCRE_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character) PCRE_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff -PCRE_UTF8_ERR22 Non-character +PCRE_UTF8_ERR22 Unused (was non-character) Arguments: string points to the string @@ -118,7 +118,6 @@ if (length < 0) for (p = string; length-- > 0; p++) { register pcre_uchar ab, c, d; - pcre_uint32 v = 0; c = *p; if (c < 128) continue; /* ASCII character */ @@ -187,7 +186,6 @@ for (p = string; length-- > 0; p++) *erroroffset = (int)(p - string) - 2; return PCRE_UTF8_ERR14; } - v = ((c & 0x0f) << 12) | ((d & 0x3f) << 6) | (*p & 0x3f); break; /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2 @@ -215,7 +213,6 @@ for (p = string; length-- > 0; p++) *erroroffset = (int)(p - string) - 3; return PCRE_UTF8_ERR13; } - v = ((c & 0x07) << 18) | ((d & 0x3f) << 12) | ((p[-1] & 0x3f) << 6) | (*p & 0x3f); break; /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be @@ -290,14 +287,6 @@ for (p = string; length-- > 0; p++) *erroroffset = (int)(p - string) - ab; return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12; } - - /* Reject non-characters. The pointer p is currently at the last byte of the - character. */ - if ((v & 0xfffeu) == 0xfffeu || (v >= 0xfdd0 && v <= 0xfdef)) - { - *erroroffset = (int)(p - string) - ab; - return PCRE_UTF8_ERR22; - } } #else /* Not SUPPORT_UTF */ diff --git a/tools/pcre/pcre_xclass.c b/tools/pcre/pcre_xclass.c index fa73cd8c..c2b61f0f 100644 --- a/tools/pcre/pcre_xclass.c +++ b/tools/pcre/pcre_xclass.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2013 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -81,6 +81,11 @@ additional data. */ if (c < 256) { + if ((*data & XCL_HASPROP) == 0) + { + if ((*data & XCL_MAP) == 0) return negated; + return (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0; + } if ((*data & XCL_MAP) != 0 && (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0) return !negated; /* char found */ @@ -128,55 +133,120 @@ while ((t = *data++) != XCL_END) else /* XCL_PROP & XCL_NOTPROP */ { const ucd_record *prop = GET_UCD(c); + BOOL isprop = t == XCL_PROP; switch(*data) { case PT_ANY: - if (t == XCL_PROP) return !negated; + if (isprop) return !negated; break; case PT_LAMP: if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt) == (t == XCL_PROP)) return !negated; + prop->chartype == ucp_Lt) == isprop) return !negated; break; case PT_GC: - if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP)) + if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop) return !negated; break; case PT_PC: - if ((data[1] == prop->chartype) == (t == XCL_PROP)) return !negated; + if ((data[1] == prop->chartype) == isprop) return !negated; break; case PT_SC: - if ((data[1] == prop->script) == (t == XCL_PROP)) return !negated; + if ((data[1] == prop->script) == isprop) return !negated; break; case PT_ALNUM: if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP)) + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop) return !negated; break; + /* Perl space used to exclude VT, but from Perl 5.18 it is included, + which means that Perl space and POSIX space are now identical. PCRE + was changed at release 8.34. */ + case PT_SPACE: /* Perl space */ - 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 ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || - c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || - c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP)) - return !negated; + switch(c) + { + HSPACE_CASES: + VSPACE_CASES: + if (isprop) return !negated; + break; + + default: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop) + return !negated; + break; + } break; case PT_WORD: if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) - == (t == XCL_PROP)) + == isprop) + return !negated; + break; + + case PT_UCNC: + if (c < 0xa0) + { + if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT) == isprop) + return !negated; + } + else + { + if ((c < 0xd800 || c > 0xdfff) == isprop) + return !negated; + } + break; + + /* The following three properties can occur only in an XCLASS, as there + is no \p or \P coding for them. */ + + /* Graphic character. Implement this as not Z (space or separator) and + not C (other), except for Cf (format) with a few exceptions. This seems + to be what Perl does. The exceptional characters are: + + U+061C Arabic Letter Mark + U+180E Mongolian Vowel Separator + U+2066 - U+2069 Various "isolate"s + */ + + case PT_PXGRAPH: + if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z && + (PRIV(ucp_gentype)[prop->chartype] != ucp_C || + (prop->chartype == ucp_Cf && + c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069)) + )) == isprop) + return !negated; + break; + + /* Printable character: same as graphic, with the addition of Zs, i.e. + not Zl and not Zp, and U+180E. */ + + case PT_PXPRINT: + if ((prop->chartype != ucp_Zl && + prop->chartype != ucp_Zp && + (PRIV(ucp_gentype)[prop->chartype] != ucp_C || + (prop->chartype == ucp_Cf && + c != 0x061c && (c < 0x2066 || c > 0x2069)) + )) == isprop) + return !negated; + break; + + /* Punctuation: all Unicode punctuation, plus ASCII characters that + Unicode treats as symbols rather than punctuation, for Perl + compatibility (these are $+<=>^`|~). */ + + case PT_PXPUNCT: + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P || + (c < 256 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop) return !negated; break; diff --git a/tools/pcre/pcregrep.c b/tools/pcre/pcregrep.c index 2e0dc03f..3e8d05dc 100644 --- a/tools/pcre/pcregrep.c +++ b/tools/pcre/pcregrep.c @@ -3,10 +3,16 @@ *************************************************/ /* This is a grep program that uses the PCRE regular expression library to do -its pattern matching. On a Unix or Win32 system it can recurse into -directories. +its pattern matching. On Unix-like, Windows, and native z/OS systems it can +recurse into directories, and in z/OS it can handle PDS files. - Copyright (c) 1997-2012 University of Cambridge +Note that for native z/OS, in addition to defining the NATIVE_ZOS macro, an +additional header is required. That header is not included in the main PCRE +distribution because other apparatus is needed to compile pcregrep for z/OS. +The header can be found in the special z/OS distribution, which is available +from www.zaconsultants.net or from www.cbttape.org. + + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -530,17 +536,29 @@ while (fn != NULL) * OS-specific functions * *************************************************/ -/* These functions are defined so that they can be made system specific, -although at present the only ones are for Unix, Win32, and for "no support". */ +/* These functions are defined so that they can be made system specific. +At present there are versions for Unix-style environments, Windows, native +z/OS, and "no support". */ -/************* Directory scanning in Unix ***********/ +/************* Directory scanning Unix-style and z/OS ***********/ -#if defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H +#if (defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H) || defined NATIVE_ZOS #include #include #include +#if defined NATIVE_ZOS +/************* Directory and PDS/E scanning for z/OS ***********/ +/************* z/OS looks mostly like Unix with USS ************/ +/* However, z/OS needs the #include statements in this header */ +#include "pcrzosfs.h" +/* That header is not included in the main PCRE distribution because + other apparatus is needed to compile pcregrep for z/OS. The header + can be found in the special z/OS distribution, which is available + from www.zaconsultants.net or from www.cbttape.org. */ +#endif + typedef DIR directory_type; #define FILESEP '/' @@ -579,7 +597,7 @@ closedir(dir); } -/************* Test for regular file in Unix **********/ +/************* Test for regular file, Unix-style **********/ static int isregfile(char *filename) @@ -591,8 +609,26 @@ return (statbuf.st_mode & S_IFMT) == S_IFREG; } -/************* Test for a terminal in Unix **********/ +#if defined NATIVE_ZOS +/************* Test for a terminal in z/OS **********/ +/* isatty() does not work in a TSO environment, so always give FALSE.*/ +static BOOL +is_stdout_tty(void) +{ +return FALSE; +} + +static BOOL +is_file_tty(FILE *f) +{ +return FALSE; +} + + +/************* Test for a terminal, Unix-style **********/ + +#else static BOOL is_stdout_tty(void) { @@ -604,9 +640,12 @@ is_file_tty(FILE *f) { return isatty(fileno(f)); } +#endif + +/* End of Unix-style or native z/OS environment functions. */ -/************* Directory scanning in Win32 ***********/ +/************* Directory scanning in Windows ***********/ /* I (Philip Hazel) have no means of testing this code. It was contributed by Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES @@ -709,7 +748,7 @@ free(dir); } -/************* Test for regular file in Win32 **********/ +/************* Test for regular file in Windows **********/ /* I don't know how to do this, or if it can be done; assume all paths are regular if they are not directories. */ @@ -720,7 +759,7 @@ return !isdirectory(filename); } -/************* Test for a terminal in Win32 **********/ +/************* Test for a terminal in Windows **********/ /* I don't know how to do this; assume never */ @@ -736,6 +775,8 @@ is_file_tty(FILE *f) return FALSE; } +/* End of Windows functions */ + /************* Directory scanning when we can't do it ***********/ @@ -752,7 +793,7 @@ char *readdirectory(directory_type *dir) { return (char*)0;} void closedirectory(directory_type *dir) {} -/************* Test for regular when we can't do it **********/ +/************* Test for regular file when we can't do it **********/ /* Assume all files are regular. */ @@ -773,7 +814,7 @@ is_file_tty(FILE *f) return FALSE; } -#endif +#endif /* End of system-specific functions */ @@ -1257,7 +1298,7 @@ switch(endlinetype) while (p > startptr && p[-1] != '\n') p--; if (p <= startptr + 1 || p[-2] == '\r') return p; } - return p; /* But control should never get here */ + /* Control can never get here */ case EL_ANY: case EL_ANYCRLF: @@ -1378,6 +1419,7 @@ to find all possible matches. Arguments: matchptr the start of the subject length the length of the subject to match + options options for pcre_exec startoffset where to start matching offsets the offets vector to fill in mrc address of where to put the result of pcre_exec() @@ -1388,8 +1430,8 @@ Returns: TRUE if there was a match */ static BOOL -match_patterns(char *matchptr, size_t length, int startoffset, int *offsets, - int *mrc) +match_patterns(char *matchptr, size_t length, unsigned int options, + int startoffset, int *offsets, int *mrc) { int i; size_t slen = length; @@ -1404,7 +1446,7 @@ if (slen > 200) for (i = 1; p != NULL; p = p->next, i++) { *mrc = pcre_exec(p->compiled, p->hint, matchptr, (int)length, - startoffset, PCRE_NOTEMPTY, offsets, OFFSET_SIZE); + startoffset, options, 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); @@ -1539,6 +1581,7 @@ while (ptr < endptr) int endlinelength; int mrc = 0; int startoffset = 0; + unsigned int options = 0; BOOL match; char *matchptr = ptr; char *t = ptr; @@ -1628,9 +1671,12 @@ while (ptr < endptr) /* Run through all the patterns until one matches or there is an error other than NOMATCH. This code is in a subroutine so that it can be re-used for - finding subsequent matches when colouring matched lines. */ + finding subsequent matches when colouring matched lines. After finding one + match, set PCRE_NOTEMPTY to disable any further matches of null strings in + this line. */ - match = match_patterns(matchptr, length, startoffset, offsets, &mrc); + match = match_patterns(matchptr, length, options, startoffset, offsets, &mrc); + options = PCRE_NOTEMPTY; /* If it's a match or a not-match (as required), do what's wanted. */ @@ -1830,7 +1876,7 @@ while (ptr < endptr) { char *endmatch = ptr + offsets[1]; t = ptr; - while (t < endmatch) + while (t <= endmatch) { t = end_of_line(t, endptr, &endlinelength); if (t < endmatch) linenumber++; else break; @@ -1871,7 +1917,8 @@ while (ptr < endptr) { startoffset = offsets[1]; if (startoffset >= (int)linelength + endlinelength || - !match_patterns(matchptr, length, startoffset, offsets, &mrc)) + !match_patterns(matchptr, length, options, startoffset, offsets, + &mrc)) break; FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout); fprintf(stdout, "%c[%sm", 0x1b, colour_string); @@ -2062,6 +2109,11 @@ BZFILE *inbz2 = NULL; int pathlen; #endif +#if defined NATIVE_ZOS +int zos_type; +FILE *zos_test_file; +#endif + /* If the file name is "-" we scan stdin */ if (strcmp(pathname, "-") == 0) @@ -2082,6 +2134,45 @@ lastcomp = (lastcomp == NULL)? pathname : lastcomp + 1; Otherwise, scan the directory and recurse for each path within it. The scanning code is localized so it can be made system-specific. */ + +/* For z/OS, determine the file type. */ + +#if defined NATIVE_ZOS +zos_test_file = fopen(pathname,"rb"); + +if (zos_test_file == NULL) + { + if (!silent) fprintf(stderr, "pcregrep: failed to test next file %s\n", + pathname, strerror(errno)); + return -1; + } +zos_type = identifyzosfiletype (zos_test_file); +fclose (zos_test_file); + +/* Handle a PDS in separate code */ + +if (zos_type == __ZOS_PDS || zos_type == __ZOS_PDSE) + { + return travelonpdsdir (pathname, only_one_at_top); + } + +/* Deal with regular files in the normal way below. These types are: + zos_type == __ZOS_PDS_MEMBER + zos_type == __ZOS_PS + zos_type == __ZOS_VSAM_KSDS + zos_type == __ZOS_VSAM_ESDS + zos_type == __ZOS_VSAM_RRDS +*/ + +/* Handle a z/OS directory using common code. */ + +else if (zos_type == __ZOS_HFS) + { +#endif /* NATIVE_ZOS */ + + +/* Handle directories: common code for all OS */ + if (isdirectory(pathname)) { if (dee_action == dee_SKIP || @@ -2116,12 +2207,22 @@ if (isdirectory(pathname)) } } -/* If the file is not a directory and not a regular file, skip it if that's -been requested. Otherwise, check for explicit include/exclude. */ +#if defined NATIVE_ZOS + } +#endif -else if ((!isregfile(pathname) && DEE_action == DEE_SKIP) || - !test_incexc(lastcomp, include_patterns, exclude_patterns)) - return -1; +/* If the file is not a directory, check for a regular file, and if it is not, +skip it if that's been requested. Otherwise, check for an explicit inclusion or +exclusion. */ + +else if ( +#if defined NATIVE_ZOS + (zos_type == __ZOS_NOFILE && DEE_action == DEE_SKIP) || +#else /* all other OS */ + (!isregfile(pathname) && DEE_action == DEE_SKIP) || +#endif + !test_incexc(lastcomp, include_patterns, exclude_patterns)) + return -1; /* File skipped */ /* Control reaches here if we have a regular file, or if we have a directory and recursion or skipping was not requested, or if we have anything else and diff --git a/tools/pcre/pcreposix.c b/tools/pcre/pcreposix.c index 15195c0e..ed506197 100644 --- a/tools/pcre/pcreposix.c +++ b/tools/pcre/pcreposix.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2012 University of Cambridge + Copyright (c) 1997-2014 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -110,7 +110,7 @@ static const int eint[] = { REG_BADPAT, /* POSIX collating elements are not supported */ REG_INVARG, /* this version of PCRE is not compiled with PCRE_UTF8 support */ REG_BADPAT, /* spare error */ - REG_BADPAT, /* character value in \x{...} sequence is too large */ + REG_BADPAT, /* character value in \x{} or \o{} is too large */ /* 35 */ REG_BADPAT, /* invalid condition (?(0) */ REG_BADPAT, /* \C not allowed in lookbehind assertion */ @@ -162,7 +162,17 @@ static const int eint[] = { /* 75 */ REG_BADPAT, /* overlong MARK name */ REG_BADPAT, /* character value in \u.... sequence is too large */ - REG_BADPAT /* invalid UTF-32 string (should not occur) */ + REG_BADPAT, /* invalid UTF-32 string (should not occur) */ + REG_BADPAT, /* setting UTF is disabled by the application */ + REG_BADPAT, /* non-hex character in \\x{} (closing brace missing?) */ + /* 80 */ + REG_BADPAT, /* non-octal character in \o{} (closing brace missing?) */ + REG_BADPAT, /* missing opening brace after \o */ + REG_BADPAT, /* parentheses too deeply nested */ + REG_BADPAT, /* invalid range in character class */ + REG_BADPAT, /* group name must start with a non-digit */ + /* 85 */ + REG_BADPAT /* parentheses too deeply nested (stack check) */ }; /* Table of texts corresponding to POSIX error codes */ diff --git a/tools/pcre/pcretest.c b/tools/pcre/pcretest.c index 0b6c821a..b8dc3c67 100644 --- a/tools/pcre/pcretest.c +++ b/tools/pcre/pcretest.c @@ -121,6 +121,12 @@ input mode under Windows. */ #endif #endif +#ifdef __VMS +#include +void vms_setsymbol( char *, char *, int ); +#endif + + #define PRIV(name) name /* We have to include pcre_internal.h because we need the internal info for @@ -227,6 +233,9 @@ argument, the casting might be incorrectly applied. */ #define SET_PCRE_CALLOUT8(callout) \ pcre_callout = callout +#define SET_PCRE_STACK_GUARD8(stack_guard) \ + pcre_stack_guard = stack_guard + #define PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata) \ pcre_assign_jit_stack(extra, callback, userdata) @@ -311,6 +320,9 @@ argument, the casting might be incorrectly applied. */ #define SET_PCRE_CALLOUT16(callout) \ pcre16_callout = (int (*)(pcre16_callout_block *))callout +#define SET_PCRE_STACK_GUARD16(stack_guard) \ + pcre16_stack_guard = (int (*)(void))stack_guard + #define PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata) \ pcre16_assign_jit_stack((pcre16_extra *)extra, \ (pcre16_jit_callback)callback, userdata) @@ -400,6 +412,9 @@ argument, the casting might be incorrectly applied. */ #define SET_PCRE_CALLOUT32(callout) \ pcre32_callout = (int (*)(pcre32_callout_block *))callout +#define SET_PCRE_STACK_GUARD32(stack_guard) \ + pcre32_stack_guard = (int (*)(void))stack_guard + #define PCRE_ASSIGN_JIT_STACK32(extra, callback, userdata) \ pcre32_assign_jit_stack((pcre32_extra *)extra, \ (pcre32_jit_callback)callback, userdata) @@ -527,6 +542,14 @@ cases separately. */ else \ SET_PCRE_CALLOUT8(callout) +#define SET_PCRE_STACK_GUARD(stack_guard) \ + if (pcre_mode == PCRE32_MODE) \ + SET_PCRE_STACK_GUARD32(stack_guard); \ + else if (pcre_mode == PCRE16_MODE) \ + SET_PCRE_STACK_GUARD16(stack_guard); \ + else \ + SET_PCRE_STACK_GUARD8(stack_guard) + #define STRLEN(p) (pcre_mode == PCRE32_MODE ? STRLEN32(p) : pcre_mode == PCRE16_MODE ? STRLEN16(p) : STRLEN8(p)) #define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \ @@ -750,6 +773,12 @@ the three different cases. */ else \ G(SET_PCRE_CALLOUT,BITTWO)(callout) +#define SET_PCRE_STACK_GUARD(stack_guard) \ + if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \ + G(SET_PCRE_STACK_GUARD,BITONE)(stack_guard); \ + else \ + G(SET_PCRE_STACK_GUARD,BITTWO)(stack_guard) + #define STRLEN(p) ((pcre_mode == G(G(PCRE,BITONE),_MODE)) ? \ G(STRLEN,BITONE)(p) : G(STRLEN,BITTWO)(p)) @@ -891,6 +920,7 @@ the three different cases. */ #define PCHARSV PCHARSV8 #define READ_CAPTURE_NAME READ_CAPTURE_NAME8 #define SET_PCRE_CALLOUT SET_PCRE_CALLOUT8 +#define SET_PCRE_STACK_GUARD SET_PCRE_STACK_GUARD8 #define STRLEN STRLEN8 #define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK8 #define PCRE_COMPILE PCRE_COMPILE8 @@ -921,6 +951,7 @@ the three different cases. */ #define PCHARSV PCHARSV16 #define READ_CAPTURE_NAME READ_CAPTURE_NAME16 #define SET_PCRE_CALLOUT SET_PCRE_CALLOUT16 +#define SET_PCRE_STACK_GUARD SET_PCRE_STACK_GUARD16 #define STRLEN STRLEN16 #define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK16 #define PCRE_COMPILE PCRE_COMPILE16 @@ -951,6 +982,7 @@ the three different cases. */ #define PCHARSV PCHARSV32 #define READ_CAPTURE_NAME READ_CAPTURE_NAME32 #define SET_PCRE_CALLOUT SET_PCRE_CALLOUT32 +#define SET_PCRE_STACK_GUARD SET_PCRE_STACK_GUARD32 #define STRLEN STRLEN32 #define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK32 #define PCRE_COMPILE PCRE_COMPILE32 @@ -1009,9 +1041,8 @@ static int first_callout; static int jit_was_used; static int locale_set = 0; static int show_malloc; +static int stack_guard_return; 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. */ @@ -1284,7 +1315,7 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */ */ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ - 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ + 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ @@ -1316,9 +1347,9 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ -/* This is a set of tables that came orginally from a Windows user. It seems to -be at least an approximation of ISO 8859. In particular, there are characters -greater than 128 that are marked as spaces, letters, etc. */ +/* This is a set of tables that came originally from a Windows user. It seems +to 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 pcre_uint8 tables1[] = { 0,1,2,3,4,5,6,7, @@ -1790,8 +1821,7 @@ Returns: TRUE if the string is a valid UTF-32 string FALSE otherwise */ -#ifdef NEVER - +#ifdef NEVER /* Not used */ #ifdef SUPPORT_UTF static BOOL valid_utf32(pcre_uint32 *string, int length) @@ -1802,28 +1832,17 @@ register pcre_uint32 c; for (p = string; length-- > 0; p++) { c = *p; - - if (c > 0x10ffffu) - return FALSE; - - /* A surrogate */ - if ((c & 0xfffff800u) == 0xd800u) - return FALSE; - - /* Non-character */ - if ((c & 0xfffeu) == 0xfffeu || (c >= 0xfdd0u && c <= 0xfdefu)) - return FALSE; + if (c > 0x10ffffu) return FALSE; /* Too big */ + if ((c & 0xfffff800u) == 0xd800u) return FALSE; /* Surrogate */ } return TRUE; } #endif /* SUPPORT_UTF */ - #endif /* NEVER */ +#endif /* SUPPORT_PCRE32 */ -#endif - /************************************************* * Read or extend an input line * *************************************************/ @@ -1922,7 +1941,7 @@ for (;;) } } -return NULL; /* Control never gets here */ +/* Control never gets here */ } @@ -2037,9 +2056,9 @@ return yield; static int strlen16(PCRE_SPTR16 p) { -int len = 0; -while (*p++ != 0) len++; -return len; +PCRE_SPTR16 pp = p; +while (*pp != 0) pp++; +return (int)(pp - p); } #endif /* SUPPORT_PCRE16 */ @@ -2052,9 +2071,9 @@ return len; static int strlen32(PCRE_SPTR32 p) { -int len = 0; -while (*p++ != 0) len++; -return len; +PCRE_SPTR32 pp = p; +while (*pp != 0) pp++; +return (int)(pp - p); } #endif /* SUPPORT_PCRE32 */ @@ -2082,7 +2101,7 @@ while (length-- > 0) if (use_utf && c >= 0xD800 && c < 0xDC00 && length > 0) { int d = *p & 0xffff; - if (d >= 0xDC00 && d < 0xDFFF) + if (d >= 0xDC00 && d <= 0xDFFF) { c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000; length--; @@ -2208,6 +2227,18 @@ return p; +/************************************************* +* Stack guard function * +*************************************************/ + +/* Called from PCRE when set in pcre_stack_guard. We give an error (non-zero) +return when a count overflows. */ + +static int stack_guard(void) +{ +return stack_guard_return; +} + /************************************************* * Callout function * *************************************************/ @@ -2328,8 +2359,6 @@ 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; @@ -2401,7 +2430,7 @@ else rc = PCRE_ERROR_BADMODE; #endif -if (rc < 0) +if (rc < 0 && rc != PCRE_ERROR_UNSET) { fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc, pcre_mode == PCRE32_MODE ? "32" : pcre_mode == PCRE16_MODE ? "16" : "", option); @@ -2477,14 +2506,18 @@ BOOL utf16_char = FALSE; 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->flags = swap_uint32(re->flags); +re->limit_match = swap_uint32(re->limit_match); +re->limit_recursion = swap_uint32(re->limit_recursion); re->first_char = swap_uint16(re->first_char); re->req_char = swap_uint16(re->req_char); +re->max_lookbehind = swap_uint16(re->max_lookbehind); +re->top_bracket = swap_uint16(re->top_bracket); +re->top_backref = swap_uint16(re->top_backref); 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); if (extra != NULL) { @@ -2654,14 +2687,18 @@ int length = re->name_count * re->name_entry_size; 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->flags = swap_uint32(re->flags); +re->limit_match = swap_uint32(re->limit_match); +re->limit_recursion = swap_uint32(re->limit_recursion); re->first_char = swap_uint32(re->first_char); re->req_char = swap_uint32(re->req_char); +re->max_lookbehind = swap_uint16(re->max_lookbehind); +re->top_bracket = swap_uint16(re->top_bracket); +re->top_backref = swap_uint16(re->top_backref); 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); if (extra != NULL) { @@ -2825,7 +2862,7 @@ return 0; /************************************************* -* Check newline indicator * +* Check multicharacter option * *************************************************/ /* This is used both at compile and run-time to check for escapes. Print @@ -2834,12 +2871,14 @@ a message and return 0 if there is no match. Arguments: p points after the leading '<' f file for error message + nl TRUE to check only for newline settings + stype "modifier" or "escape sequence" Returns: appropriate PCRE_NEWLINE_xxx flags, or 0 */ static int -check_newline(pcre_uint8 *p, FILE *f) +check_mc_option(pcre_uint8 *p, FILE *f, BOOL nl, const char *stype) { if (strncmpic(p, (pcre_uint8 *)"cr>", 3) == 0) return PCRE_NEWLINE_CR; if (strncmpic(p, (pcre_uint8 *)"lf>", 3) == 0) return PCRE_NEWLINE_LF; @@ -2848,7 +2887,13 @@ 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); + +if (!nl) + { + if (strncmpic(p, (pcre_uint8 *)"JS>", 3) == 0) return PCRE_JAVASCRIPT_COMPAT; + } + +fprintf(f, "Unknown %s at: <%s\n", stype, p); return 0; } @@ -2877,8 +2922,8 @@ printf(" -32 use the 32-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(" -C arg show a specific compile-time option and exit\n"); +printf(" with its value if numeric (else 0). 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"); @@ -2886,7 +2931,8 @@ printf(" pcre32 32 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(" newline Newline type [CR, LF, CRLF, ANYCRLF, ANY]\n"); +printf(" bsr \\R type [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"); @@ -2895,6 +2941,7 @@ printf(" -help show usage information\n"); printf(" -i show information about compiled patterns\n" " -M find MATCH_LIMIT minimum for each subject\n" " -m output memory used information\n" + " -O set PCRE_NO_AUTO_POSSESS on each pattern\n" " -o set size of offsets vector to \n"); #if !defined NOPOSIX printf(" -p use POSIX interface\n"); @@ -2911,6 +2958,8 @@ printf(" -s force each pattern to be studied at basic level\n" printf(" -t time compilation and execution, repeating times\n"); printf(" -tm time execution (matching) only\n"); printf(" -tm time execution (matching) only, repeating times\n"); +printf(" -T same as -t, but show total times at the end\n"); +printf(" -TM same as -tm, but show total time at the end\n"); } @@ -2930,9 +2979,11 @@ const char *version; int options = 0; int study_options = 0; int default_find_match_limit = FALSE; +pcre_uint32 default_options = 0; int op = 1; int timeit = 0; int timeitm = 0; +int showtotaltimes = 0; int showinfo = 0; int showstore = 0; int force_study = -1; @@ -2948,7 +2999,11 @@ int verify_jit = 0; int yield = 0; int stack_size; pcre_uint8 *dbuffer = NULL; +pcre_uint8 lockout[24] = { 0 }; size_t dbuffer_size = 1u << 14; +clock_t total_compile_time = 0; +clock_t total_study_time = 0; +clock_t total_match_time = 0; #if !defined NOPOSIX int posix = 0; @@ -3071,6 +3126,7 @@ while (argc > 1 && argv[op][0] == '-') 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; + else if (strcmp(arg, "-O") == 0) default_options |= PCRE_NO_AUTO_POSSESS; #if !defined NODFA else if (strcmp(arg, "-dfa") == 0) all_use_dfa = 1; #endif @@ -3081,10 +3137,12 @@ while (argc > 1 && argv[op][0] == '-') op++; argc--; } - else if (strcmp(arg, "-t") == 0 || strcmp(arg, "-tm") == 0) + else if (strcmp(arg, "-t") == 0 || strcmp(arg, "-tm") == 0 || + strcmp(arg, "-T") == 0 || strcmp(arg, "-TM") == 0) { - int both = arg[2] == 0; int temp; + int both = arg[2] == 0; + showtotaltimes = arg[1] == 'T'; if (argc > 2 && (temp = get_value((pcre_uint8 *)argv[op+1], &endptr), *endptr == 0)) { @@ -3099,7 +3157,7 @@ while (argc > 1 && argv[op][0] == '-') ((stack_size = get_value((pcre_uint8 *)argv[op+1], &endptr)), *endptr == 0)) { -#if defined(_WIN32) || defined(WIN32) || defined(__minix) || defined(NATIVE_ZOS) +#if defined(_WIN32) || defined(WIN32) || defined(__minix) || defined(NATIVE_ZOS) || defined(__VMS) printf("PCRE: -S not supported on this OS\n"); exit(1); #else @@ -3132,6 +3190,10 @@ while (argc > 1 && argv[op][0] == '-') (void)PCRE_CONFIG(PCRE_CONFIG_LINK_SIZE, &rc); printf("%d\n", rc); yield = rc; + +#ifdef __VMS + vms_setsymbol("LINKSIZE",0,yield ); +#endif } else if (strcmp(argv[op + 1], "pcre8") == 0) { @@ -3142,7 +3204,9 @@ while (argc > 1 && argv[op][0] == '-') printf("0\n"); yield = 0; #endif - goto EXIT; +#ifdef __VMS + vms_setsymbol("PCRE8",0,yield ); +#endif } else if (strcmp(argv[op + 1], "pcre16") == 0) { @@ -3153,7 +3217,9 @@ while (argc > 1 && argv[op][0] == '-') printf("0\n"); yield = 0; #endif - goto EXIT; +#ifdef __VMS + vms_setsymbol("PCRE16",0,yield ); +#endif } else if (strcmp(argv[op + 1], "pcre32") == 0) { @@ -3164,9 +3230,11 @@ while (argc > 1 && argv[op][0] == '-') printf("0\n"); yield = 0; #endif - goto EXIT; +#ifdef __VMS + vms_setsymbol("PCRE32",0,yield ); +#endif } - if (strcmp(argv[op + 1], "utf") == 0) + else if (strcmp(argv[op + 1], "utf") == 0) { #ifdef SUPPORT_PCRE8 if (pcre_mode == PCRE8_MODE) @@ -3182,7 +3250,9 @@ while (argc > 1 && argv[op][0] == '-') #endif printf("%d\n", rc); yield = rc; - goto EXIT; +#ifdef __VMS + vms_setsymbol("UTF",0,yield ); +#endif } else if (strcmp(argv[op + 1], "ucp") == 0) { @@ -3201,6 +3271,11 @@ while (argc > 1 && argv[op][0] == '-') (void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &rc); print_newline_config(rc, TRUE); } + else if (strcmp(argv[op + 1], "bsr") == 0) + { + (void)PCRE_CONFIG(PCRE_CONFIG_BSR, &rc); + printf("%s\n", rc? "ANYCRLF" : "ANY"); + } else if (strcmp(argv[op + 1], "ebcdic") == 0) { #ifdef EBCDIC @@ -3273,6 +3348,8 @@ are set, either both UTFs are supported or both are not supported. */ printf(" Internal link size = %d\n", rc); (void)PCRE_CONFIG(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc); printf(" POSIX malloc threshold = %d\n", rc); + (void)PCRE_CONFIG(PCRE_CONFIG_PARENS_LIMIT, &lrc); + printf(" Parentheses nest limit = %ld\n", 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); @@ -3364,7 +3441,7 @@ pcre32_stack_malloc = stack_malloc; pcre32_stack_free = stack_free; #endif -/* Heading line unless quiet, then prompt for first regex if stdin */ +/* Heading line unless quiet */ if (!quiet) fprintf(outfile, "PCRE version %s\n\n", version); @@ -3387,7 +3464,7 @@ while (!done) 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; + size_t size; int do_allcaps = 0; int do_mark = 0; int do_study = 0; @@ -3407,6 +3484,7 @@ while (!done) use_utf = 0; debug_lengths = 1; + SET_PCRE_STACK_GUARD(NULL); if (extend_inputline(infile, buffer, " re> ") == NULL) break; if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); @@ -3416,6 +3494,30 @@ while (!done) while (isspace(*p)) p++; if (*p == 0) continue; + /* Handle option lock-out setting */ + + if (*p == '<' && p[1] == ' ') + { + p += 2; + while (isspace(*p)) p++; + if (strncmp((char *)p, "forbid ", 7) == 0) + { + p += 7; + while (isspace(*p)) p++; + pp = lockout; + while (!isspace(*p) && pp < lockout + sizeof(lockout) - 1) + *pp++ = *p++; + *pp = 0; + } + else + { + printf("** Unrecognized special command '%s'\n", p); + yield = 1; + goto EXIT; + } + continue; + } + /* See if the pattern is to be loaded pre-compiled from a file. */ if (*p == '<' && strchr((char *)(p+1), '<') == NULL) @@ -3442,8 +3544,6 @@ while (!done) fprintf(outfile, "Failed to open %s: %s\n", p, strerror(errno)); continue; } - - first_gotten_store = 0; if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ; true_size = @@ -3459,8 +3559,6 @@ while (!done) yield = 1; goto EXIT; } - regex_gotten_store = first_gotten_store; - if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ; magic = REAL_PCRE_MAGIC(re); @@ -3519,11 +3617,11 @@ while (!done) PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, NULL); if (rc == PCRE_ERROR_BADMODE) { - pcre_uint16 flags_in_host_byte_order; + pcre_uint32 flags_in_host_byte_order; if (REAL_PCRE_MAGIC(re) == MAGIC_NUMBER) flags_in_host_byte_order = REAL_PCRE_FLAGS(re); else - flags_in_host_byte_order = swap_uint16(REAL_PCRE_FLAGS(re)); + flags_in_host_byte_order = swap_uint32(REAL_PCRE_FLAGS(re)); /* Simulate the result of the function call below. */ fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc, pcre_mode == PCRE32_MODE ? "32" : pcre_mode == PCRE16_MODE ? "16" : "", @@ -3599,14 +3697,62 @@ while (!done) *pp++ = 0; strcpy((char *)pbuffer, (char *)p); - /* Look for options after final delimiter */ + /* Look for modifiers and options after the final delimiter. */ - options = 0; + options = default_options; study_options = force_study_options; log_store = showstore; /* default from command line */ while (*pp != 0) { + /* Check to see whether this modifier has been locked out for this file. + This is complicated for the multi-character options that begin with '<'. + If there is no '>' in the lockout string, all multi-character modifiers are + locked out. */ + + if (strchr((char *)lockout, *pp) != NULL) + { + if (*pp == '<' && strchr((char *)lockout, '>') != NULL) + { + int x = check_mc_option(pp+1, outfile, FALSE, "modifier"); + if (x == 0) goto SKIP_DATA; + + for (ppp = lockout; *ppp != 0; ppp++) + { + if (*ppp == '<') + { + int y = check_mc_option(ppp+1, outfile, FALSE, "modifier"); + if (y == 0) + { + printf("** Error in modifier forbid data - giving up.\n"); + yield = 1; + goto EXIT; + } + if (x == y) + { + ppp = pp; + while (*ppp != '>') ppp++; + printf("** The %.*s modifier is locked out - giving up.\n", + (int)(ppp - pp + 1), pp); + yield = 1; + goto EXIT; + } + } + } + } + + /* The single-character modifiers are straightforward. */ + + else + { + printf("** The /%c modifier is locked out - giving up.\n", *pp); + yield = 1; + goto EXIT; + } + } + + /* The modifier is not locked out; handle it. */ + switch (*pp++) { case 'f': options |= PCRE_FIRSTLINE; break; @@ -3633,11 +3779,27 @@ while (!done) case 'K': do_mark = 1; break; case 'M': log_store = 1; break; case 'N': options |= PCRE_NO_AUTO_CAPTURE; break; + case 'O': options |= PCRE_NO_AUTO_POSSESS; break; #if !defined NOPOSIX case 'P': do_posix = 1; break; #endif + case 'Q': + switch (*pp) + { + case '0': + case '1': + stack_guard_return = *pp++ - '0'; + break; + + default: + fprintf(outfile, "** Missing 0 or 1 after /Q\n"); + goto SKIP_DATA; + } + SET_PCRE_STACK_GUARD(stack_guard); + break; + case 'S': do_study = 1; for (;;) @@ -3683,6 +3845,7 @@ while (!done) case 'Y': options |= PCRE_NO_START_OPTIMISE; break; case 'Z': debug_lengths = 0; break; case '8': options |= PCRE_UTF8; use_utf = 1; break; + case '9': options |= PCRE_NEVER_UTF; break; case '?': options |= PCRE_NO_UTF8_CHECK; break; case 'T': @@ -3729,18 +3892,10 @@ while (!done) case '<': { - if (strncmpic(pp, (pcre_uint8 *)"JS>", 3) == 0) - { - options |= PCRE_JAVASCRIPT_COMPAT; - pp += 3; - } - else - { - int x = check_newline(pp, outfile); - if (x == 0) goto SKIP_DATA; - options |= x; - while (*pp++ != '>'); - } + int x = check_mc_option(pp, outfile, FALSE, "modifier"); + if (x == 0) goto SKIP_DATA; + options |= x; + while (*pp++ != '>'); } break; @@ -3750,7 +3905,7 @@ while (!done) break; default: - fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); + fprintf(outfile, "** Unknown modifier '%c'\n", pp[-1]); goto SKIP_DATA; } } @@ -3773,7 +3928,6 @@ while (!done) 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 @@ -3860,13 +4014,12 @@ while (!done) PCRE_COMPILE(re, p, options, &error, &erroroffset, tables); if (re != NULL) free(re); } - time_taken = clock() - start_time; + total_compile_time += (time_taken = clock() - start_time); fprintf(outfile, "Compile time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeit) / (double)CLOCKS_PER_SEC); } - first_gotten_store = 0; PCRE_COMPILE(re, p, options, &error, &erroroffset, tables); /* Compilation failed; go back for another re, skipping to blank line @@ -3906,7 +4059,6 @@ while (!done) and remember the store that was got. */ true_size = REAL_PCRE_SIZE(re); - regex_gotten_store = first_gotten_store; /* Output code size information if requested */ @@ -3929,8 +4081,9 @@ while (!done) if (REAL_PCRE_FLAGS(re) & PCRE_MODE32) real_pcre_size = sizeof(real_pcre32); #endif + new_info(re, NULL, PCRE_INFO_SIZE, &size); fprintf(outfile, "Memory allocation (code space): %d\n", - (int)(first_gotten_store - real_pcre_size - name_count * name_entry_size)); + (int)(size - real_pcre_size - name_count * name_entry_size)); } /* If -s or /S was present, study the regex to generate additional info to @@ -3949,7 +4102,7 @@ while (!done) { PCRE_STUDY(extra, re, study_options, &error); } - time_taken = clock() - start_time; + total_study_time = (time_taken = clock() - start_time); if (extra != NULL) { PCRE_FREE_STUDY(extra); @@ -4003,13 +4156,13 @@ while (!done) { unsigned long int all_options; pcre_uint32 first_char, need_char; + pcre_uint32 match_limit, recursion_limit; int count, backrefmax, first_char_set, need_char_set, okpartial, jchanged, - hascrorlf, maxlookbehind; + hascrorlf, maxlookbehind, match_empty; int nameentrysize, namecount; const pcre_uint8 *nametable; - if (new_info(re, NULL, PCRE_INFO_SIZE, &size) + - new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count) + + if (new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count) + new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax) + new_info(re, NULL, PCRE_INFO_FIRSTCHARACTER, &first_char) + new_info(re, NULL, PCRE_INFO_FIRSTCHARACTERFLAGS, &first_char_set) + @@ -4021,18 +4174,25 @@ while (!done) 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_MATCH_EMPTY, &match_empty) + 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", - (int)size, (int)regex_gotten_store); - fprintf(outfile, "Capturing subpattern count = %d\n", count); + if (backrefmax > 0) fprintf(outfile, "Max back reference = %d\n", backrefmax); + if (maxlookbehind > 0) + fprintf(outfile, "Max lookbehind = %d\n", maxlookbehind); + + if (new_info(re, NULL, PCRE_INFO_MATCHLIMIT, &match_limit) == 0) + fprintf(outfile, "Match limit = %u\n", match_limit); + + if (new_info(re, NULL, PCRE_INFO_RECURSIONLIMIT, &recursion_limit) == 0) + fprintf(outfile, "Recursion limit = %u\n", recursion_limit); + if (namecount > 0) { fprintf(outfile, "Named capturing subpatterns:\n"); @@ -4059,14 +4219,15 @@ while (!done) } } - if (!okpartial) fprintf(outfile, "Partial matching not supported\n"); - if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n"); + if (!okpartial) fprintf(outfile, "Partial matching not supported\n"); + if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n"); + if (match_empty) fprintf(outfile, "May match empty string\n"); all_options = REAL_PCRE_OPTIONS(re); 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", + else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", ((get_options & PCRE_CASELESS) != 0)? " caseless" : "", ((get_options & PCRE_EXTENDED) != 0)? " extended" : "", @@ -4079,11 +4240,13 @@ while (!done) ((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_NO_AUTO_POSSESS) != 0)? " no_auto_possessify" : "", ((get_options & PCRE_UTF8) != 0)? " utf" : "", ((get_options & PCRE_UCP) != 0)? " ucp" : "", ((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" : ""); + ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "", + ((get_options & PCRE_NEVER_UTF) != 0)? " never_utf" : ""); if (jchanged) fprintf(outfile, "Duplicate name status changes\n"); @@ -4157,9 +4320,6 @@ while (!done) } } - 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 @@ -4183,12 +4343,12 @@ while (!done) if (new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits) == 0) { if (start_bits == NULL) - fprintf(outfile, "No set of starting bytes\n"); + fprintf(outfile, "No starting char list\n"); else { int i; int c = 24; - fprintf(outfile, "Starting byte set: "); + fprintf(outfile, "Starting chars: "); for (i = 0; i < 256; i++) { if ((start_bits[i/8] & (1<<(i&7))) != 0) @@ -4387,7 +4547,8 @@ while (!done) #ifndef NOUTF /* Check that the data is well-formed UTF-8 if we're in UTF mode. To create - invalid input to pcre_exec, you must use \x?? or \x{} sequences. */ + invalid input to pcre_exec, you must use \x?? or \x{} sequences. */ + if (use_utf) { pcre_uint8 *q; @@ -4405,21 +4566,23 @@ while (!done) #ifdef SUPPORT_VALGRIND /* Mark the dbuffer as addressable but undefined again. */ + if (dbuffer != NULL) { VALGRIND_MAKE_MEM_UNDEFINED(dbuffer, dbuffer_size * CHAR_SIZE); } #endif - /* Allocate a buffer to hold the data line. len+1 is an upper bound on - the number of pcre_uchar units that will be needed. */ - if (dbuffer == NULL || (size_t)len >= dbuffer_size) + /* Allocate a buffer to hold the data line; len+1 is an upper bound on + the number of pcre_uchar units that will be needed. */ + + while (dbuffer == NULL || (size_t)len >= dbuffer_size) { dbuffer_size *= 2; dbuffer = (pcre_uint8 *)realloc(dbuffer, dbuffer_size * CHAR_SIZE); if (dbuffer == NULL) { - fprintf(stderr, "pcretest: malloc(%d) failed\n", (int)dbuffer_size); + fprintf(stderr, "pcretest: realloc(%d) failed\n", (int)dbuffer_size); exit(1); } } @@ -4471,6 +4634,23 @@ while (!done) c = c * 8 + *p++ - '0'; break; + case 'o': + if (*p == '{') + { + pcre_uint8 *pt = p; + c = 0; + for (pt++; isdigit(*pt) && *pt != '8' && *pt != '9'; pt++) + { + if (++i == 12) + fprintf(outfile, "** Too many octal digits in \\o{...} item; " + "using only the first twelve.\n"); + else c = c * 8 + *pt - '0'; + } + if (*pt == '}') p = pt + 1; + else fprintf(outfile, "** Missing } after \\o{ (assumed)\n"); + } + break; + case 'x': if (*p == '{') { @@ -4713,7 +4893,7 @@ while (!done) case '<': { - int x = check_newline(p, outfile); + int x = check_mc_option(p, outfile, TRUE, "escape sequence"); if (x == 0) goto NEXT_DATA; options |= x; while (*p++ != '>'); @@ -4955,7 +5135,7 @@ while (!done) PCRE_EXEC(count, re, extra, bptr, len, start_offset, (options | g_notempty), use_offsets, use_size_offsets); } - time_taken = clock() - start_time; + total_match_time += (time_taken = clock() - start_time); fprintf(outfile, "Execute time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeitm) / (double)CLOCKS_PER_SEC); @@ -5016,7 +5196,7 @@ while (!done) DFA_WS_DIMENSION); if (count == 0) { - fprintf(outfile, "Matched, but too many subsidiary matches\n"); + fprintf(outfile, "Matched, but offsets vector is too small to show all matches\n"); count = use_size_offsets/2; } } @@ -5029,7 +5209,8 @@ while (!done) if (count == 0) { fprintf(outfile, "Matched, but too many substrings\n"); - count = use_size_offsets/3; + /* 2 is a special case; match can be returned */ + count = (use_size_offsets == 2)? 1 : use_size_offsets/3; } } @@ -5043,7 +5224,8 @@ while (!done) #if !defined NODFA if (all_use_dfa || use_dfa) maxcount = use_size_offsets/2; else #endif - maxcount = use_size_offsets/3; + /* 2 is a special case; match can be returned */ + maxcount = (use_size_offsets == 2)? 1 : use_size_offsets/3; /* This is a check against a lunatic return value. */ @@ -5071,7 +5253,8 @@ while (!done) if (count * 2 > use_size_offsets) count = use_size_offsets/2; } - /* Output the captured substrings */ + /* Output the captured substrings. Note that, for the matched string, + the use of \K in an assertion can make the start later than the end. */ for (i = 0; i < count * 2; i += 2) { @@ -5087,11 +5270,25 @@ while (!done) } else { + int start = use_offsets[i]; + int end = use_offsets[i+1]; + + if (start > end) + { + start = use_offsets[i+1]; + end = use_offsets[i]; + fprintf(outfile, "Start of matched string is beyond its end - " + "displaying from end to start.\n"); + } + fprintf(outfile, "%2d: ", i/2); - PCHARSV(bptr, use_offsets[i], - use_offsets[i+1] - use_offsets[i], outfile); + PCHARSV(bptr, start, end - start, outfile); if (verify_jit && jit_was_used) fprintf(outfile, " (JIT)"); fprintf(outfile, "\n"); + + /* Note: don't use the start/end variables here because we want to + show the text from what is reported as the end. */ + if (do_showcaprest || (i == 0 && do_showrest)) { fprintf(outfile, "%2d+ ", i/2); @@ -5261,14 +5458,17 @@ while (!done) } } - /* There was a partial match */ + /* There was a partial match. If the bumpalong point is not the same as + the first inspected character, show the offset explicitly. */ else if (count == PCRE_ERROR_PARTIAL) { - if (markptr == NULL) fprintf(outfile, "Partial match"); - else + fprintf(outfile, "Partial match"); + if (use_size_offsets > 2 && use_offsets[0] != use_offsets[2]) + fprintf(outfile, " at offset %d", use_offsets[2]); + if (markptr != NULL) { - fprintf(outfile, "Partial match, mark="); + fprintf(outfile, ", mark="); PCHARSV(markptr, 0, -1, outfile); } if (use_size_offsets > 1) @@ -5460,6 +5660,23 @@ while (!done) if (infile == stdin) fprintf(outfile, "\n"); +if (showtotaltimes) + { + fprintf(outfile, "--------------------------------------\n"); + if (timeit > 0) + { + fprintf(outfile, "Total compile time %.4f milliseconds\n", + (((double)total_compile_time * 1000.0) / (double)timeit) / + (double)CLOCKS_PER_SEC); + fprintf(outfile, "Total study time %.4f milliseconds\n", + (((double)total_study_time * 1000.0) / (double)timeit) / + (double)CLOCKS_PER_SEC); + } + fprintf(outfile, "Total execute time %.4f milliseconds\n", + (((double)total_match_time * 1000.0) / (double)timeitm) / + (double)CLOCKS_PER_SEC); + } + EXIT: if (infile != NULL && infile != stdin) fclose(infile); @@ -5482,6 +5699,10 @@ if (dfa_workspace != NULL) free(dfa_workspace); #endif +#if defined(__VMS) + yield = SS$_NORMAL; /* Return values via DCL symbols */ +#endif + return yield; } diff --git a/tools/pcre/perltest.pl b/tools/pcre/perltest.pl index 80ab1b8b..05983a33 100644 --- a/tools/pcre/perltest.pl +++ b/tools/pcre/perltest.pl @@ -1,20 +1,17 @@ #! /usr/bin/env perl # Program for testing regular expressions with perl to check that PCRE handles -# 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. +# them the same. This version 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 utf8; #require Encode; +# Function for turning a string into a string of printing chars. + sub pchars { my($t) = ""; @@ -71,7 +68,7 @@ for (;;) printf " re> " if $infile eq "STDIN"; last if ! ($_ = <$infile>); printf $outfile "$_" if $infile ne "STDIN"; - next if ($_ eq ""); + next if ($_ =~ /^\s*$/ || $_ =~ /^< forbid/); $pattern = $_; @@ -106,17 +103,17 @@ for (;;) $pattern =~ s/K(?=[a-zA-Z]*$)//; - # Remove /W from a pattern (asks pcretest to set PCRE_UCP) + # /W asks pcretest to set PCRE_UCP; change this to /u for Perl - $pattern =~ s/W(?=[a-zA-Z]*$)//; + $pattern =~ s/W(?=[a-zA-Z]*$)/u/; # 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) + # Remove /Y and /O from a pattern (disable PCRE optimizations) - $pattern =~ s/Y(?=[a-zA-Z]*$)//; + $pattern =~ s/[YO](?=[a-zA-Z]*$)//; # Check that the pattern is valid diff --git a/tools/pcre/sljit/sljitConfig.h b/tools/pcre/sljit/sljitConfig.h index 68bc59d0..4d93f4f7 100644 --- a/tools/pcre/sljit/sljitConfig.h +++ b/tools/pcre/sljit/sljitConfig.h @@ -44,10 +44,13 @@ /* #define SLJIT_CONFIG_ARM_V5 1 */ /* #define SLJIT_CONFIG_ARM_V7 1 */ /* #define SLJIT_CONFIG_ARM_THUMB2 1 */ +/* #define SLJIT_CONFIG_ARM_64 1 */ /* #define SLJIT_CONFIG_PPC_32 1 */ /* #define SLJIT_CONFIG_PPC_64 1 */ /* #define SLJIT_CONFIG_MIPS_32 1 */ +/* #define SLJIT_CONFIG_MIPS_64 1 */ /* #define SLJIT_CONFIG_SPARC_32 1 */ +/* #define SLJIT_CONFIG_TILEGX 1 */ /* #define SLJIT_CONFIG_AUTO 1 */ /* #define SLJIT_CONFIG_UNSUPPORTED 1 */ @@ -105,6 +108,13 @@ #define SLJIT_VERBOSE 1 #endif -/* See the beginning of sljitConfigInternal.h */ +/* + SLJIT_IS_FPU_AVAILABLE + The availability of the FPU can be controlled by SLJIT_IS_FPU_AVAILABLE. + zero value - FPU is NOT present. + nonzero value - FPU is present. +*/ + +/* For further configurations, see the beginning of sljitConfigInternal.h */ #endif diff --git a/tools/pcre/sljit/sljitConfigInternal.h b/tools/pcre/sljit/sljitConfigInternal.h index 2b6616ef..89be38bd 100644 --- a/tools/pcre/sljit/sljitConfigInternal.h +++ b/tools/pcre/sljit/sljitConfigInternal.h @@ -59,10 +59,13 @@ || (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_ARM_64 && SLJIT_CONFIG_ARM_64) \ || (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_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ + || (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \ || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)) #error "An architecture must be selected" @@ -74,9 +77,12 @@ + (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_ARM_64 && SLJIT_CONFIG_ARM_64) \ + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + + (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \ + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 @@ -100,14 +106,20 @@ #else #define SLJIT_CONFIG_ARM_V5 1 #endif +#elif defined (__aarch64__) +#define SLJIT_CONFIG_ARM_64 1 #elif defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) || (defined(_POWER) && defined(__64BIT__)) #define SLJIT_CONFIG_PPC_64 1 #elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) #define SLJIT_CONFIG_PPC_32 1 -#elif defined(__mips__) +#elif defined(__mips__) && !defined(_LP64) #define SLJIT_CONFIG_MIPS_32 1 +#elif defined(__mips64) +#define SLJIT_CONFIG_MIPS_64 1 #elif defined(__sparc__) || defined(__sparc) #define SLJIT_CONFIG_SPARC_32 1 +#elif defined(__tilegx__) +#define SLJIT_CONFIG_TILEGX 1 #else /* Unsupported architecture */ #define SLJIT_CONFIG_UNSUPPORTED 1 @@ -173,9 +185,13 @@ #endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */ #ifndef SLJIT_INLINE -/* Inline functions. */ +/* Inline functions. Some old compilers do not support them. */ +#if defined(__SUNPRO_C) && __SUNPRO_C <= 0x510 +#define SLJIT_INLINE +#else #define SLJIT_INLINE __inline #endif +#endif /* !SLJIT_INLINE */ #ifndef SLJIT_CONST /* Const variables. */ @@ -217,6 +233,13 @@ #define SLJIT_CACHE_FLUSH(from, to) \ sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from)) +#elif defined __ANDROID__ + +/* Android lacks __clear_cache; instead, cacheflush should be used. */ + +#define SLJIT_CACHE_FLUSH(from, to) \ + cacheflush((long)(from), (long)(to), 0) + #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. */ @@ -259,7 +282,11 @@ typedef signed int sljit_si; #define SLJIT_WORD_SHIFT 0 typedef unsigned long int sljit_uw; typedef long int sljit_sw; -#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + && !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) #define SLJIT_32BIT_ARCHITECTURE 1 #define SLJIT_WORD_SHIFT 2 typedef unsigned int sljit_uw; @@ -304,7 +331,7 @@ typedef double sljit_d; /* ABI (Application Binary Interface) types. */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -#if defined(__GNUC__) +#if defined(__GNUC__) && !defined(__APPLE__) #define SLJIT_CALL __attribute__ ((fastcall)) #define SLJIT_X86_32_FASTCALL 1 @@ -336,13 +363,18 @@ typedef double sljit_d; #if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) -/* These macros are useful for the application. */ +/* These macros are useful for the applications. */ #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -#define SLJIT_BIG_ENDIAN 1 + || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#ifdef __LITTLE_ENDIAN__ +#define SLJIT_LITTLE_ENDIAN 1 +#else +#define SLJIT_BIG_ENDIAN 1 +#endif + +#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) #ifdef __MIPSEL__ #define SLJIT_LITTLE_ENDIAN 1 @@ -350,6 +382,10 @@ typedef double sljit_d; #define SLJIT_BIG_ENDIAN 1 #endif +#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + +#define SLJIT_BIG_ENDIAN 1 + #else #define SLJIT_LITTLE_ENDIAN 1 #endif @@ -366,7 +402,8 @@ typedef double sljit_d; #endif #ifndef SLJIT_INDIRECT_CALL -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32 && defined _AIX) +#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)) \ + || ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX) /* It seems certain ppc compilers use an indirect addressing for functions which makes things complicated. */ #define SLJIT_INDIRECT_CALL 1 @@ -403,6 +440,7 @@ typedef double sljit_d; || (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_ARM_64 && SLJIT_CONFIG_ARM_64) \ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define SLJIT_UNALIGNED 1 @@ -413,6 +451,7 @@ typedef double sljit_d; #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); +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void); #define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size) #define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) #endif diff --git a/tools/pcre/sljit/sljitExecAllocator.c b/tools/pcre/sljit/sljitExecAllocator.c index 75a38991..f24ed337 100644 --- a/tools/pcre/sljit/sljitExecAllocator.c +++ b/tools/pcre/sljit/sljitExecAllocator.c @@ -287,3 +287,26 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) allocator_release_lock(); } + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) +{ + struct free_block* free_block; + struct free_block* next_free_block; + + allocator_grab_lock(); + + free_block = free_blocks; + while (free_block) { + next_free_block = free_block->next; + if (!free_block->header.prev_size && + AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) { + total_size -= free_block->size; + sljit_remove_free_block(free_block); + free_chunk(free_block, free_block->size + sizeof(struct block_header)); + } + free_block = next_free_block; + } + + SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks)); + allocator_release_lock(); +} diff --git a/tools/pcre/sljit/sljitLir.c b/tools/pcre/sljit/sljitLir.c index 69798410..1acecba8 100644 --- a/tools/pcre/sljit/sljitLir.c +++ b/tools/pcre/sljit/sljitLir.c @@ -83,13 +83,13 @@ #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)) + ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | 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)) + ((op) & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) #define GET_ALL_FLAGS(op) \ - ((op) & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) + ((op) & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) #define TYPE_CAST_NEEDED(op) \ (((op) >= SLJIT_MOV_UB && (op) <= SLJIT_MOV_SH) || ((op) >= SLJIT_MOVU_UB && (op) <= SLJIT_MOVU_SH)) @@ -102,6 +102,16 @@ #define ABUF_SIZE 4096 #endif +/* Parameter parsing. */ +#define REG_MASK 0x3f +#define OFFS_REG(reg) (((reg) >> 8) & REG_MASK) +#define OFFS_REG_MASK (REG_MASK << 8) +#define TO_OFFS_REG(reg) ((reg) << 8) +/* When reg cannot be unused. */ +#define FAST_IS_REG(reg) ((reg) <= REG_MASK) +/* When reg can be unused. */ +#define SLOW_IS_REG(reg) ((reg) > 0 && (reg) <= REG_MASK) + /* Jump flags. */ #define JUMP_LABEL 0x1 #define JUMP_ADDR 0x2 @@ -127,39 +137,59 @@ #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) # define IS_COND 0x04 # define IS_BL 0x08 - /* cannot be encoded as branch */ -# define B_TYPE0 0x00 /* conditional + imm8 */ -# define B_TYPE1 0x10 +# define PATCH_TYPE1 0x10 /* conditional + imm20 */ -# define B_TYPE2 0x20 +# define PATCH_TYPE2 0x20 /* IT + imm24 */ -# define B_TYPE3 0x30 +# define PATCH_TYPE3 0x30 /* imm11 */ -# define B_TYPE4 0x40 +# define PATCH_TYPE4 0x40 /* imm24 */ -# define B_TYPE5 0x50 +# define PATCH_TYPE5 0x50 /* BL + imm24 */ -# define BL_TYPE6 0x60 +# define PATCH_BL 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 +#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) +# define IS_COND 0x004 +# define IS_CBZ 0x008 +# define IS_BL 0x010 +# define PATCH_B 0x020 +# define PATCH_COND 0x040 +# define PATCH_ABS48 0x080 +# define PATCH_ABS64 0x100 #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 +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +# define IS_COND 0x004 +# define IS_CALL 0x008 +# define PATCH_B 0x010 +# define PATCH_ABS_B 0x020 +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +# define PATCH_ABS32 0x040 +# define PATCH_ABS48 0x080 +#endif +# define REMOVE_COND 0x100 +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +# define IS_MOVABLE 0x004 +# define IS_JAL 0x008 +# define IS_CALL 0x010 +# define IS_BIT26_COND 0x020 +# define IS_BIT16_COND 0x040 # define IS_COND (IS_BIT26_COND | IS_BIT16_COND) -# define PATCH_B 0x40 -# define PATCH_J 0x80 +# define PATCH_B 0x080 +# define PATCH_J 0x100 + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +# define PATCH_ABS32 0x200 +# define PATCH_ABS48 0x400 +#endif /* instruction types */ # define MOVABLE_INS 0 @@ -167,7 +197,15 @@ /* no destination (i.e: store) */ # define UNMOVABLE_INS 32 /* FPU status register */ -# define FCSR_FCC 33 +# define FCSR_FCC 33 +#endif + +#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) +# define IS_JAL 0x04 +# define IS_COND 0x08 + +# define PATCH_B 0x10 +# define PATCH_J 0x20 #endif #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) @@ -207,9 +245,13 @@ #endif #endif +#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) +#define SLJIT_HAS_VARIABLE_LOCALS_OFFSET 1 +#endif + #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +#ifdef _AIX #define FIXED_LOCALS_OFFSET ((6 + 8) * sizeof(sljit_sw)) #else #define FIXED_LOCALS_OFFSET (2 * sizeof(sljit_sw)) @@ -226,6 +268,11 @@ #define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_sw)) #endif +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 +#define FIXED_LOCALS_OFFSET 0 +#endif + #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 #define FIXED_LOCALS_OFFSET (23 * sizeof(sljit_sw)) @@ -335,7 +382,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) compiler->cpool_diff = 0xffffffff; #endif -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) compiler->delay_slot = UNMOVABLE_INS; #endif @@ -410,8 +457,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sl 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; @@ -526,7 +571,7 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp } #define ADDRESSING_DEPENDS_ON(exp, reg) \ - (((exp) & SLJIT_MEM) && (((exp) & 0xf) == reg || (((exp) >> 4) & 0xf) == reg)) + (((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg)) #if (defined SLJIT_DEBUG && SLJIT_DEBUG) #define FUNCTION_CHECK_OP() \ @@ -540,41 +585,43 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp case SLJIT_SHL: \ case SLJIT_LSHR: \ case SLJIT_ASHR: \ - SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))); \ + SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))); \ break; \ case SLJIT_NEG: \ - SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \ + SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \ break; \ case SLJIT_MUL: \ - SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \ + SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \ break; \ case SLJIT_CMPD: \ SLJIT_ASSERT(!(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))); \ + SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_S))); \ 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))); \ + SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))); \ break; \ case SLJIT_BREAKPOINT: \ case SLJIT_NOP: \ case SLJIT_UMUL: \ case SLJIT_SMUL: \ case SLJIT_MOV: \ + case SLJIT_MOV_UI: \ case SLJIT_MOV_P: \ case SLJIT_MOVU: \ + case SLJIT_MOVU_UI: \ case SLJIT_MOVU_P: \ /* 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))); \ + SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ break; \ default: \ /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ - SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ + SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ break; \ } @@ -592,12 +639,12 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp 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(FUNCTION_CHECK_IS_REG((p) & REG_MASK)); \ + if ((p) & OFFS_REG_MASK) { \ + SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ SLJIT_ASSERT(!((i) & ~0x3)); \ } \ - SLJIT_ASSERT(((p) >> 9) == 0); \ + SLJIT_ASSERT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ } \ else \ SLJIT_ASSERT_STOP(); @@ -609,12 +656,12 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp 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(FUNCTION_CHECK_IS_REG((p) & REG_MASK)); \ + if ((p) & OFFS_REG_MASK) { \ + SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ SLJIT_ASSERT(!((i) & ~0x3)); \ } \ - SLJIT_ASSERT(((p) >> 9) == 0); \ + SLJIT_ASSERT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ } \ else \ SLJIT_ASSERT_STOP(); @@ -623,23 +670,23 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp if ((p) >= SLJIT_FLOAT_REG1 && (p) <= SLJIT_FLOAT_REG6) \ 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)); \ + SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & REG_MASK)); \ + if ((p) & OFFS_REG_MASK) { \ + SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ + SLJIT_ASSERT(((p) & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_LOCALS_REG) && !(i & ~0x3)); \ } else \ - SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \ - SLJIT_ASSERT(((p) >> 9) == 0); \ + SLJIT_ASSERT(OFFS_REG(p) == 0); \ + SLJIT_ASSERT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ } \ else \ SLJIT_ASSERT_STOP(); #define FUNCTION_CHECK_OP1() \ if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_P) { \ - 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)); \ + SLJIT_ASSERT(!(src & SLJIT_MEM) || (src & REG_MASK) != SLJIT_LOCALS_REG); \ + SLJIT_ASSERT(!(dst & SLJIT_MEM) || (dst & REG_MASK) != SLJIT_LOCALS_REG); \ + if ((src & SLJIT_MEM) && (src & REG_MASK)) \ + SLJIT_ASSERT((dst & REG_MASK) != (src & REG_MASK) && OFFS_REG(dst) != (src & REG_MASK)); \ } #endif @@ -652,17 +699,17 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp } 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" + (char*)"unused", (char*)"s1", (char*)"s2", (char*)"s3", + (char*)"se1", (char*)"se2", (char*)"p1", (char*)"p2", + (char*)"p3", (char*)"pe1", (char*)"pe2", (char*)"lc" }; static char* freg_names[] = { - (char*)"", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3", - (char*)"float_r4", (char*)"float_r5", (char*)"float_r6" + (char*)"unused", (char*)"f1", (char*)"f2", (char*)"f3", + (char*)"f4", (char*)"f5", (char*)"f6" }; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) #ifdef _WIN64 # define SLJIT_PRINT_D "I64" #else @@ -676,18 +723,18 @@ static char* freg_names[] = { if ((p) & SLJIT_IMM) \ fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \ else if ((p) & SLJIT_MEM) { \ - if ((p) & 0xf) { \ + if ((p) & REG_MASK) { \ if (i) { \ - if (((p) >> 4) & 0xf) \ - fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \ + if ((p) & OFFS_REG_MASK) \ + fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & REG_MASK], reg_names[OFFS_REG(p)], 1 << (i)); \ else \ - fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & 0xF], (i)); \ + fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & REG_MASK], (i)); \ } \ else { \ - if (((p) >> 4) & 0xf) \ - fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \ + if ((p) & OFFS_REG_MASK) \ + fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & REG_MASK], reg_names[OFFS_REG(p)]); \ else \ - fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \ + fprintf(compiler->verbose, "[%s]", reg_names[(p) & REG_MASK]); \ } \ } \ else \ @@ -696,18 +743,18 @@ static char* freg_names[] = { fprintf(compiler->verbose, "%s", reg_names[p]); #define sljit_verbose_fparam(p, i) \ if ((p) & SLJIT_MEM) { \ - if ((p) & 0xf) { \ + if ((p) & REG_MASK) { \ if (i) { \ - if (((p) >> 4) & 0xf) \ - fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \ + if ((p) & OFFS_REG_MASK) \ + fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & REG_MASK], reg_names[OFFS_REG(p)], 1 << (i)); \ else \ - fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & 0xF], (i)); \ + fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & REG_MASK], (i)); \ } \ else { \ - if (((p) >> 4) & 0xF) \ - fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \ + if ((p) & OFFS_REG_MASK) \ + fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & REG_MASK], reg_names[OFFS_REG(p)]); \ else \ - fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \ + fprintf(compiler->verbose, "[%s]", reg_names[(p) & REG_MASK]); \ } \ } \ else \ @@ -736,17 +783,17 @@ static SLJIT_CONST char* op_names[] = { }; 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_unordered", (char*)"c_float_ordered", + (char*)"equal", (char*)"not_equal", + (char*)"less", (char*)"greater_equal", + (char*)"greater", (char*)"less_equal", + (char*)"sig_less", (char*)"sig_greater_equal", + (char*)"sig_greater", (char*)"sig_less_equal", + (char*)"overflow", (char*)"not_overflow", + (char*)"mul_overflow", (char*)"mul_not_overflow", + (char*)"float_equal", (char*)"float_not_equal", + (char*)"float_less", (char*)"float_greater_equal", + (char*)"float_greater", (char*)"float_less_equal", + (char*)"float_unordered", (char*)"float_ordered", (char*)"jump", (char*)"fast_call", (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3" }; @@ -933,7 +980,7 @@ static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, s #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_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", "); @@ -975,7 +1022,7 @@ static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, s #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_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", "); @@ -993,6 +1040,12 @@ static SLJIT_INLINE void check_sljit_get_register_index(sljit_si reg) SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_REGISTERS); } +static SLJIT_INLINE void check_sljit_get_float_register_index(sljit_si reg) +{ + SLJIT_UNUSED_ARG(reg); + SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_FLOAT_REGISTERS); +} + static SLJIT_INLINE void check_sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_si size) { @@ -1104,7 +1157,7 @@ static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, 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]); + fprintf(compiler->verbose, " jump%s.%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]); #endif } @@ -1127,7 +1180,7 @@ static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, s #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]); + 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); @@ -1156,7 +1209,7 @@ static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %scmp%s<%s> ", (type & SLJIT_SINGLE_OP) ? "s" : "d", + fprintf(compiler->verbose, " %scmp%s.%s ", (type & SLJIT_SINGLE_OP) ? "s" : "d", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]); sljit_verbose_fparam(src1, src1w); fprintf(compiler->verbose, ", "); @@ -1187,7 +1240,7 @@ static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " ijump<%s> ", jump_names[type]); + fprintf(compiler->verbose, " ijump.%s ", jump_names[type]); sljit_verbose_param(src, srcw); fprintf(compiler->verbose, "\n"); } @@ -1211,7 +1264,7 @@ static SLJIT_INLINE void check_sljit_emit_op_flags(struct sljit_compiler *compil SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP); SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_UI || GET_OPCODE(op) == SLJIT_MOV_SI || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); - SLJIT_ASSERT((op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C)) == 0); + SLJIT_ASSERT((op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) == 0); SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS)); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) if (GET_OPCODE(op) < SLJIT_ADD) { @@ -1223,14 +1276,14 @@ static SLJIT_INLINE void check_sljit_emit_op_flags(struct sljit_compiler *compil #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " op_flags<%s%s%s%s> ", !(op & SLJIT_INT_OP) ? "" : "i", + fprintf(compiler->verbose, " %sflags.%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); sljit_verbose_param(dst, dstw); if (src != SLJIT_UNUSED) { fprintf(compiler->verbose, ", "); sljit_verbose_param(src, srcw); } - fprintf(compiler->verbose, ", <%s>\n", jump_names[type]); + fprintf(compiler->verbose, ", %s\n", jump_names[type]); } #endif } @@ -1326,22 +1379,28 @@ static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compi #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" +# include "sljitNativeARM_32.c" #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) -# include "sljitNativeARM_v5.c" +# include "sljitNativeARM_32.c" #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) -# include "sljitNativeARM_Thumb2.c" +# include "sljitNativeARM_T2_32.c" +#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) +# include "sljitNativeARM_64.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" +#elif (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +# include "sljitNativeMIPS_common.c" #elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) # include "sljitNativeSPARC_common.c" +#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) +# include "sljitNativeTILEGX_64.c" #endif -#if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, sljit_si src1, sljit_sw src1w, @@ -1355,6 +1414,19 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w); condition = type & 0xff; +#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) + if ((condition == SLJIT_C_EQUAL || condition == SLJIT_C_NOT_EQUAL)) { + if ((src1 & SLJIT_IMM) && !src1w) { + src1 = src2; + src1w = src2w; + src2 = SLJIT_IMM; + src2w = 0; + } + if ((src2 & SLJIT_IMM) && !src2w) + return emit_cmp_to0(compiler, type, src1, src1w); + } +#endif + if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) { /* Immediate is prefered as second argument by most architectures. */ switch (condition) { diff --git a/tools/pcre/sljit/sljitLir.h b/tools/pcre/sljit/sljitLir.h index 3171d155..e2cd2184 100644 --- a/tools/pcre/sljit/sljitLir.h +++ b/tools/pcre/sljit/sljitLir.h @@ -77,7 +77,7 @@ #endif /* The following header file defines useful macros for fine tuning -sljit based code generators. They are listed in the begining +sljit based code generators. They are listed in the beginning of sljitConfigInternal.h */ #include "sljitConfigInternal.h" @@ -161,12 +161,14 @@ of sljitConfigInternal.h */ /* Floating point operations are performed on double or single precision values. */ -#define SLJIT_FLOAT_REG1 1 -#define SLJIT_FLOAT_REG2 2 -#define SLJIT_FLOAT_REG3 3 -#define SLJIT_FLOAT_REG4 4 -#define SLJIT_FLOAT_REG5 5 -#define SLJIT_FLOAT_REG6 6 +#define SLJIT_FLOAT_REG1 1 +#define SLJIT_FLOAT_REG2 2 +#define SLJIT_FLOAT_REG3 3 +#define SLJIT_FLOAT_REG4 4 +#define SLJIT_FLOAT_REG5 5 +#define SLJIT_FLOAT_REG6 6 + +#define SLJIT_NO_FLOAT_REGISTERS 6 /* --------------------------------------------------------------------- */ /* Main structures and functions */ @@ -263,13 +265,19 @@ struct sljit_compiler { sljit_sw cache_argw; #endif +#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) + sljit_si locals_offset; + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) sljit_sw imm; sljit_si cache_arg; sljit_sw cache_argw; #endif -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) sljit_si delay_slot; sljit_si cache_arg; sljit_sw cache_argw; @@ -281,6 +289,11 @@ struct sljit_compiler { sljit_sw cache_argw; #endif +#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) + sljit_si cache_arg; + sljit_sw cache_argw; +#endif + #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) FILE* verbose; #endif @@ -306,7 +319,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void); /* Free everything except the compiled machine code. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler); -/* Returns the current error code. If an error is occured, future sljit +/* Returns the current error code. If an error is occurred, future sljit calls which uses the same compiler argument returns early with the same error code. Thus there is no need for checking the error after every call, it is enough to do it before the code is compiled. Removing @@ -447,7 +460,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * sequences. This information could help to improve those code generators which focuses only a few architectures. - x86: [reg+imm], -2^32+1 <= imm <= 2^32-1 (full adress space on x86-32) + x86: [reg+imm], -2^32+1 <= imm <= 2^32-1 (full address space on x86-32) [reg+(reg<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 sljit_si 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 sljit_si 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 sljit_si 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 sljit_si 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 sljit_si 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 ((sljit_si)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; + sljit_si index; + sljit_si value; +}; + +static SLJIT_INLINE sljit_si resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) +{ + sljit_si value; + struct future_patch *curr_patch, *prev_patch; + + /* Using the values generated by patch_pc_relative_loads. */ + if (!*first_patch) + value = (sljit_si)cpool_start_address[cpool_current_index]; + else { + curr_patch = *first_patch; + prev_patch = 0; + while (1) { + if (!curr_patch) { + value = (sljit_si)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 sljit_si 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 sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si reg, sljit_sw 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 sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) +{ + sljit_sw 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_sw)jump->u.target - (sljit_sw)(code_ptr + 2)); + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)); + } + + /* Branch to Thumb code has not been optimized yet. */ + if (diff & 0x3) + return 0; + + 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_sw)jump->u.target - (sljit_sw)code_ptr); + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr); + } + + /* Branch to Thumb code has not been optimized yet. */ + if (diff & 0x3) + return 0; + + 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, sljit_si 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]; + sljit_si bl = (mov_pc & 0x0000f000) != RD(TMP_PC); + sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(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_imm(sljit_uw imm); + +static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_si 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_imm(new_constant); + if (src2) { + *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2; + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + return; + } + + src2 = get_imm(~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_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); + *buf_ptr |= (((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff; + } + else { + SLJIT_ASSERT(((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); + *buf_ptr |= (((sljit_sw)jump->u.target - (sljit_sw)(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 <= (sljit_si)size); + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw); + SLJIT_CACHE_FLUSH(code, code_ptr); + return code; +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +/* 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 sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w); + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si size; + sljit_uw push; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + 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 (scratches >= 5) + push |= 1 << 11; + if (scratches >= 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 (scratches >= 4) + size += (scratches - 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_SCRATCH_REG1))); + if (args >= 2) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG2))); + if (args >= 3) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG3))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si size; + + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + size = (1 + saveds) * sizeof(sljit_uw); + if (scratches >= 4) + size += (scratches - 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 sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_uw pop; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, 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->scratches >= 5) + pop |= 1 << 11; + if (compiler->scratches >= 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_sw 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 sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_si src2) +{ + sljit_sw mul_inst; + + switch (GET_OPCODE(op)) { + 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; + + 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); + } + 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_imm(sljit_uw imm) +{ + sljit_si 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 sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm, sljit_si positive) +{ + sljit_uw mask; + sljit_uw imm1; + sljit_uw imm2; + sljit_si 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 sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si 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_imm(imm); + if (tmp) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp)); + return SLJIT_SUCCESS; + } + + tmp = get_imm(~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 +} + +/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ +static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +{ + if (value >= 0) { + value = get_imm(value); + if (value) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, dst, reg, value)); + } + else { + value = get_imm(-value); + if (value) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, dst, reg, value)); + } + return SLJIT_ERR_UNSUPPORTED; +} + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_uw imm; + + if (arg & SLJIT_IMM) { + imm = get_imm(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_imm(~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 0; + } + + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads/stores. */ + if (!(arg & REG_MASK)) + return 0; + + if (arg & OFFS_REG_MASK) { + if ((argw & 0x3) != 0 && !IS_TYPE1_TRANSFER(inp_flags)) + return 0; + + if (inp_flags & ARG_TEST) + return 1; + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, + RM(OFFS_REG(arg)) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7))); + return -1; + } + + 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 & REG_MASK, 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 & REG_MASK, -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 & REG_MASK, 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 & REG_MASK, TYPE2_TRANSFER_IMM(argw))); + return -1; + } + } + + return 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw 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 & OFFS_REG_MASK) + return 0; + + if (!(arg & REG_MASK)) { + /* 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 & REG_MASK; \ + 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 sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_r; + sljit_sw max_delta; + sljit_sw sign; + sljit_uw imm; + + 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 & REG_MASK) == SLJIT_UNUSED) { + /* Write back is not used. */ + imm = (sljit_uw)(argw - compiler->cache_argw); + if ((compiler->cache_arg & SLJIT_IMM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { + if (imm <= (sljit_uw)max_delta) { + sign = 1; + argw = argw - compiler->cache_argw; + } + else { + sign = 0; + argw = compiler->cache_argw - argw; + } + + GETPUT_ARG_DATA_TRANSFER(sign, 0, reg, TMP_REG3, 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). */ + imm = (sljit_uw)(argw - next_argw); + if ((next_arg & SLJIT_MEM) && (imm <= (sljit_uw)max_delta || imm >= (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; + } + + if (arg & OFFS_REG_MASK) { + SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00)); + if (inp_flags & WRITE_BACK) + tmp_r = arg & REG_MASK; + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7))); + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0))); + return SLJIT_SUCCESS; + } + + imm = (sljit_uw)(argw - compiler->cache_argw); + if (compiler->cache_arg == arg && imm <= (sljit_uw)max_delta) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); + GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, imm); + return SLJIT_SUCCESS; + } + if (compiler->cache_arg == arg && imm >= (sljit_uw)-max_delta) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); + imm = (sljit_uw)-(sljit_sw)imm; + GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, imm); + return SLJIT_SUCCESS; + } + + imm = get_imm(argw & ~max_delta); + if (imm) { + TEST_WRITE_BACK(); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, imm)); + GETPUT_ARG_DATA_TRANSFER(1, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta); + return SLJIT_SUCCESS; + } + + imm = get_imm(-argw & ~max_delta); + if (imm) { + argw = -argw; + TEST_WRITE_BACK(); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & REG_MASK, imm)); + GETPUT_ARG_DATA_TRANSFER(0, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta); + 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 & REG_MASK, 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 & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0))); + return SLJIT_SUCCESS; + } + + imm = (sljit_uw)(argw - next_argw); + if (arg == next_arg && !(inp_flags & WRITE_BACK) && (imm <= (sljit_uw)max_delta || imm >= (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 & REG_MASK])); + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, 0); + return SLJIT_SUCCESS; + } + + if ((arg & REG_MASK) == 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 & REG_MASK, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0))); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw 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); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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. */ + sljit_si dst_r; + sljit_si src1_r; + sljit_si src2_r = 0; + sljit_si sugg_src2_r = TMP_REG2; + sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + /* Destination check. */ + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } + else if (FAST_IS_REG(dst)) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } + 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 (FAST_IS_REG(src1)) + src1_r = src1; + else if (FAST_IS_REG(src2)) { + 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_imm(src1w); + if (src2_r) { + flags |= ARGS_SWAPPED; + src1 = src2; + src1w = src2w; + break; + } + if (inp_flags & ALLOW_INV_IMM) { + src2_r = get_imm(~src1w); + if (src2_r) { + flags |= ARGS_SWAPPED | INV_IMM; + src1 = src2; + src1w = src2w; + break; + } + } + if (GET_OPCODE(op) == SLJIT_ADD) { + src2_r = get_imm(-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 (FAST_IS_REG(src2)) { + 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_imm(src2w); + if (src2_r) + break; + if (inp_flags & ALLOW_INV_IMM) { + src2_r = get_imm(~src2w); + if (src2_r) { + flags |= INV_IMM; + break; + } + } + if (GET_OPCODE(op) == SLJIT_ADD) { + src2_r = get_imm(-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_imm(-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 int numerator, unsigned int denominator); +extern int __aeabi_idivmod(int numerator, int denominator); +#else +#error "Software divmod functions are needed" +#endif + +#ifdef __cplusplus +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si 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_SCRATCH_REG2] << 16) + | (reg_map[SLJIT_SCRATCH_REG1] << 12) + | (reg_map[SLJIT_SCRATCH_REG1] << 8) + | reg_map[SLJIT_SCRATCH_REG2]); +#else + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) + | (reg_map[SLJIT_SCRATCH_REG2] << 16) + | (reg_map[SLJIT_SCRATCH_REG1] << 12) + | (reg_map[SLJIT_SCRATCH_REG1] << 8) + | reg_map[TMP_REG1]); +#endif + case SLJIT_UDIV: + case SLJIT_SDIV: + if (compiler->scratches >= 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->scratches >= 3) + return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */); + return SLJIT_SUCCESS; + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw 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: + case SLJIT_MOV_P: + 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) ? (sljit_ub)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) ? (sljit_sb)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) ? (sljit_uh)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) ? (sljit_sh)srcw : srcw); + + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + case SLJIT_MOVU_P: + 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) ? (sljit_ub)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) ? (sljit_sb)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) ? (sljit_uh)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) ? (sljit_sh)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 sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw 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 sljit_si sljit_get_register_index(sljit_si reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + check_sljit_get_float_register_index(reg); + return reg; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si 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 sljit_si arm_fpu_type = -1; + +static void init_compiler(void) +{ + 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 sljit_si sljit_is_fpu_available(void) +{ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#else + if (arm_fpu_type == -1) + init_compiler(); + return arm_fpu_type; +#endif +} + +#else + +#define arm_fpu_type 1 + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ + /* Always available. */ + return 1; +} + +#endif + +#define FPU_LOAD (1 << 20) +#define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \ + ((inst) | ((add) << 23) | (reg_map[base] << 16) | (freg << 12) | (offs)) +#define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \ + ((opcode) | (mode) | ((dst) << 12) | (src1) | ((src2) << 16)) + +static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_sw tmp; + sljit_uw imm; + sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7))); + arg = SLJIT_MEM | TMP_REG1; + argw = 0; + } + + /* Fast loads and stores. */ + if ((arg & REG_MASK)) { + if (!(argw & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & REG_MASK, reg, argw >> 2)); + if (!(-argw & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & REG_MASK, reg, (-argw) >> 2)); + } + + if (compiler->cache_arg == arg) { + tmp = argw - compiler->cache_argw; + if (!(tmp & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, tmp >> 2)); + if (!(-tmp & ~0x3fc)) + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG3, 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_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); + } + } + + if (arg & REG_MASK) { + if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, 0)); + } + imm = get_imm(argw & ~0x3fc); + if (imm) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, imm)); + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2)); + } + imm = get_imm(-argw & ~0x3fc); + if (imm) { + argw = -argw; + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & REG_MASK, imm)); + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2)); + } + } + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + if (arg & REG_MASK) { + FAIL_IF(load_immediate(compiler, TMP_REG1, argw)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & REG_MASK, reg_map[TMP_REG1])); + } + else + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + + return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + op ^= SLJIT_SINGLE_OP; + + if (GET_OPCODE(op) == SLJIT_CMPD) { + if (dst & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, dst, dstw)); + dst = TMP_FREG1; + } + if (src & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src, srcw)); + src = TMP_FREG2; + } + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_SINGLE_OP, dst, src, 0)); + EMIT_INSTRUCTION(VMRS); + return SLJIT_SUCCESS; + } + + dst_fr = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_fr, src, srcw)); + src = dst_fr; + } + + switch (GET_OPCODE(op)) { + case SLJIT_MOVD: + if (src != dst_fr && dst_fr != TMP_FREG1) + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0)); + break; + case SLJIT_NEGD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0)); + break; + case SLJIT_ABSD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0)); + break; + } + + if (dst_fr == TMP_FREG1) { + if (GET_OPCODE(op) == SLJIT_MOVD) + dst_fr = src; + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_fr, dst, dstw)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + op ^= SLJIT_SINGLE_OP; + + dst_fr = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src2 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); + src2 = TMP_FREG2; + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); + src1 = TMP_FREG1; + } + + switch (GET_OPCODE(op)) { + case SLJIT_ADDD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + break; + + case SLJIT_SUBD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + break; + + case SLJIT_MULD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + break; + + case SLJIT_DIVD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + break; + } + + if (dst_fr == TMP_FREG1) + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw)); + + return SLJIT_SUCCESS; +} + +#undef FPU_LOAD +#undef EMIT_FPU_DATA_TRANSFER +#undef EMIT_FPU_OPERATION + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + 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) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3))); + + /* Memory. */ + if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw)) + return compiler->error; + /* TMP_REG3 is used for caching. */ + 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); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) + 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(sljit_si 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_UNORDERED: + return 0x60000000; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_FLOAT_ORDERED: + 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, sljit_si 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 sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw 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)) { + if (FAST_IS_REG(src)) + return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src)); + + SLJIT_ASSERT(src & SLJIT_MEM); + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw)); + return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2)); + } + + 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; + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_uw cc, ins; + + CHECK_ERROR(); + check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + cc = get_cc(type); + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + + if (op < SLJIT_ADD) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 0)); + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); + return (dst_r == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; + } + + ins = (op == SLJIT_AND ? AND_DP : (op == SLJIT_OR ? ORR_DP : EOR_DP)); + if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) { + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc); + /* The condition must always be set, even if the ORR/EOR is not executed above. */ + return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))) : SLJIT_SUCCESS; + } + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } else if (src & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + srcw = 0; + } + + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 1) & ~COND_MASK) | cc); + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000)); + if (dst_r == TMP_REG2) + FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0)); + + return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst_r))) : SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si 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 = SLOW_IS_REG(dst) ? 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 (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, 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_sw new_constant) +{ + inline_set_const(addr, new_constant, 1); +} diff --git a/tools/pcre/sljit/sljitNativeARM_64.c b/tools/pcre/sljit/sljitNativeARM_64.c new file mode 100644 index 00000000..cfd1a382 --- /dev/null +++ b/tools/pcre/sljit/sljitNativeARM_64.c @@ -0,0 +1,1902 @@ +/* + * 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(void) +{ + return "ARM-64" SLJIT_CPUINFO; +} + +/* Length of an instruction word */ +typedef sljit_ui sljit_ins; + +#define TMP_ZERO 0 + +#define TMP_REG1 (SLJIT_NO_REGISTERS + 1) +#define TMP_REG2 (SLJIT_NO_REGISTERS + 2) +#define TMP_REG3 (SLJIT_NO_REGISTERS + 3) +#define TMP_REG4 (SLJIT_NO_REGISTERS + 4) +#define TMP_LR (SLJIT_NO_REGISTERS + 5) +#define TMP_SP (SLJIT_NO_REGISTERS + 6) + +#define TMP_FREG1 (0) +#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 7] = { + 31, 0, 1, 2, 3, 4, 19, 20, 21, 22, 23, 29, 9, 10, 11, 12, 30, 31 +}; + +#define W_OP (1 << 31) +#define RD(rd) (reg_map[rd]) +#define RT(rt) (reg_map[rt]) +#define RN(rn) (reg_map[rn] << 5) +#define RT2(rt2) (reg_map[rt2] << 10) +#define RM(rm) (reg_map[rm] << 16) +#define VD(vd) (vd) +#define VT(vt) (vt) +#define VN(vn) ((vn) << 5) +#define VM(vm) ((vm) << 16) + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +#define ADC 0x9a000000 +#define ADD 0x8b000000 +#define ADDI 0x91000000 +#define AND 0x8a000000 +#define ANDI 0x92000000 +#define ASRV 0x9ac02800 +#define B 0x14000000 +#define B_CC 0x54000000 +#define BL 0x94000000 +#define BLR 0xd63f0000 +#define BR 0xd61f0000 +#define BRK 0xd4200000 +#define CBZ 0xb4000000 +#define CLZ 0xdac01000 +#define CSINC 0x9a800400 +#define EOR 0xca000000 +#define EORI 0xd2000000 +#define FABS 0x1e60c000 +#define FADD 0x1e602800 +#define FCMP 0x1e602000 +#define FDIV 0x1e601800 +#define FMOV 0x1e604000 +#define FMUL 0x1e600800 +#define FNEG 0x1e614000 +#define FSUB 0x1e603800 +#define LDRI 0xf9400000 +#define LDP 0xa9400000 +#define LDP_PST 0xa8c00000 +#define LSLV 0x9ac02000 +#define LSRV 0x9ac02400 +#define MADD 0x9b000000 +#define MOVK 0xf2800000 +#define MOVN 0x92800000 +#define MOVZ 0xd2800000 +#define NOP 0xd503201f +#define ORN 0xaa200000 +#define ORR 0xaa000000 +#define ORRI 0xb2000000 +#define RET 0xd65f0000 +#define SBC 0xda000000 +#define SBFM 0x93000000 +#define SDIV 0x9ac00c00 +#define SMADDL 0x9b200000 +#define SMULH 0x9b403c00 +#define STP 0xa9000000 +#define STP_PRE 0xa9800000 +#define STRI 0xf9000000 +#define STR_FI 0x3d000000 +#define STR_FR 0x3c206800 +#define STUR_FI 0x3c000000 +#define SUB 0xcb000000 +#define SUBI 0xd1000000 +#define SUBS 0xeb000000 +#define UBFM 0xd3000000 +#define UDIV 0x9ac00800 +#define UMULH 0x9bc03c00 + +/* dest_reg is the absolute name of the register + Useful for reordering instructions in the delay slot. */ +static sljit_si 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 sljit_si emit_imm64_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +{ + FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5))); + FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21))); + FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 32) & 0xffff) << 5) | (2 << 21))); + return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21)); +} + +static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) +{ + sljit_si dst = inst[0] & 0x1f; + SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21))); + inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5); + inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21); + inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21); + inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21); +} + +static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_sw diff; + sljit_uw target_addr; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) { + jump->flags |= PATCH_ABS64; + 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_sw)target_addr - (sljit_sw)(code_ptr + 4); + + if (jump->flags & IS_COND) { + diff += sizeof(sljit_ins); + if (diff <= 0xfffff && diff >= -0x100000) { + code_ptr[-5] ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1; + jump->addr -= sizeof(sljit_ins); + jump->flags |= PATCH_COND; + return 5; + } + diff -= sizeof(sljit_ins); + } + + if (diff <= 0x7ffffff && diff >= -0x8000000) { + jump->flags |= PATCH_B; + return 4; + } + + if (target_addr <= 0xffffffffl) { + if (jump->flags & IS_COND) + code_ptr[-5] -= (2 << 5); + code_ptr[-2] = code_ptr[0]; + return 2; + } + if (target_addr <= 0xffffffffffffl) { + if (jump->flags & IS_COND) + code_ptr[-5] -= (1 << 5); + jump->flags |= PATCH_ABS48; + code_ptr[-1] = code_ptr[0]; + return 1; + } + + jump->flags |= PATCH_ABS64; + 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; + sljit_si dst; + + 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++; + /* 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 (label && label->size == word_count) { + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { + jump->addr = (sljit_uw)(code_ptr - 4); + code_ptr -= detect_jump_type(jump, code_ptr, code); + jump = jump->next; + } + if (const_ && const_->addr == word_count) { + 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 <= (sljit_sw)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_sw)(addr - jump->addr) >> 2; + SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000); + buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff); + if (jump->flags & IS_COND) + buf_ptr[-1] -= (4 << 5); + break; + } + if (jump->flags & PATCH_COND) { + addr = (sljit_sw)(addr - jump->addr) >> 2; + SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000); + buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5); + break; + } + + SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || addr <= 0xffffffffl); + SLJIT_ASSERT((jump->flags & PATCH_ABS64) || addr <= 0xffffffffffffl); + + dst = buf_ptr[0] & 0x1f; + buf_ptr[0] = MOVZ | dst | ((addr & 0xffff) << 5); + buf_ptr[1] = MOVK | dst | (((addr >> 16) & 0xffff) << 5) | (1 << 21); + if (jump->flags & (PATCH_ABS48 | PATCH_ABS64)) + buf_ptr[2] = MOVK | dst | (((addr >> 32) & 0xffff) << 5) | (2 << 21); + if (jump->flags & PATCH_ABS64) + buf_ptr[3] = MOVK | dst | (((addr >> 48) & 0xffff) << 5) | (3 << 21); + } while (0); + jump = jump->next; + } + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); + SLJIT_CACHE_FLUSH(code, code_ptr); + return code; +} + +/* --------------------------------------------------------------------- */ +/* Core code generator functions. */ +/* --------------------------------------------------------------------- */ + +#define COUNT_TRAILING_ZERO(value, result) \ + result = 0; \ + if (!(value & 0xffffffff)) { \ + result += 32; \ + value >>= 32; \ + } \ + if (!(value & 0xffff)) { \ + result += 16; \ + value >>= 16; \ + } \ + if (!(value & 0xff)) { \ + result += 8; \ + value >>= 8; \ + } \ + if (!(value & 0xf)) { \ + result += 4; \ + value >>= 4; \ + } \ + if (!(value & 0x3)) { \ + result += 2; \ + value >>= 2; \ + } \ + if (!(value & 0x1)) { \ + result += 1; \ + value >>= 1; \ + } + +#define LOGICAL_IMM_CHECK 0x100 + +static sljit_ins logical_imm(sljit_sw imm, sljit_si len) +{ + sljit_si negated, ones, right; + sljit_uw mask, uimm; + sljit_ins ins; + + if (len & LOGICAL_IMM_CHECK) { + len &= ~LOGICAL_IMM_CHECK; + if (len == 32 && (imm == 0 || imm == -1)) + return 0; + if (len == 16 && ((sljit_si)imm == 0 || (sljit_si)imm == -1)) + return 0; + } + + SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1) + || (len == 16 && (sljit_si)imm != 0 && (sljit_si)imm != -1)); + uimm = (sljit_uw)imm; + while (1) { + if (len <= 0) { + SLJIT_ASSERT_STOP(); + return 0; + } + mask = ((sljit_uw)1 << len) - 1; + if ((uimm & mask) != ((uimm >> len) & mask)) + break; + len >>= 1; + } + + len <<= 1; + + negated = 0; + if (uimm & 0x1) { + negated = 1; + uimm = ~uimm; + } + + if (len < 64) + uimm &= ((sljit_uw)1 << len) - 1; + + /* Unsigned right shift. */ + COUNT_TRAILING_ZERO(uimm, right); + + /* Signed shift. We also know that the highest bit is set. */ + imm = (sljit_sw)~uimm; + SLJIT_ASSERT(imm < 0); + + COUNT_TRAILING_ZERO(imm, ones); + + if (~imm) + return 0; + + if (len == 64) + ins = 1 << 22; + else + ins = (0x3f - ((len << 1) - 1)) << 10; + + if (negated) + return ins | ((len - ones - 1) << 10) | ((len - ones - right) << 16); + + return ins | ((ones - 1) << 10) | ((len - right) << 16); +} + +#undef COUNT_TRAILING_ZERO + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw simm) +{ + sljit_uw imm = (sljit_uw)simm; + sljit_si i, zeros, ones, first; + sljit_ins bitmask; + + if (imm <= 0xffff) + return push_inst(compiler, MOVZ | RD(dst) | (imm << 5)); + + if (simm >= -0x10000 && simm < 0) + return push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5)); + + if (imm <= 0xffffffffl) { + if ((imm & 0xffff0000l) == 0xffff0000) + return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff) << 5)); + if ((imm & 0xffff) == 0xffff) + return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); + bitmask = logical_imm(simm, 16); + if (bitmask != 0) + return push_inst(compiler, (ORRI ^ W_OP) | RD(dst) | RN(TMP_ZERO) | bitmask); + } + else { + bitmask = logical_imm(simm, 32); + if (bitmask != 0) + return push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask); + } + + if (imm <= 0xffffffffl) { + FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5))); + return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); + } + + if (simm >= -0x100000000l && simm < 0) { + FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5))); + return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21)); + } + + /* A large amount of number can be constructed from ORR and MOVx, + but computing them is costly. We don't */ + + zeros = 0; + ones = 0; + for (i = 4; i > 0; i--) { + if ((simm & 0xffff) == 0) + zeros++; + if ((simm & 0xffff) == 0xffff) + ones++; + simm >>= 16; + } + + simm = (sljit_sw)imm; + first = 1; + if (ones > zeros) { + simm = ~simm; + for (i = 0; i < 4; i++) { + if (!(simm & 0xffff)) { + simm >>= 16; + continue; + } + if (first) { + first = 0; + FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); + } + else + FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((~simm & 0xffff) << 5) | (i << 21))); + simm >>= 16; + } + return SLJIT_SUCCESS; + } + + for (i = 0; i < 4; i++) { + if (!(simm & 0xffff)) { + simm >>= 16; + continue; + } + if (first) { + first = 0; + FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); + } + else + FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((simm & 0xffff) << 5) | (i << 21))); + simm >>= 16; + } + return SLJIT_SUCCESS; +} + +#define ARG1_IMM 0x0010000 +#define ARG2_IMM 0x0020000 +#define INT_OP 0x0040000 +#define SET_FLAGS 0x0080000 +#define UNUSED_RETURN 0x0100000 +#define SLOW_DEST 0x0200000 +#define SLOW_SRC1 0x0400000 +#define SLOW_SRC2 0x0800000 + +#define CHECK_FLAGS(flag_bits) \ + if (flags & SET_FLAGS) { \ + inv_bits |= flag_bits; \ + if (flags & UNUSED_RETURN) \ + dst = TMP_ZERO; \ + } + +static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_sw arg1, sljit_sw arg2) +{ + /* dst must be register, TMP_REG1 + arg1 must be register, TMP_REG1, imm + arg2 must be register, TMP_REG2, imm */ + sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0; + sljit_ins inst_bits; + sljit_si op = (flags & 0xffff); + sljit_si reg; + sljit_sw imm, nimm; + + if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { + /* Both are immediates. */ + flags &= ~ARG1_IMM; + if (arg1 == 0 && op != SLJIT_ADD && op != SLJIT_SUB) + arg1 = TMP_ZERO; + else { + 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 (op) { + case SLJIT_MUL: + case SLJIT_NEG: + case SLJIT_CLZ: + case SLJIT_ADDC: + case SLJIT_SUBC: + /* No form with immediate operand (except imm 0, which + is represented by a ZERO register). */ + break; + case SLJIT_MOV: + SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1); + return load_immediate(compiler, dst, imm); + case SLJIT_NOT: + SLJIT_ASSERT(flags & ARG2_IMM); + FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm)); + goto set_flags; + case SLJIT_SUB: + if (flags & ARG1_IMM) + break; + imm = -imm; + /* Fall through. */ + case SLJIT_ADD: + if (imm == 0) { + CHECK_FLAGS(1 << 29); + return push_inst(compiler, ((op == SLJIT_ADD ? ADDI : SUBI) ^ inv_bits) | RD(dst) | RN(reg)); + } + if (imm > 0 && imm <= 0xfff) { + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (imm << 10)); + } + nimm = -imm; + if (nimm > 0 && nimm <= 0xfff) { + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (nimm << 10)); + } + if (imm > 0 && imm <= 0xffffff && !(imm & 0xfff)) { + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22)); + } + if (nimm > 0 && nimm <= 0xffffff && !(nimm & 0xfff)) { + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22)); + } + if (imm > 0 && imm <= 0xffffff && !(flags & SET_FLAGS)) { + FAIL_IF(push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22))); + return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(dst) | ((imm & 0xfff) << 10)); + } + if (nimm > 0 && nimm <= 0xffffff && !(flags & SET_FLAGS)) { + FAIL_IF(push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22))); + return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(dst) | ((nimm & 0xfff) << 10)); + } + break; + case SLJIT_AND: + inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32)); + if (!inst_bits) + break; + CHECK_FLAGS(3 << 29); + return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits); + case SLJIT_OR: + case SLJIT_XOR: + inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32)); + if (!inst_bits) + break; + if (op == SLJIT_OR) + inst_bits |= ORRI; + else + inst_bits |= EORI; + FAIL_IF(push_inst(compiler, (inst_bits ^ inv_bits) | RD(dst) | RN(reg))); + goto set_flags; + case SLJIT_SHL: + if (flags & ARG1_IMM) + break; + if (flags & INT_OP) { + imm &= 0x1f; + FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | ((-imm & 0x1f) << 16) | ((31 - imm) << 10))); + } + else { + imm &= 0x3f; + FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | ((-imm & 0x3f) << 16) | ((63 - imm) << 10))); + } + goto set_flags; + case SLJIT_LSHR: + case SLJIT_ASHR: + if (flags & ARG1_IMM) + break; + if (op == SLJIT_ASHR) + inv_bits |= 1 << 30; + if (flags & INT_OP) { + imm &= 0x1f; + FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (imm << 16) | (31 << 10))); + } + else { + imm &= 0x3f; + FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | (imm << 16) | (63 << 10))); + } + goto set_flags; + default: + SLJIT_ASSERT_STOP(); + break; + } + + if (flags & ARG2_IMM) { + if (arg2 == 0) + arg2 = TMP_ZERO; + else { + FAIL_IF(load_immediate(compiler, TMP_REG2, arg2)); + arg2 = TMP_REG2; + } + } + else { + if (arg1 == 0) + arg1 = TMP_ZERO; + else { + FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); + arg1 = TMP_REG1; + } + } + } + + /* Both arguments are registers. */ + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: + case SLJIT_MOVU: + case SLJIT_MOVU_P: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (dst == arg2) + return SLJIT_SUCCESS; + return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + case SLJIT_MOV_UB: + case SLJIT_MOVU_UB: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10)); + case SLJIT_MOV_SB: + case SLJIT_MOVU_SB: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (!(flags & INT_OP)) + inv_bits |= 1 << 22; + return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); + case SLJIT_MOV_UH: + case SLJIT_MOVU_UH: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10)); + case SLJIT_MOV_SH: + case SLJIT_MOVU_SH: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (!(flags & INT_OP)) + inv_bits |= 1 << 22; + return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10)); + case SLJIT_MOV_UI: + case SLJIT_MOVU_UI: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if ((flags & INT_OP) && dst == arg2) + return SLJIT_SUCCESS; + return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + case SLJIT_MOV_SI: + case SLJIT_MOVU_SI: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if ((flags & INT_OP) && dst == arg2) + return SLJIT_SUCCESS; + return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10)); + case SLJIT_NOT: + SLJIT_ASSERT(arg1 == TMP_REG1); + FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2))); + goto set_flags; + case SLJIT_NEG: + SLJIT_ASSERT(arg1 == TMP_REG1); + if (flags & SET_FLAGS) + inv_bits |= 1 << 29; + return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + case SLJIT_CLZ: + SLJIT_ASSERT(arg1 == TMP_REG1); + FAIL_IF(push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2))); + goto set_flags; + case SLJIT_ADD: + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (ADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); + case SLJIT_ADDC: + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (ADC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); + case SLJIT_SUB: + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); + case SLJIT_SUBC: + CHECK_FLAGS(1 << 29); + return push_inst(compiler, (SBC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); + case SLJIT_MUL: + if (!(flags & SET_FLAGS)) + return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)); + if (flags & INT_OP) { + FAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10))); + FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG4) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10))); + return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_REG4) | RM(dst) | (2 << 22) | (63 << 10)); + } + FAIL_IF(push_inst(compiler, SMULH | RD(TMP_REG4) | RN(arg1) | RM(arg2))); + FAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO))); + return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_REG4) | RM(dst) | (2 << 22) | (63 << 10)); + case SLJIT_AND: + CHECK_FLAGS(3 << 29); + return push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)); + case SLJIT_OR: + FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); + goto set_flags; + case SLJIT_XOR: + FAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); + goto set_flags; + case SLJIT_SHL: + FAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); + goto set_flags; + case SLJIT_LSHR: + FAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); + goto set_flags; + case SLJIT_ASHR: + FAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2))); + goto set_flags; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + +set_flags: + if (flags & SET_FLAGS) + return push_inst(compiler, (SUBS ^ inv_bits) | RD(TMP_ZERO) | RN(dst) | RM(TMP_ZERO)); + return SLJIT_SUCCESS; +} + +#define STORE 0x01 +#define SIGNED 0x02 + +#define UPDATE 0x04 +#define ARG_TEST 0x08 + +#define BYTE_SIZE 0x000 +#define HALF_SIZE 0x100 +#define INT_SIZE 0x200 +#define WORD_SIZE 0x300 + +#define MEM_SIZE_SHIFT(flags) ((flags) >> 8) + +static SLJIT_CONST sljit_ins sljit_mem_imm[4] = { +/* u l */ 0x39400000 /* ldrb [reg,imm] */, +/* u s */ 0x39000000 /* strb [reg,imm] */, +/* s l */ 0x39800000 /* ldrsb [reg,imm] */, +/* s s */ 0x39000000 /* strb [reg,imm] */, +}; + +static SLJIT_CONST sljit_ins sljit_mem_simm[4] = { +/* u l */ 0x38400000 /* ldurb [reg,imm] */, +/* u s */ 0x38000000 /* sturb [reg,imm] */, +/* s l */ 0x38800000 /* ldursb [reg,imm] */, +/* s s */ 0x38000000 /* sturb [reg,imm] */, +}; + +static SLJIT_CONST sljit_ins sljit_mem_pre_simm[4] = { +/* u l */ 0x38400c00 /* ldrb [reg,imm]! */, +/* u s */ 0x38000c00 /* strb [reg,imm]! */, +/* s l */ 0x38800c00 /* ldrsb [reg,imm]! */, +/* s s */ 0x38000c00 /* strb [reg,imm]! */, +}; + +static SLJIT_CONST sljit_ins sljit_mem_reg[4] = { +/* u l */ 0x38606800 /* ldrb [reg,reg] */, +/* u s */ 0x38206800 /* strb [reg,reg] */, +/* s l */ 0x38a06800 /* ldrsb [reg,reg] */, +/* s s */ 0x38206800 /* strb [reg,reg] */, +}; + +/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ +static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +{ + if (value >= 0) { + if (value <= 0xfff) + return push_inst(compiler, ADDI | RD(dst) | RN(reg) | (value << 10)); + if (value <= 0xffffff && !(value & 0xfff)) + return push_inst(compiler, ADDI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2)); + } + else { + value = -value; + if (value <= 0xfff) + return push_inst(compiler, SUBI | RD(dst) | RN(reg) | (value << 10)); + if (value <= 0xffffff && !(value & 0xfff)) + return push_inst(compiler, SUBI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2)); + } + return SLJIT_ERR_UNSUPPORTED; +} + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_ui shift = MEM_SIZE_SHIFT(flags); + + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (SLJIT_UNLIKELY(flags & UPDATE)) { + if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 255 && argw >= -256) { + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + arg &= REG_MASK; + argw &= 0x1ff; + FAIL_IF(push_inst(compiler, sljit_mem_pre_simm[flags & 0x3] + | (shift << 30) | RT(reg) | RN(arg) | (argw << 12))); + return -1; + } + return 0; + } + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + argw &= 0x3; + if (argw && argw != shift) + return 0; + + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) + | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0))); + return -1; + } + + arg &= REG_MASK; + if (argw >= 0 && (argw >> shift) <= 0xfff && (argw & ((1 << shift) - 1)) == 0) { + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) + | RT(reg) | RN(arg) | (argw << (10 - shift)))); + return -1; + } + + if (argw > 255 || argw < -256) + return 0; + + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + FAIL_IF(push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30) + | RT(reg) | RN(arg) | ((argw & 0x1ff) << 12))); + 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 sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_sw diff; + if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) + return 0; + + if (!(arg & REG_MASK)) { + diff = argw - next_argw; + if (diff <= 0xfff && diff >= -0xfff) + return 1; + return 0; + } + + if (argw == next_argw) + return 1; + + diff = argw - next_argw; + if (arg == next_arg && diff <= 0xfff && diff >= -0xfff) + return 1; + + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, + sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_ui shift = MEM_SIZE_SHIFT(flags); + sljit_si tmp_r, other_r; + sljit_sw diff; + + 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) && (arg & REG_MASK))) { + /* Update only applies if a base register exists. */ + other_r = OFFS_REG(arg); + if (!other_r) { + other_r = arg & REG_MASK; + if (other_r != reg && argw >= 0 && argw <= 0xffffff) { + if ((argw & 0xfff) != 0) + FAIL_IF(push_inst(compiler, ADDI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10))); + if (argw >> 12) + FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10))); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r)); + } + else if (other_r != reg && argw < 0 && argw >= -0xffffff) { + argw = -argw; + if ((argw & 0xfff) != 0) + FAIL_IF(push_inst(compiler, SUBI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10))); + if (argw >> 12) + FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10))); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r)); + } + + if (compiler->cache_arg == SLJIT_MEM) { + if (argw == compiler->cache_argw) { + other_r = 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; + other_r = TMP_REG3; + argw = 0; + } + } + + if (argw) { + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + other_r = TMP_REG3; + argw = 0; + } + } + + /* No caching here. */ + arg &= REG_MASK; + argw &= 0x3; + if (!argw || argw == shift) { + FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(other_r) | (argw ? (1 << 12) : 0))); + return push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10)); + } + if (arg != reg) { + FAIL_IF(push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10))); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg)); + } + FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG4) | RN(arg) | RM(other_r) | (argw << 10))); + FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG4))); + return push_inst(compiler, ORR | RD(arg) | RN(TMP_ZERO) | RM(TMP_REG4)); + } + + if (arg & OFFS_REG_MASK) { + other_r = OFFS_REG(arg); + arg &= REG_MASK; + FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RN(arg) | RM(other_r) | ((argw & 0x3) << 10))); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(tmp_r)); + } + + if (compiler->cache_arg == arg) { + diff = argw - compiler->cache_argw; + if (diff <= 255 && diff >= -256) + return push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30) + | RT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg)); + } + } + + if (argw >= 0 && argw <= 0xffffff && (argw & ((1 << shift) - 1)) == 0) { + FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_r) | RN(arg & REG_MASK) | ((argw >> 12) << 10))); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) + | RT(reg) | RN(tmp_r) | ((argw & 0xfff) << (10 - shift))); + } + + diff = argw - next_argw; + next_arg = (arg & REG_MASK) && (arg == next_arg) && diff <= 0xfff && diff >= -0xfff && diff != 0; + arg &= REG_MASK; + + if (arg && compiler->cache_arg == SLJIT_MEM) { + if (compiler->cache_argw == argw) + return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(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_inst(compiler, ADD | RD(TMP_REG3) | RN(TMP_REG3) | RM(arg))); + compiler->cache_arg = SLJIT_MEM | arg; + arg = 0; + } + } + + if (arg) + return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3)); + return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3)); +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw 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); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + compiler->locals_offset = (2 + saveds) * sizeof(sljit_sw); + local_size = (compiler->locals_offset + local_size + 15) & ~15; + compiler->local_size = local_size; + + if (local_size <= (64 << 3)) + FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) + | RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15))); + else { + local_size -= (64 << 3); + if (local_size > 0xfff) { + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); + local_size &= 0xfff; + } + if (local_size) + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); + FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) | RN(TMP_SP) | (0x40 << 15))); + } + + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_LOCALS_REG) | RN(TMP_SP))); + + if (saveds >= 2) + FAIL_IF(push_inst(compiler, STP | RT(SLJIT_SAVED_REG1) | RT2(SLJIT_SAVED_REG2) | RN(TMP_SP) | (2 << 15))); + if (saveds >= 4) + FAIL_IF(push_inst(compiler, STP | RT(SLJIT_SAVED_REG3) | RT2(SLJIT_SAVED_EREG1) | RN(TMP_SP) | (4 << 15))); + if (saveds == 1) + FAIL_IF(push_inst(compiler, STRI | RT(SLJIT_SAVED_REG1) | RN(TMP_SP) | (2 << 10))); + if (saveds == 3) + FAIL_IF(push_inst(compiler, STRI | RT(SLJIT_SAVED_REG3) | RN(TMP_SP) | (4 << 10))); + if (saveds == 5) + FAIL_IF(push_inst(compiler, STRI | RT(SLJIT_SAVED_EREG2) | RN(TMP_SP) | (6 << 10))); + + if (args >= 1) + FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_SAVED_REG1) | RN(TMP_ZERO) | RM(SLJIT_SCRATCH_REG1))); + if (args >= 2) + FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_SAVED_REG2) | RN(TMP_ZERO) | RM(SLJIT_SCRATCH_REG2))); + if (args >= 3) + FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_SAVED_REG3) | RN(TMP_ZERO) | RM(SLJIT_SCRATCH_REG3))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + compiler->locals_offset = (2 + saveds) * sizeof(sljit_sw); + compiler->local_size = (compiler->locals_offset + local_size + 15) & ~15; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si saveds, local_size; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + saveds = compiler->saveds; + + if (saveds >= 2) + FAIL_IF(push_inst(compiler, LDP | RT(SLJIT_SAVED_REG1) | RT2(SLJIT_SAVED_REG2) | RN(TMP_SP) | (2 << 15))); + if (saveds >= 4) + FAIL_IF(push_inst(compiler, LDP | RT(SLJIT_SAVED_REG3) | RT2(SLJIT_SAVED_EREG1) | RN(TMP_SP) | (4 << 15))); + if (saveds == 1) + FAIL_IF(push_inst(compiler, LDRI | RT(SLJIT_SAVED_REG1) | RN(TMP_SP) | (2 << 10))); + if (saveds == 3) + FAIL_IF(push_inst(compiler, LDRI | RT(SLJIT_SAVED_REG3) | RN(TMP_SP) | (4 << 10))); + if (saveds == 5) + FAIL_IF(push_inst(compiler, LDRI | RT(SLJIT_SAVED_EREG2) | RN(TMP_SP) | (6 << 10))); + + local_size = compiler->local_size; + + if (local_size <= (62 << 3)) + FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) + | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15))); + else { + FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) | RN(TMP_SP) | (0x3e << 15))); + local_size -= (62 << 3); + if (local_size > 0xfff) { + FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); + local_size &= 0xfff; + } + if (local_size) + FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); + } + + FAIL_IF(push_inst(compiler, RET | RN(TMP_LR))); + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + sljit_ins inv_bits = (op & SLJIT_INT_OP) ? (1 << 31) : 0; + + CHECK_ERROR(); + check_sljit_emit_op0(compiler, op); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + return push_inst(compiler, BRK); + case SLJIT_NOP: + return push_inst(compiler, NOP); + case SLJIT_UMUL: + case SLJIT_SMUL: + FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_SCRATCH_REG1))); + FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_SCRATCH_REG1) | RN(SLJIT_SCRATCH_REG1) | RM(SLJIT_SCRATCH_REG2) | RT2(TMP_ZERO))); + return push_inst(compiler, (op == SLJIT_SMUL ? SMULH : UMULH) | RD(SLJIT_SCRATCH_REG2) | RN(TMP_REG1) | RM(SLJIT_SCRATCH_REG2)); + case SLJIT_UDIV: + case SLJIT_SDIV: + FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_SCRATCH_REG1))); + FAIL_IF(push_inst(compiler, ((op == SLJIT_SDIV ? SDIV : UDIV) ^ inv_bits) | RD(SLJIT_SCRATCH_REG1) | RN(SLJIT_SCRATCH_REG1) | RM(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_SCRATCH_REG2) | RN(SLJIT_SCRATCH_REG1) | RM(SLJIT_SCRATCH_REG2) | RT2(TMP_ZERO))); + return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_SCRATCH_REG2) | RN(TMP_REG1) | RM(SLJIT_SCRATCH_REG2)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r, flags, mem_flags; + sljit_si op_flags = GET_ALL_FLAGS(op); + + 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; + + dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + + op = GET_OPCODE(op); + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_P: + flags = WORD_SIZE; + break; + case SLJIT_MOV_UB: + flags = BYTE_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOV_SB: + flags = BYTE_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOV_UH: + flags = HALF_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOV_SH: + flags = HALF_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_sh)srcw; + break; + case SLJIT_MOV_UI: + flags = INT_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_ui)srcw; + break; + case SLJIT_MOV_SI: + flags = INT_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_si)srcw; + break; + case SLJIT_MOVU: + case SLJIT_MOVU_P: + flags = WORD_SIZE | UPDATE; + break; + case SLJIT_MOVU_UB: + flags = BYTE_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOVU_SB: + flags = BYTE_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOVU_UH: + flags = HALF_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOVU_SH: + flags = HALF_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_sh)srcw; + break; + case SLJIT_MOVU_UI: + flags = INT_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_ui)srcw; + break; + case SLJIT_MOVU_SI: + flags = INT_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_si)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 | ((op_flags & SLJIT_INT_OP) ? INT_OP : 0), 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; + } + + flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0; + mem_flags = WORD_SIZE; + if (op_flags & SLJIT_INT_OP) { + flags |= INT_OP; + mem_flags = INT_SIZE; + } + + if (dst == SLJIT_UNUSED) + flags |= UNUSED_RETURN; + + if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src, srcw)) + FAIL_IF(compiler->error); + else + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src, srcw, dst, dstw)); + src = TMP_REG2; + } + + if (src & SLJIT_IMM) { + flags |= ARG2_IMM; + if (op_flags & SLJIT_INT_OP) + srcw = (sljit_si)srcw; + } else + srcw = src; + + emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw); + + if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw)) + return compiler->error; + else + return getput_arg(compiler, mem_flags | STORE, dst_r, dst, dstw, 0, 0); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r, flags, mem_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 = SLOW_IS_REG(dst) ? dst : TMP_REG1; + flags = GET_FLAGS(op) ? SET_FLAGS : 0; + mem_flags = WORD_SIZE; + if (op & SLJIT_INT_OP) { + flags |= INT_OP; + mem_flags = INT_SIZE; + } + + if (dst == SLJIT_UNUSED) + flags |= UNUSED_RETURN; + + if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, mem_flags | STORE | ARG_TEST, TMP_REG1, dst, dstw)) + flags |= SLOW_DEST; + + if (src1 & SLJIT_MEM) { + if (getput_arg_fast(compiler, mem_flags, TMP_REG1, src1, src1w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC1; + } + if (src2 & SLJIT_MEM) { + if (getput_arg_fast(compiler, mem_flags, 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, mem_flags, TMP_REG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, mem_flags, 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; + + emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w); + + if (dst & SLJIT_MEM) { + if (!(flags & SLOW_DEST)) { + getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw); + return compiler->error; + } + return getput_arg(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + check_sljit_get_float_register_index(reg); + return reg; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si 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 sljit_si sljit_is_fpu_available(void) +{ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#else + /* Available by default. */ + return 1; +#endif +} + +static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_ui shift = MEM_SIZE_SHIFT(flags); + sljit_ins ins_bits = (shift << 30); + sljit_si other_r; + sljit_sw diff; + + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (!(flags & STORE)) + ins_bits |= 1 << 22; + + if (arg & OFFS_REG_MASK) { + argw &= 3; + if (!argw || argw == shift) + return push_inst(compiler, STR_FR | ins_bits | VT(reg) + | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0)); + other_r = OFFS_REG(arg); + arg &= REG_MASK; + FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg) | RM(other_r) | (argw << 10))); + arg = TMP_REG1; + argw = 0; + } + + arg &= REG_MASK; + if (arg && argw >= 0 && ((argw >> shift) <= 0xfff) && (argw & ((1 << shift) - 1)) == 0) + return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(arg) | (argw << (10 - shift))); + + if (arg && argw <= 255 && argw >= -256) + return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(arg) | ((argw & 0x1ff) << 12)); + + /* Slow cases */ + if (compiler->cache_arg == SLJIT_MEM && argw != compiler->cache_argw) { + diff = argw - compiler->cache_argw; + if (!arg && diff <= 255 && diff >= -256) + return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + } + } + + if (compiler->cache_arg != SLJIT_MEM || argw != compiler->cache_argw) { + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + } + + if (arg & REG_MASK) + return push_inst(compiler, STR_FR | ins_bits | VT(reg) | RN(arg) | RM(TMP_REG3)); + return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; + sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + + 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_CMPD) { + if (dst & SLJIT_MEM) { + emit_fop_mem(compiler, mem_flags, TMP_FREG1, dst, dstw); + dst = TMP_FREG1; + } + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, mem_flags, TMP_FREG2, src, srcw); + src = TMP_FREG2; + } + return push_inst(compiler, (FCMP ^ inv_bits) | VN(dst) | VM(src)); + } + + dst_r = (dst <= REG_MASK) ? dst : TMP_FREG1; + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, mem_flags, dst_r, src, srcw); + src = dst_r; + } + + switch (GET_OPCODE(op)) { + case SLJIT_MOVD: + if (src != dst_r) + FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src))); + break; + case SLJIT_NEGD: + FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src))); + break; + case SLJIT_ABSD: + FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src))); + break; + } + + if (!(dst & SLJIT_MEM)) + return SLJIT_SUCCESS; + return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; + sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + + 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 <= REG_MASK) ? dst : TMP_FREG1; + if (src1 & SLJIT_MEM) { + emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); + src1 = TMP_FREG1; + } + if (src2 & SLJIT_MEM) { + emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); + src2 = TMP_FREG2; + } + + switch (GET_OPCODE(op)) { + case SLJIT_ADDD: + FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); + break; + case SLJIT_SUBD: + FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); + break; + case SLJIT_MULD: + FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); + break; + case SLJIT_DIVD: + FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); + break; + } + + if (!(dst & SLJIT_MEM)) + return SLJIT_SUCCESS; + return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw); +} + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + 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) + return SLJIT_SUCCESS; + + if (dst <= REG_MASK) + return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR)); + + /* Memory. */ + return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src <= REG_MASK) + FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src))); + else if (src & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw)); + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, TMP_LR, srcw)); + + return push_inst(compiler, RET | RN(TMP_LR)); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +static sljit_uw get_cc(sljit_si type) +{ + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_MUL_NOT_OVERFLOW: + case SLJIT_C_FLOAT_EQUAL: + return 0x1; + + case SLJIT_C_NOT_EQUAL: + case SLJIT_C_MUL_OVERFLOW: + case SLJIT_C_FLOAT_NOT_EQUAL: + return 0x0; + + case SLJIT_C_LESS: + case SLJIT_C_FLOAT_LESS: + return 0x2; + + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_GREATER_EQUAL: + return 0x3; + + case SLJIT_C_GREATER: + case SLJIT_C_FLOAT_GREATER: + return 0x9; + + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_LESS_EQUAL: + return 0x8; + + case SLJIT_C_SIG_LESS: + return 0xa; + + case SLJIT_C_SIG_GREATER_EQUAL: + return 0xb; + + case SLJIT_C_SIG_GREATER: + return 0xd; + + case SLJIT_C_SIG_LESS_EQUAL: + return 0xc; + + case SLJIT_C_OVERFLOW: + case SLJIT_C_FLOAT_UNORDERED: + return 0x7; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_FLOAT_ORDERED: + return 0x6; + + default: + SLJIT_ASSERT_STOP(); + 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, sljit_si 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; + + if (type < SLJIT_JUMP) { + jump->flags |= IS_COND; + PTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(type))); + } + else if (type >= SLJIT_FAST_CALL) + jump->flags |= IS_BL; + + PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1))); + + return jump; +} + +static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_si type, + sljit_si src, sljit_sw srcw) +{ + struct sljit_jump *jump; + sljit_ins inv_bits = (type & SLJIT_INT_OP) ? (1 << 31) : 0; + + SLJIT_ASSERT((type & 0xff) == SLJIT_C_EQUAL || (type & 0xff) == SLJIT_C_NOT_EQUAL); + ADJUST_LOCAL_OFFSET(src, srcw); + + 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_CBZ | IS_COND; + + if (src & SLJIT_MEM) { + PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw)); + src = TMP_REG1; + } + else if (src & SLJIT_IMM) { + PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } + SLJIT_ASSERT(FAST_IS_REG(src)); + + if ((type & 0xff) == SLJIT_C_EQUAL) + inv_bits |= 1 << 24; + + PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src))); + PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG1))); + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw 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)) { + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw)); + src = TMP_REG1; + } + return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src)); + } + + 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_imm64_const(compiler, TMP_REG1, 0)); + jump->addr = compiler->size; + return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si dst_r, flags, mem_flags; + sljit_ins cc; + + CHECK_ERROR(); + check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + cc = get_cc(type); + dst_r = (dst <= REG_MASK) ? dst : TMP_REG1; + + if (GET_OPCODE(op) < SLJIT_ADD) { + FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO))); + if (dst_r != TMP_REG1) + return SLJIT_SUCCESS; + return emit_op_mem(compiler, (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE, TMP_REG1, dst, dstw); + } + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + flags = GET_FLAGS(op) ? SET_FLAGS : 0; + mem_flags = WORD_SIZE; + if (op & SLJIT_INT_OP) { + flags |= INT_OP; + mem_flags = INT_SIZE; + } + + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, mem_flags, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } else if (src & SLJIT_IMM) + flags |= ARG1_IMM; + + FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(TMP_ZERO))); + emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src, TMP_REG2); + + if (dst_r != TMP_REG1) + return SLJIT_SUCCESS; + return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si 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 = SLOW_IS_REG(dst) ? dst : TMP_REG1; + PTR_FAIL_IF(emit_imm64_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) +{ + sljit_ins* inst = (sljit_ins*)addr; + modify_imm64_const(inst, new_addr); + SLJIT_CACHE_FLUSH(inst, inst + 4); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_ins* inst = (sljit_ins*)addr; + modify_imm64_const(inst, new_constant); + SLJIT_CACHE_FLUSH(inst, inst + 4); +} diff --git a/tools/pcre/sljit/sljitNativeARM_T2_32.c b/tools/pcre/sljit/sljitNativeARM_T2_32.c new file mode 100644 index 00000000..682f964e --- /dev/null +++ b/tools/pcre/sljit/sljitNativeARM_T2_32.c @@ -0,0 +1,2007 @@ +/* + * 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(void) +{ + return "ARM-Thumb2" SLJIT_CPUINFO; +} + +/* Length of an instruction word. */ +typedef sljit_ui sljit_ins; + +/* 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 (0) +#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 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, 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)) + +/* --------------------------------------------------------------------- */ +/* 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_F32 0xeeb00ac0 +#define VADD_F32 0xee300a00 +#define VCMP_F32 0xeeb40a40 +#define VDIV_F32 0xee800a00 +#define VMOV_F32 0xeeb00a40 +#define VMRS 0xeef1fa10 +#define VMUL_F32 0xee200a00 +#define VNEG_F32 0xeeb10a40 +#define VSTR_F32 0xed000a00 +#define VSUB_F32 0xee300a40 + +static sljit_si 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 sljit_si 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 sljit_si emit_imm32_const(struct sljit_compiler *compiler, sljit_si 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) +{ + sljit_si 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 sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code) +{ + sljit_sw 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_sw)jump->u.target - (sljit_sw)(code_ptr + 2)) >> 1; + } + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)) >> 1; + } + + if (jump->flags & IS_COND) { + SLJIT_ASSERT(!(jump->flags & IS_BL)); + if (diff <= 127 && diff >= -128) { + jump->flags |= PATCH_TYPE1; + return 5; + } + if (diff <= 524287 && diff >= -524288) { + jump->flags |= PATCH_TYPE2; + return 4; + } + /* +1 comes from the prefix IT instruction. */ + diff--; + if (diff <= 8388607 && diff >= -8388608) { + jump->flags |= PATCH_TYPE3; + return 3; + } + } + else if (jump->flags & IS_BL) { + if (diff <= 8388607 && diff >= -8388608) { + jump->flags |= PATCH_BL; + return 3; + } + } + else { + if (diff <= 1023 && diff >= -1024) { + jump->flags |= PATCH_TYPE4; + return 4; + } + if (diff <= 8388607 && diff >= -8388608) { + jump->flags |= PATCH_TYPE5; + return 3; + } + } + + return 0; +} + +static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) +{ + sljit_si type = (jump->flags >> 4) & 0xf; + sljit_sw diff; + sljit_uh *jump_inst; + sljit_si s, j1, j2; + + if (SLJIT_UNLIKELY(type == 0)) { + modify_imm32_const((sljit_uh*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target); + return; + } + + if (jump->flags & JUMP_ADDR) { + SLJIT_ASSERT(jump->u.target & 0x1); + diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + 4)) >> 1; + } + else + diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(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_COND)); + 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_COND)); + 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_COND); + *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_COND)); + 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_COND) ? 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 <= (sljit_sw)compiler->size); + + jump = compiler->jumps; + while (jump) { + set_jump_instruction(jump); + jump = jump->next; + } + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_uh); + SLJIT_CACHE_FLUSH(code, code_ptr); + /* Set thumb mode flag. */ + return (void*)((sljit_uw)code | 0x1); +} + +/* --------------------------------------------------------------------- */ +/* Core code generator functions. */ +/* --------------------------------------------------------------------- */ + +#define INVALID_IMM 0x80000000 +static sljit_uw get_imm(sljit_uw imm) +{ + /* Thumb immediate form. */ + sljit_si 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 sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si 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 +/* 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 sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si 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 */ + sljit_si reg; + sljit_uw imm, nimm; + + 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_CLZ: + case SLJIT_MUL: + /* No form with immediate operand. */ + break; + 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 some clever things could be done here, "NOT IMM" does not worth the efforts. */ + break; + case SLJIT_ADD: + nimm = -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 (nimm <= 0x7) + return push_inst16(compiler, SUBSI3 | IMM3(nimm) | RD3(dst) | RN3(reg)); + if (reg == dst) { + if (imm <= 0xff) + return push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst)); + if (nimm <= 0xff) + return push_inst16(compiler, SUBSI8 | IMM8(nimm) | RDN3(dst)); + } + } + if (!(flags & SET_FLAGS)) { + if (imm <= 0xfff) + return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm)); + if (nimm <= 0xfff) + return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(nimm)); + } + 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 & ARG1_IMM) { + 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; + } + nimm = -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 (nimm <= 0x7) + return push_inst16(compiler, ADDSI3 | IMM3(nimm) | RD3(dst) | RN3(reg)); + if (reg == dst) { + if (imm <= 0xff) + return push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst)); + if (nimm <= 0xff) + return push_inst16(compiler, ADDSI8 | IMM8(nimm) | 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 (nimm <= 0xfff) + return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(nimm)); + } + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_SUBC: + if (flags & ARG1_IMM) + break; + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_AND: + nimm = get_imm(imm); + if (nimm != INVALID_IMM) + return push_inst32(compiler, ANDI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm); + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_OR: + nimm = get_imm(imm); + if (nimm != INVALID_IMM) + return push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm); + imm = get_imm(imm); + 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: + case SLJIT_LSHR: + case SLJIT_ASHR: + if (flags & ARG1_IMM) + break; + 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)); + } + switch (flags & 0xffff) { + case SLJIT_SHL: + 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)); + case SLJIT_LSHR: + 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)); + default: /* SLJIT_ASHR */ + 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)); + } + 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_MOV_P: + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + case SLJIT_MOVU_P: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (dst == arg2) + return SLJIT_SUCCESS; + 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_ins 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_ins 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_ins 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 sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw 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 sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_si other_r, shift; + + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (SLJIT_UNLIKELY(flags & UPDATE)) { + if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 0xff && argw >= -0xff) { + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + flags &= ~UPDATE; + arg &= 0xf; + 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 0; + } + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + argw &= 0x3; + other_r = OFFS_REG(arg); + arg &= 0xf; + + if (!argw && IS_3_LO_REGS(reg, arg, other_r)) + FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r))); + else + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4))); + return -1; + } + + if (!(arg & REG_MASK) || argw > 0xfff || argw < -0xff) + return 0; + + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + arg &= 0xf; + if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) { + shift = 3; + if (IS_WORD_SIZE(flags)) { + if (OFFSET_CHECK(0x1f, 2)) + shift = 2; + } + else if (flags & BYTE_SIZE) + { + if (OFFSET_CHECK(0x1f, 0)) + shift = 0; + } + else { + SLJIT_ASSERT(flags & HALF_SIZE); + if (OFFSET_CHECK(0x1f, 1)) + shift = 1; + } + + if (shift != 3) { + FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - shift)))); + 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 sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_sw diff; + if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) + return 0; + + if (!(arg & REG_MASK)) { + diff = argw - next_argw; + if (diff <= 0xfff && diff >= -0xfff) + return 1; + return 0; + } + + if (argw == next_argw) + return 1; + + diff = argw - next_argw; + if (arg == next_arg && diff <= 0xfff && diff >= -0xfff) + return 1; + + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, + sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_r, other_r; + sljit_sw diff; + + 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) && (arg & REG_MASK))) { + /* Update only applies if a base register exists. */ + /* There is no caching here. */ + other_r = OFFS_REG(arg); + arg &= 0xf; + flags &= ~UPDATE; + + if (!other_r) { + 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) { + other_r = 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; + other_r = TMP_REG3; + argw = 0; + } + } + + if (argw) { + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + other_r = TMP_REG3; + argw = 0; + } + } + + argw &= 0x3; + if (!argw && IS_3_LO_REGS(reg, arg, other_r)) { + FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r))); + return push_inst16(compiler, ADD | SET_REGS44(arg, other_r)); + } + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4))); + return push_inst32(compiler, ADD_W | RD4(arg) | RN4(arg) | RM4(other_r) | (argw << 6)); + } + flags &= ~UPDATE; + + SLJIT_ASSERT(!(arg & OFFS_REG_MASK)); + + if (compiler->cache_arg == arg) { + diff = argw - compiler->cache_argw; + if (!(diff & ~0xfff)) + return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | diff); + 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, diff) != 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 & REG_MASK) && (arg == next_arg) && (argw != next_argw); + arg &= 0xf; + if (arg && compiler->cache_arg == SLJIT_MEM) { + if (compiler->cache_argw == argw) + return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + 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; + + diff = argw - next_argw; + if (next_arg && diff <= 0xfff && diff >= -0xfff) { + 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 sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw 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); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +/* --------------------------------------------------------------------- */ +/* Entry, exit */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si size; + sljit_ins push; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + 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 (scratches >= 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_SCRATCH_REG1))); + if (args >= 2) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_SCRATCH_REG2))); + if (args >= 3) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_SCRATCH_REG3))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_si size; + + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + 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 sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_ins pop; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, 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->scratches >= 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 int numerator, int unsigned denominator); +extern int __aeabi_idivmod(int numerator, int denominator); +#else +#error "Software divmod functions are needed" +#endif + +#ifdef __cplusplus +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +{ + CHECK_ERROR(); + check_sljit_emit_op0(compiler, op); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + return push_inst16(compiler, BKPT); + case SLJIT_NOP: + return push_inst16(compiler, NOP); + case SLJIT_UMUL: + case SLJIT_SMUL: + return push_inst32(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) + | (reg_map[SLJIT_SCRATCH_REG2] << 8) + | (reg_map[SLJIT_SCRATCH_REG1] << 12) + | (reg_map[SLJIT_SCRATCH_REG1] << 16) + | reg_map[SLJIT_SCRATCH_REG2]); + case SLJIT_UDIV: + case SLJIT_SDIV: + if (compiler->scratches >= 4) { + FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */)); + FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */)); + } else if (compiler->scratches >= 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->scratches >= 4) { + FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */)); + return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */); + } else if (compiler->scratches >= 3) + return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */); + return SLJIT_SUCCESS; + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r, flags; + sljit_si op_flags = GET_ALL_FLAGS(op); + + 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; + + dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + + op = GET_OPCODE(op); + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { + switch (op) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOV_P: + flags = WORD_SIZE; + break; + case SLJIT_MOV_UB: + flags = BYTE_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOV_SB: + flags = BYTE_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOV_UH: + flags = HALF_SIZE; + if (src & SLJIT_IMM) + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOV_SH: + flags = HALF_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (sljit_sh)srcw; + break; + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + case SLJIT_MOVU_P: + flags = WORD_SIZE | UPDATE; + break; + case SLJIT_MOVU_UB: + flags = BYTE_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_ub)srcw; + break; + case SLJIT_MOVU_SB: + flags = BYTE_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_sb)srcw; + break; + case SLJIT_MOVU_UH: + flags = HALF_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_uh)srcw; + break; + case SLJIT_MOVU_SH: + flags = HALF_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (sljit_sh)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, 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 == 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 | op_flags, dst, dstw, SLJIT_IMM, 0, src, srcw); + } + + flags = (GET_FLAGS(op_flags) ? SET_FLAGS : 0) | ((op_flags & 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, 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 sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si 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 = SLOW_IS_REG(dst) ? 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; + + 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 sljit_si sljit_get_register_index(sljit_si reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + check_sljit_get_float_register_index(reg); + return reg; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si 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 sljit_si sljit_is_fpu_available(void) +{ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#else + /* Available by default. */ + return 1; +#endif +} + +#define FPU_LOAD (1 << 20) + +static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + sljit_sw tmp; + sljit_uw imm; + sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads and stores. */ + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG2) | RN4(arg & REG_MASK) | RM4(OFFS_REG(arg)) | ((argw & 0x3) << 6))); + arg = SLJIT_MEM | TMP_REG2; + argw = 0; + } + + if ((arg & REG_MASK) && (argw & 0x3) == 0) { + if (!(argw & ~0x3fc)) + return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | DD4(reg) | (argw >> 2)); + if (!(-argw & ~0x3fc)) + return push_inst32(compiler, inst | RN4(arg & REG_MASK) | DD4(reg) | (-argw >> 2)); + } + + /* Slow cases */ + SLJIT_ASSERT(!(arg & OFFS_REG_MASK)); + 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)); + } + } + + if (arg & REG_MASK) { + if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg)); + } + imm = get_imm(argw & ~0x3fc); + if (imm != INVALID_IMM) { + FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm)); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2)); + } + imm = get_imm(-argw & ~0x3fc); + if (imm != INVALID_IMM) { + argw = -argw; + FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm)); + return push_inst32(compiler, inst | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2)); + } + } + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + if (arg & REG_MASK) + FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, (arg & REG_MASK)))); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw) +{ + sljit_si dst_r; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + op ^= SLJIT_SINGLE_OP; + + if (GET_OPCODE(op) == SLJIT_CMPD) { + if (dst & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, dst, dstw); + dst = TMP_FREG1; + } + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src, srcw); + src = TMP_FREG2; + } + FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst) | DM4(src))); + return push_inst32(compiler, VMRS); + } + + dst_r = (dst <= REG_MASK) ? dst : TMP_FREG1; + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw); + src = dst_r; + } + + switch (GET_OPCODE(op)) { + case SLJIT_MOVD: + if (src != dst_r) + FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + break; + case SLJIT_NEGD: + FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + break; + case SLJIT_ABSD: + FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + break; + } + + if (!(dst & SLJIT_MEM)) + return SLJIT_SUCCESS; + return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src1, sljit_sw src1w, + sljit_si src2, sljit_sw src2w) +{ + sljit_si dst_r; + + CHECK_ERROR(); + check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + op ^= SLJIT_SINGLE_OP; + + dst_r = (dst <= REG_MASK) ? dst : TMP_FREG1; + if (src1 & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); + src1 = TMP_FREG1; + } + if (src2 & SLJIT_MEM) { + emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); + src2 = TMP_FREG2; + } + + switch (GET_OPCODE(op)) { + case SLJIT_ADDD: + FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_SUBD: + FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_MULD: + FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_DIVD: + FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + } + + if (!(dst & SLJIT_MEM)) + return SLJIT_SUCCESS; + return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); +} + +#undef FPU_LOAD + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + 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) + return SLJIT_SUCCESS; + + if (dst <= REG_MASK) + return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3)); + + /* Memory. */ + if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw)) + return compiler->error; + /* TMP_REG3 is used for caching. */ + 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); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src <= REG_MASK) + 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(sljit_si 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_UNORDERED: + return 0x6; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_FLOAT_ORDERED: + 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, sljit_si type) +{ + struct sljit_jump *jump; + sljit_ins 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_COND; + 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 sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw 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)) { + if (FAST_IS_REG(src)) + 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)); + } + + 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; + return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, + sljit_si dst, sljit_sw dstw, + sljit_si src, sljit_sw srcw, + sljit_si type) +{ + sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_ins cc, ins; + + CHECK_ERROR(); + check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + cc = get_cc(type); + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + + if (op < SLJIT_ADD) { + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); + if (reg_map[dst_r] > 7) { + FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 1)); + FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 0)); + } else { + FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 1)); + FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0)); + } + if (dst_r != TMP_REG2) + return SLJIT_SUCCESS; + return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw); + } + + ins = (op == SLJIT_AND ? ANDI : (op == SLJIT_OR ? ORRI : EORI)); + if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) { + /* Does not change the other bits. */ + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst) | 1)); + if (flags & SLJIT_SET_E) { + /* The condition must always be set, even if the ORRI/EORI is not executed above. */ + if (reg_map[dst] <= 7) + return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst)); + } + return SLJIT_SUCCESS; + } + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw)); + src = TMP_REG2; + srcw = 0; + } else if (src & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG2, srcw)); + src = TMP_REG2; + srcw = 0; + } + + if (op == SLJIT_AND || src != dst_r) { + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 0)); + } + else { + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1)); + } + + if (dst_r == TMP_REG2) + FAIL_IF(emit_op_mem2(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0)); + + if (flags & SLJIT_SET_E) { + /* The condition must always be set, even if the ORR/EORI is not executed above. */ + if (reg_map[dst_r] <= 7) + return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst_r)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r)); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si 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 = SLOW_IS_REG(dst) ? 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) +{ + sljit_uh *inst = (sljit_uh*)addr; + modify_imm32_const(inst, new_addr); + SLJIT_CACHE_FLUSH(inst, inst + 4); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_uh *inst = (sljit_uh*)addr; + modify_imm32_const(inst, new_constant); + SLJIT_CACHE_FLUSH(inst, inst + 4); +} diff --git a/tools/pcre/sljit/sljitNativeMIPS_32.c b/tools/pcre/sljit/sljitNativeMIPS_32.c index f8c21486..cb7c6951 100644 --- a/tools/pcre/sljit/sljitNativeMIPS_32.c +++ b/tools/pcre/sljit/sljitNativeMIPS_32.c @@ -52,7 +52,7 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \ } -#define EMIT_SHIFT(op_imm, op_norm) \ +#define EMIT_SHIFT(op_imm, op_v) \ 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)); \ @@ -61,16 +61,14 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, } \ else { \ if (op & SLJIT_SET_E) \ - FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ + FAIL_IF(push_inst(compiler, op_v | 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))); \ + FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst))); \ } static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_si src1, sljit_sw src2) { - sljit_si overflow_ra = 0; - switch (GET_OPCODE(op)) { case SLJIT_MOV: case SLJIT_MOV_UI: @@ -138,30 +136,31 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj 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))); + FAIL_IF(push_inst(compiler, ADDU | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); /* Check zero. */ FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, ADDIU_W | SA(0) | T(dst) | IMM(-1), DR(dst))); + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(dst) | IMM(-1), DR(dst))); /* Loop for searching the highest bit. */ - FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), DR(dst))); + FAIL_IF(push_inst(compiler, ADDIU | S(dst) | T(dst) | IMM(1), DR(dst))); FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); if (op & SLJIT_SET_E) - return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); + return push_inst(compiler, ADDU | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); #endif return SLJIT_SUCCESS; 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 (src2 >= 0) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1)); + else + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), 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 (op & (SLJIT_SET_C | SLJIT_SET_O)) { if (src2 >= 0) FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); else { @@ -172,45 +171,28 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj /* 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) { + 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) + if (op & (SLJIT_SET_C | SLJIT_SET_O)) 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) + if (op & (SLJIT_SET_C | SLJIT_SET_O)) 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; + if (!(op & SLJIT_SET_O)) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + return push_inst(compiler, SLL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); case SLJIT_ADDC: if (flags & SRC2_IMM) { @@ -236,14 +218,13 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj 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 ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */ + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); /* Set carry flag. */ - return push_inst(compiler, OR | SA(TMP_EREG2) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG); + return push_inst(compiler, OR | SA(ULESS_FLAG) | 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)) { + if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || 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; @@ -251,40 +232,25 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj 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 (src2 >= 0) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1)); + else + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), 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 (op & (SLJIT_SET_C | SLJIT_SET_O)) 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) { + 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)) + if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O)) 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)); @@ -293,16 +259,16 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj 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)) + if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | 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; + if (!(op & SLJIT_SET_O)) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + return push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); case SLJIT_SUBC: if ((flags & SRC2_IMM) && src2 == SIMM_MIN) { @@ -313,7 +279,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj if (flags & SRC2_IMM) { if (op & SLJIT_SET_C) - FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(-src2), TMP_EREG1)); + 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))); } @@ -325,14 +291,10 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj } 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, SLTU | S(dst) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2)); 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; + return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS; case SLJIT_MUL: SLJIT_ASSERT(!(flags & SRC2_IMM)); diff --git a/tools/pcre/sljit/sljitNativeMIPS_64.c b/tools/pcre/sljit/sljitNativeMIPS_64.c new file mode 100644 index 00000000..df22ebaf --- /dev/null +++ b/tools/pcre/sljit/sljitNativeMIPS_64.c @@ -0,0 +1,469 @@ +/* + * 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 64-bit arch dependent functions. */ + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +{ + sljit_si shift = 32; + sljit_si shift2; + sljit_si inv = 0; + sljit_ins ins; + sljit_uw uimm; + + 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); + + if (imm <= 0x7fffffffl && imm >= -0x80000000l) { + 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; + } + + /* Zero extended number. */ + uimm = imm; + if (imm < 0) { + uimm = ~imm; + inv = 1; + } + + while (!(uimm & 0xff00000000000000l)) { + shift -= 8; + uimm <<= 8; + } + + if (!(uimm & 0xf000000000000000l)) { + shift -= 4; + uimm <<= 4; + } + + if (!(uimm & 0xc000000000000000l)) { + shift -= 2; + uimm <<= 2; + } + + if ((sljit_sw)uimm < 0) { + uimm >>= 1; + shift += 1; + } + SLJIT_ASSERT(((uimm & 0xc000000000000000l) == 0x4000000000000000l) && (shift > 0) && (shift <= 32)); + + if (inv) + uimm = ~uimm; + + FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(uimm >> 48), dst_ar)); + if (uimm & 0x0000ffff00000000l) + FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 32), dst_ar)); + + imm &= (1l << shift) - 1; + if (!(imm & ~0xffff)) { + ins = (shift == 32) ? DSLL32 : DSLL; + if (shift < 32) + ins |= SH_IMM(shift); + FAIL_IF(push_inst(compiler, ins | TA(dst_ar) | DA(dst_ar), dst_ar)); + return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar); + } + + /* Double shifts needs to be performed. */ + uimm <<= 32; + shift2 = shift - 16; + + while (!(uimm & 0xf000000000000000l)) { + shift2 -= 4; + uimm <<= 4; + } + + if (!(uimm & 0xc000000000000000l)) { + shift2 -= 2; + uimm <<= 2; + } + + if (!(uimm & 0x8000000000000000l)) { + shift2--; + uimm <<= 1; + } + + SLJIT_ASSERT((uimm & 0x8000000000000000l) && (shift2 > 0) && (shift2 <= 16)); + + FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift - shift2), dst_ar)); + FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 48), dst_ar)); + FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift2), dst_ar)); + + imm &= (1l << shift2) - 1; + return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar); +} + +#define SELECT_OP(a, b) \ + (!(op & SLJIT_INT_OP) ? a : b) + +#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_dimm, op_dimm32, op_imm, op_dv, op_v) \ + if (flags & SRC2_IMM) { \ + if (src2 >= 32) { \ + SLJIT_ASSERT(!(op & SLJIT_INT_OP)); \ + ins = op_dimm32; \ + src2 -= 32; \ + } \ + else \ + ins = (op & SLJIT_INT_OP) ? op_imm : op_dimm; \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ + } \ + else { \ + ins = (op & SLJIT_INT_OP) ? op_v : op_dv; \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \ + } + +static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, + sljit_si dst, sljit_si src1, sljit_sw src2) +{ + sljit_ins ins; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (dst != src2) + return push_inst(compiler, SELECT_OP(DADDU, 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 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) { + FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst))); + return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst)); + } + 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 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) { + FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst))); + return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst)); + } + 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_MOV_UI: + SLJIT_ASSERT(!(op & SLJIT_INT_OP)); + FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst))); + return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)); + + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst)); + + 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, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst))); +#else + if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { + FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, 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, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); + /* Check zero. */ + FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_INT_OP) ? 32 : 64), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst))); + /* Loop for searching the highest bit. */ + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst))); + FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); + if (op & SLJIT_SET_E) + return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); +#endif + return SLJIT_SUCCESS; + + case SLJIT_ADD: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1)); + else + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1)); + } + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); + if (op & (SLJIT_SET_C | SLJIT_SET_O)) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); + else { + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, 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, SELECT_OP(DADDIU, 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)); + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (op & (SLJIT_SET_C | SLJIT_SET_O)) + 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, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst))); + } + + /* a + b >= a | b (otherwise, the carry should be set to 1). */ + if (op & (SLJIT_SET_C | SLJIT_SET_O)) + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); + if (!(op & SLJIT_SET_O)) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + return push_inst(compiler, SELECT_OP(DSRL32, SLL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); + + 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, SELECT_OP(DADDIU, 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, SELECT_OP(DADDIU, 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, SELECT_OP(DADDU, 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, SELECT_OP(DADDU, ADDU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); + if (!(op & SLJIT_SET_C)) + return SLJIT_SUCCESS; + + /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */ + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); + /* Set carry flag. */ + return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG); + + case SLJIT_SUB: + if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || 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) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1)); + else + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1)); + } + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG)); + if (op & (SLJIT_SET_C | SLJIT_SET_O)) + 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, SELECT_OP(DADDIU, 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)); + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O)) + 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_U | SLJIT_SET_S | SLJIT_SET_C)) + FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst))); + } + + if (!(op & SLJIT_SET_O)) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); + + 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, SELECT_OP(DADDIU, 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, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst))); + } + + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2)); + + FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); + return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(ULESS_FLAG), ULESS_FLAG) : 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) + if (op & SLJIT_INT_OP) + return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); + FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS)); + return push_inst(compiler, MFLO | D(dst), DR(dst)); +#else + FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); + return push_inst(compiler, MFLO | D(dst), DR(dst)); +#endif + } + FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, 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, SELECT_OP(DSRA32, SRA) | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2)); + return push_inst(compiler, SELECT_OP(DSUBU, 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(DSLL, DSLL32, SLL, DSLLV, SLLV); + return SLJIT_SUCCESS; + + case SLJIT_LSHR: + EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV); + return SLJIT_SUCCESS; + + case SLJIT_ASHR: + EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV); + return SLJIT_SUCCESS; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +{ + FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst))); + FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst))); + FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); + FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 16), DR(dst))); + FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); + return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); +} + +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[5] = (inst[5] & 0xffff0000) | (new_addr & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 6); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw 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[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 6); +} diff --git a/tools/pcre/sljit/sljitNativeMIPS_common.c b/tools/pcre/sljit/sljitNativeMIPS_common.c index 9559ec32..011d8874 100644 --- a/tools/pcre/sljit/sljitNativeMIPS_common.c +++ b/tools/pcre/sljit/sljitNativeMIPS_common.c @@ -30,7 +30,7 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) { #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) - return "MIPS" SLJIT_CPUINFO; + return "MIPS V" SLJIT_CPUINFO; #else return "MIPS III" SLJIT_CPUINFO; #endif @@ -47,7 +47,7 @@ typedef sljit_ui sljit_ins; /* 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. */ +/* TMP_EREGs are used mainly for arithmetic operations. */ #define TMP_EREG1 15 #define TMP_EREG2 24 /* Floating point status register. */ @@ -86,7 +86,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { #define FS(s) ((s) << 11) #define FD(d) ((d) << 6) #define IMM(imm) ((imm) & 0xffff) -#define SH_IMM(imm) ((imm & 0x1f) << 6) +#define SH_IMM(imm) ((imm) << 6) #define DR(dr) (reg_map[dr]) #define HI(opcode) ((opcode) << 26) @@ -96,8 +96,8 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { #define ABS_fmt (HI(17) | FMT_SD | LO(5)) #define ADD_fmt (HI(17) | FMT_SD | LO(0)) -#define ADDU (HI(0) | LO(33)) #define ADDIU (HI(9)) +#define ADDU (HI(0) | LO(33)) #define AND (HI(0) | LO(36)) #define ANDI (HI(12)) #define B (HI(4)) @@ -116,9 +116,25 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { #define C_UEQ_fmt (HI(17) | FMT_SD | LO(51)) #define C_ULE_fmt (HI(17) | FMT_SD | LO(55)) #define C_ULT_fmt (HI(17) | FMT_SD | LO(53)) +#define DADDIU (HI(25)) +#define DADDU (HI(0) | LO(45)) +#define DDIV (HI(0) | LO(30)) +#define DDIVU (HI(0) | LO(31)) #define DIV (HI(0) | LO(26)) #define DIVU (HI(0) | LO(27)) #define DIV_fmt (HI(17) | FMT_SD | LO(3)) +#define DMULT (HI(0) | LO(28)) +#define DMULTU (HI(0) | LO(29)) +#define DSLL (HI(0) | LO(56)) +#define DSLL32 (HI(0) | LO(60)) +#define DSLLV (HI(0) | LO(20)) +#define DSRA (HI(0) | LO(59)) +#define DSRA32 (HI(0) | LO(63)) +#define DSRAV (HI(0) | LO(23)) +#define DSRL (HI(0) | LO(58)) +#define DSRL32 (HI(0) | LO(62)) +#define DSRLV (HI(0) | LO(22)) +#define DSUBU (HI(0) | LO(47)) #define J (HI(2)) #define JAL (HI(3)) #define JALR (HI(0) | LO(9)) @@ -129,8 +145,6 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { #define MFHI (HI(0) | LO(16)) #define MFLO (HI(0) | LO(18)) #define MOV_fmt (HI(17) | FMT_SD | LO(6)) -#define MOVN (HI(0) | LO(11)) -#define MOVZ (HI(0) | LO(10)) #define MUL_fmt (HI(17) | FMT_SD | LO(2)) #define MULT (HI(0) | LO(24)) #define MULTU (HI(0) | LO(25)) @@ -158,6 +172,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) #define CLZ (HI(28) | LO(32)) +#define DCLZ (HI(28) | LO(36)) #define MUL (HI(28) | LO(2)) #define SEB (HI(31) | (16 << 6) | LO(32)) #define SEH (HI(31) | (24 << 6) | LO(32)) @@ -198,15 +213,20 @@ static SLJIT_INLINE sljit_ins invert_branch(sljit_si 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) +static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { sljit_sw diff; sljit_uw target_addr; sljit_ins *inst; sljit_ins saved_inst; +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL)) + return code_ptr; +#else if (jump->flags & SLJIT_REWRITABLE_JUMP) return code_ptr; +#endif if (jump->flags & JUMP_ADDR) target_addr = jump->u.target; @@ -218,6 +238,11 @@ static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins if (jump->flags & IS_COND) inst--; +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (jump->flags & IS_CALL) + goto keep_address; +#endif + /* B instructions. */ if (jump->flags & IS_MOVABLE) { diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2; @@ -237,24 +262,34 @@ static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins return inst; } } + else { + diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1)) >> 2; + if (diff <= SIMM_MAX && diff >= SIMM_MIN) { + jump->flags |= PATCH_B; - diff = ((sljit_sw)target_addr - (sljit_sw)(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; + 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; } - 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)) { + if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~0xfffffff)) { + jump->flags |= PATCH_J; + saved_inst = inst[0]; + inst[0] = inst[-1]; + inst[-1] = (saved_inst & 0xffff0000) | 3; + inst[1] = J; + inst[2] = NOP; + return inst + 2; + } + else if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) { jump->flags |= PATCH_J; inst[0] = (inst[0] & 0xffff0000) | 3; inst[1] = NOP; @@ -263,26 +298,48 @@ static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins 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)) { + else { + /* J instuctions. */ + if ((jump->flags & IS_MOVABLE) && (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; + } } - 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; +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +keep_address: + if (target_addr <= 0x7fffffff) { + jump->flags |= PATCH_ABS32; + if (jump->flags & IS_COND) { + inst[0] -= 4; + inst++; + } + inst[2] = inst[6]; + inst[3] = inst[7]; + return inst + 3; } + if (target_addr <= 0x7fffffffffffl) { + jump->flags |= PATCH_ABS48; + if (jump->flags & IS_COND) { + inst[0] -= 2; + inst++; + } + inst[4] = inst[6]; + inst[5] = inst[7]; + return inst + 5; + } +#endif return code_ptr; } @@ -340,9 +397,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) jump->addr = (sljit_uw)(code_ptr - 3); #else -#error "Implementation required" + jump->addr = (sljit_uw)(code_ptr - 7); #endif - code_ptr = optimize_jump(jump, code_ptr, code); + code_ptr = detect_jump_type(jump, code_ptr, code); jump = jump->next; } if (const_ && const_->addr == word_count) { @@ -391,14 +448,30 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); #else -#error "Implementation required" + if (jump->flags & PATCH_ABS32) { + SLJIT_ASSERT(addr <= 0x7fffffff); + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); + } + else if (jump->flags & PATCH_ABS48) { + SLJIT_ASSERT(addr <= 0x7fffffffffffl); + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[3] = (buf_ptr[3] & 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[5] = (buf_ptr[5] & 0xffff0000) | (addr & 0xffff); + } #endif } while (0); jump = jump->next; } compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = compiler->size * sizeof(sljit_ins); + compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); #ifndef __GNUC__ SLJIT_CACHE_FLUSH(code, code_ptr); #else @@ -473,7 +546,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #endif local_size += (saveds + 1 + 4) * sizeof(sljit_sw); +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) local_size = (local_size + 15) & ~0xf; +#else + local_size = (local_size + 31) & ~0x1f; +#endif compiler->local_size = local_size; if (local_size <= SIMM_MAX) { @@ -523,7 +600,11 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, #endif local_size += (saveds + 1 + 4) * sizeof(sljit_sw); +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) compiler->local_size = (local_size + 15) & ~0xf; +#else + compiler->local_size = (local_size + 31) & ~0x1f; +#endif } SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) @@ -612,11 +693,11 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, { SLJIT_ASSERT(arg & SLJIT_MEM); - if ((!(flags & WRITE_BACK) || !(arg & 0xf)) && !(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) { + if ((!(flags & WRITE_BACK) || !(arg & REG_MASK)) && !(arg & OFFS_REG_MASK) && 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) + FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK) | TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS)); return -1; } @@ -631,10 +712,10 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); /* Simple operation except for updates. */ - if (arg & 0xf0) { + if (arg & OFFS_REG_MASK) { argw &= 0x3; next_argw &= 0x3; - if (argw && argw == next_argw && (arg == next_arg || (arg & 0xf0) == (next_arg & 0xf0))) + if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK))) return 1; return 0; } @@ -666,9 +747,9 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji tmp_ar = DR(TMP_REG1); delay_slot = MOVABLE_INS; } - base = arg & 0xf; + base = arg & REG_MASK; - if (SLJIT_UNLIKELY(arg & 0xf0)) { + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { argw &= 0x3; if ((flags & WRITE_BACK) && reg_ar == DR(base)) { SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); @@ -681,7 +762,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji 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), delay_slot); - if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) { + if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { if (arg == next_arg && argw == (next_argw & 0x3)) { compiler->cache_arg = arg; compiler->cache_argw = argw; @@ -693,7 +774,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji } } else { - if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) { + if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == 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), delay_slot); } @@ -701,23 +782,23 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji } if (SLJIT_UNLIKELY(argw)) { - compiler->cache_arg = SLJIT_MEM | (arg & 0xf0); + compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); compiler->cache_argw = argw; - FAIL_IF(push_inst(compiler, SLL_W | T((arg >> 4) & 0xf) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3))); + FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | 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))); + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : 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)); + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar)); return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); } - FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(base), DR(base))); + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(base), DR(base))); return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); } @@ -829,7 +910,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f if (GET_FLAGS(op)) flags |= UNUSED_DEST; } - else if (dst <= TMP_REG3) { + else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) @@ -862,7 +943,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } /* Source 1. */ - if (src1 <= TMP_REG3) { + if (FAST_IS_REG(src1)) { src1_r = src1; flags |= REG1_SOURCE; } @@ -883,7 +964,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } /* Source 2. */ - if (src2 <= TMP_REG3) { + if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) @@ -941,6 +1022,10 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) { +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + sljit_si int_op = op & SLJIT_INT_OP; +#endif + CHECK_ERROR(); check_sljit_emit_op0(compiler, op); @@ -952,7 +1037,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst(compiler, NOP, UNMOVABLE_INS); case SLJIT_UMUL: case SLJIT_SMUL: +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? DMULTU : DMULT) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); +#else FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); +#endif FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_SCRATCH_REG1), DR(SLJIT_SCRATCH_REG1))); return push_inst(compiler, MFHI | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)); case SLJIT_UDIV: @@ -961,7 +1050,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); #endif + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (int_op) + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); + else + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DDIVU : DDIV) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); +#else FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); +#endif + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_SCRATCH_REG1), DR(SLJIT_SCRATCH_REG1))); return push_inst(compiler, MFHI | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)); } @@ -975,6 +1073,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define flags 0 +#else + sljit_si flags = 0; #endif CHECK_ERROR(); @@ -982,50 +1082,74 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if ((op & SLJIT_INT_OP) && GET_OPCODE(op) >= SLJIT_NOT) { + flags |= INT_DATA | SIGNED_DATA; + if (src & SLJIT_IMM) + srcw = (sljit_si)srcw; + } +#endif + switch (GET_OPCODE(op)) { case SLJIT_MOV: case SLJIT_MOV_P: - return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_UI: - return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw); +#endif case SLJIT_MOV_SI: - return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw); +#endif case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); case SLJIT_MOVU: case SLJIT_MOVU_P: - return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_UI: - return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw); +#endif case SLJIT_MOVU_SI: - return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw); +#endif case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); case SLJIT_NOT: return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); @@ -1038,6 +1162,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler } return SLJIT_SUCCESS; + #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # undef flags #endif @@ -1050,6 +1175,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define flags 0 +#else + sljit_si flags = 0; #endif CHECK_ERROR(); @@ -1058,6 +1185,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler ADJUST_LOCAL_OFFSET(src1, src1w); ADJUST_LOCAL_OFFSET(src2, src2w); +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (op & SLJIT_INT_OP) { + flags |= INT_DATA | SIGNED_DATA; + if (src1 & SLJIT_IMM) + src1w = (sljit_si)src1w; + if (src2 & SLJIT_IMM) + src2w = (sljit_si)src2w; + } +#endif + switch (GET_OPCODE(op)) { case SLJIT_ADD: case SLJIT_ADDC: @@ -1082,12 +1219,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler if (src2 & SLJIT_IMM) src2w &= 0x1f; #else - SLJIT_ASSERT_STOP(); + if (src2 & SLJIT_IMM) { + if (op & SLJIT_INT_OP) + src2w &= 0x1f; + else + src2w &= 0x3f; + } #endif return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); } return SLJIT_SUCCESS; + #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # undef flags #endif @@ -1099,6 +1242,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) return reg_map[reg]; } +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + check_sljit_get_float_register_index(reg); + return reg << 1; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_si size) { @@ -1115,9 +1264,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) { -#if (defined SLJIT_QEMU && SLJIT_QEMU) - /* Qemu says fir is 0 by default. */ - return 1; +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; #elif defined(__GNUC__) sljit_sw fir; asm ("cfc1 %0, $0" : "=r"(fir)); @@ -1144,14 +1292,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile compiler->cache_argw = 0; if (GET_OPCODE(op) == SLJIT_CMPD) { - if (dst > SLJIT_FLOAT_REG6) { + if (dst & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw)); dst = TMP_FREG1; } else dst <<= 1; - if (src > SLJIT_FLOAT_REG6) { + if (src & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0)); src = TMP_FREG2; } @@ -1179,9 +1327,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return push_inst(compiler, C_UN_fmt | FMT(op) | FT(src) | FS(dst), FCSR_FCC); } - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : (dst << 1); + dst_fr = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; - if (src > SLJIT_FLOAT_REG6) { + if (src & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw)); src = dst_fr; } @@ -1223,9 +1371,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->cache_arg = 0; compiler->cache_argw = 0; - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG2 : (dst << 1); + dst_fr = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2; - if (src1 > SLJIT_FLOAT_REG6) { + if (src1 & SLJIT_MEM) { if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { FAIL_IF(compiler->error); src1 = TMP_FREG1; @@ -1235,7 +1383,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile else src1 <<= 1; - if (src2 > SLJIT_FLOAT_REG6) { + if (src2 & SLJIT_MEM) { if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { FAIL_IF(compiler->error); src2 = TMP_FREG2; @@ -1303,7 +1451,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; - if (dst <= TMP_REG3) + if (FAST_IS_REG(dst)) return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); /* Memory. */ @@ -1316,7 +1464,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= TMP_REG3) + if (FAST_IS_REG(src)) 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)); @@ -1351,7 +1499,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define JUMP_LENGTH 4 #else -#error "Implementation required" +#define JUMP_LENGTH 8 #endif #define BR_Z(src) \ @@ -1461,7 +1609,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile } 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); + jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? IS_CALL : 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. */ @@ -1625,14 +1773,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile compiler->cache_arg = 0; compiler->cache_argw = 0; - if (src1 > SLJIT_FLOAT_REG6) { + if (src1 & SLJIT_MEM) { PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); src1 = TMP_FREG1; } else src1 <<= 1; - if (src2 > SLJIT_FLOAT_REG6) { + if (src2 & SLJIT_MEM) { PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); src2 = TMP_FREG2; } @@ -1708,7 +1856,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= TMP_REG3) { + if (FAST_IS_REG(src)) { if (DR(src) != 4) src_r = src; else @@ -1764,6 +1912,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com { sljit_si sugg_dst_ar, dst_ar; sljit_si flags = GET_ALL_FLAGS(op); +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# define mem_type WORD_DATA +#else + sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; +#endif CHECK_ERROR(); check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); @@ -1773,13 +1926,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; op = GET_OPCODE(op); - sugg_dst_ar = DR((op < SLJIT_ADD && dst <= TMP_REG3) ? dst : TMP_REG2); +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI) + mem_type = INT_DATA | SIGNED_DATA; +#endif + sugg_dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2); compiler->cache_arg = 0; compiler->cache_argw = 0; if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { ADJUST_LOCAL_OFFSET(src, srcw); - FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw)); + FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw)); src = TMP_REG1; srcw = 0; } @@ -1847,15 +2004,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (op >= SLJIT_ADD) { 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 | flags, CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); + return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); } if (dst & SLJIT_MEM) - return emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw); + return emit_op_mem(compiler, mem_type, 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; + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +# undef mem_type +#endif } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) @@ -1871,7 +2032,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = (dst <= TMP_REG3) ? dst : TMP_REG2; + reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; PTR_FAIL_IF(emit_const(compiler, reg, init_value)); diff --git a/tools/pcre/sljit/sljitNativePPC_32.c b/tools/pcre/sljit/sljitNativePPC_32.c index 0bd35a6e..b14b75ce 100644 --- a/tools/pcre/sljit/sljitNativePPC_32.c +++ b/tools/pcre/sljit/sljitNativePPC_32.c @@ -32,7 +32,7 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl 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)); + return push_inst(compiler, ORI | S(TMP_ZERO) | 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; diff --git a/tools/pcre/sljit/sljitNativePPC_64.c b/tools/pcre/sljit/sljitNativePPC_64.c index 8eaeb41f..182ac7b3 100644 --- a/tools/pcre/sljit/sljitNativePPC_64.c +++ b/tools/pcre/sljit/sljitNativePPC_64.c @@ -52,9 +52,9 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl 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)); + return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm)); - if (imm <= SLJIT_W(0x7fffffff) && imm >= SLJIT_W(-0x80000000)) { + if (imm <= 0x7fffffffl && imm >= -0x80000000l) { 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; } diff --git a/tools/pcre/sljit/sljitNativePPC_common.c b/tools/pcre/sljit/sljitNativePPC_common.c index f7c75a79..5e06f2fd 100644 --- a/tools/pcre/sljit/sljitNativePPC_common.c +++ b/tools/pcre/sljit/sljitNativePPC_common.c @@ -33,10 +33,19 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) Both for ppc-32 and ppc-64. */ typedef sljit_ui sljit_ins; +#if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \ + || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_PPC_STACK_FRAME_V2 1 +#endif + #ifdef _AIX #include #endif +#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1 +#endif + static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) { #ifdef _AIX @@ -81,13 +90,19 @@ static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) #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_ZERO (SLJIT_NO_REGISTERS + 4) + +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) +#define TMP_CALL_REG (SLJIT_NO_REGISTERS + 5) +#else +#define TMP_CALL_REG TMP_REG2 +#endif #define TMP_FREG1 (0) #define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { - 0, 3, 4, 5, 6, 7, 30, 29, 28, 27, 26, 1, 8, 9, 10, 31 +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, 12 }; /* --------------------------------------------------------------------- */ @@ -224,13 +239,19 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { sljit_sw diff; sljit_uw target_addr; + sljit_sw extra_jump_flags; +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL)) + return 0; +#else if (jump->flags & SLJIT_REWRITABLE_JUMP) return 0; +#endif if (jump->flags & JUMP_ADDR) target_addr = jump->u.target; @@ -238,28 +259,52 @@ static SLJIT_INLINE sljit_si optimize_jump(struct sljit_jump *jump, sljit_ins *c SLJIT_ASSERT(jump->flags & JUMP_LABEL); target_addr = (sljit_uw)(code + jump->u.label->size); } + +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (jump->flags & IS_CALL) + goto keep_address; +#endif + diff = ((sljit_sw)target_addr - (sljit_sw)(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 { + extra_jump_flags = 0; + if (jump->flags & IS_COND) { if (diff <= 0x7fff && diff >= -0x8000) { jump->flags |= PATCH_B; return 1; } if (target_addr <= 0xffff) { - jump->flags |= PATCH_B | ABSOLUTE_B; + jump->flags |= PATCH_B | PATCH_ABS_B; return 1; } + extra_jump_flags = REMOVE_COND; + + diff -= sizeof(sljit_ins); } + + if (diff <= 0x01ffffff && diff >= -0x02000000) { + jump->flags |= PATCH_B | extra_jump_flags; + return 1; + } + if (target_addr <= 0x03ffffff) { + jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags; + return 1; + } + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) +keep_address: +#endif + if (target_addr <= 0x7fffffff) { + jump->flags |= PATCH_ABS32; + return 1; + } + if (target_addr <= 0x7fffffffffffl) { + jump->flags |= PATCH_ABS48; + return 1; + } +#endif + return 0; } @@ -318,19 +363,42 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #else jump->addr = (sljit_uw)(code_ptr - 6); #endif - if (optimize_jump(jump, code_ptr, code)) { + if (detect_jump_type(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; + if (jump->flags & PATCH_ABS32) { + code_ptr -= 3; + code_ptr[-1] = code_ptr[2]; + code_ptr[0] = code_ptr[3]; + } + else if (jump->flags & PATCH_ABS48) { + code_ptr--; + code_ptr[-1] = code_ptr[0]; + code_ptr[0] = code_ptr[1]; + /* rldicr rX,rX,32,31 -> rX,rX,16,47 */ + SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6); + code_ptr[-3] ^= 0x8422; + /* oris -> ori */ + code_ptr[-2] ^= 0x4000000; + } + else { + code_ptr[-6] = code_ptr[0]; + code_ptr -= 6; + } #endif + if (jump->flags & REMOVE_COND) { + code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001); + code_ptr++; + jump->addr += sizeof(sljit_ins); + code_ptr[0] = Bx; + jump->flags -= IS_COND; + } } jump = jump->next; } if (const_ && const_->addr == word_count) { - /* Just recording the address. */ const_->addr = (sljit_uw)code_ptr; const_ = const_->next; } @@ -362,8 +430,19 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil 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)) { + if (jump->flags & IS_COND) { + if (!(jump->flags & PATCH_ABS_B)) { + addr = addr - jump->addr; + SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000); + *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001); + } + else { + SLJIT_ASSERT(addr <= 0xffff); + *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001); + } + } + else { + if (!(jump->flags & PATCH_ABS_B)) { addr = addr - jump->addr; SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000); *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1); @@ -373,19 +452,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1); } } - else { - if (!(jump->flags & ABSOLUTE_B)) { - addr = addr - jump->addr; - SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)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. */ @@ -393,6 +459,19 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); #else + if (jump->flags & PATCH_ABS32) { + SLJIT_ASSERT(addr <= 0x7fffffff); + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); + break; + } + if (jump->flags & PATCH_ABS48) { + SLJIT_ASSERT(addr <= 0x7fffffffffff); + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff); + break; + } 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); @@ -402,9 +481,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = jump->next; } - SLJIT_CACHE_FLUSH(code, code_ptr); compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = compiler->size * sizeof(sljit_ins); + compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); + SLJIT_CACHE_FLUSH(code, code_ptr); #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -498,7 +577,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #endif FAIL_IF(push_inst(compiler, MFLR | D(0))); - FAIL_IF(push_inst(compiler, STACK_STORE | S(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) )); if (saveds >= 1) FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (sljit_si)(sizeof(sljit_sw))) )); if (saveds >= 2) @@ -509,9 +588,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (sljit_si)(sizeof(sljit_sw))) )); if (saveds >= 5) FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (sljit_si)(sizeof(sljit_sw))) )); +#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) + FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_LOCALS_REG) | IMM(2 * sizeof(sljit_sw)) )); +#else FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_sw)) )); +#endif - FAIL_IF(push_inst(compiler, ADDI | D(ZERO_REG) | A(0) | 0)); + FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0)); if (args >= 1) FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_SCRATCH_REG1))); if (args >= 2) @@ -519,7 +602,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil if (args >= 3) FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_SCRATCH_REG3))); -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size; #else compiler->local_size = (1 + saveds + 2) * sizeof(sljit_sw) + local_size; @@ -556,7 +639,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, compiler->logical_local_size = local_size; #endif -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size; #else compiler->local_size = (1 + saveds + 2) * sizeof(sljit_sw) + local_size; @@ -578,7 +661,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi FAIL_IF(push_inst(compiler, ADD | D(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0))); } +#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_LOCALS_REG) | IMM(2 * sizeof(sljit_sw)))); +#else FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_sw)))); +#endif if (compiler->saveds >= 5) FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (sljit_si)(sizeof(sljit_sw))) )); if (compiler->saveds >= 4) @@ -589,7 +676,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (sljit_si)(sizeof(sljit_sw))) )); if (compiler->saveds >= 1) FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (sljit_si)(sizeof(sljit_sw))) )); - FAIL_IF(push_inst(compiler, STACK_LOAD | D(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) )); FAIL_IF(push_inst(compiler, MTLR | S(0))); FAIL_IF(push_inst(compiler, BLR)); @@ -612,7 +699,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi It contans 32 items, but not all are different. */ /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */ -#define ADDR_MODE2 0x10000 +#define INT_ALIGNED 0x10000 /* 64-bit only: there is no lwau instruction. */ #define UPDATE_REQ 0x20000 @@ -623,7 +710,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #else #define ARCH_32_64(a, b) b #define INST_CODE_AND_DST(inst, flags, reg) \ - (((inst) & ~(ADDR_MODE2 | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) + (((inst) & ~(INT_ALIGNED | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) #endif static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { @@ -632,13 +719,13 @@ static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { /* Word. */ -/* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), -/* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), +/* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */), +/* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */), /* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), /* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), -/* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), -/* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), +/* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */), +/* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */), /* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), /* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), @@ -682,13 +769,13 @@ static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { /* Word. */ -/* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), -/* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), +/* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */), +/* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */), /* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), /* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), -/* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), -/* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), +/* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */), +/* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */), /* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), /* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), @@ -719,12 +806,12 @@ static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { /* Int. */ /* s i n i s */ HI(36) /* stw */, -/* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x2 /* lwa */), +/* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */), /* s i n x s */ HI(31) | LO(151) /* stwx */, /* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */), /* s i w i s */ HI(37) /* stwu */, -/* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | UPDATE_REQ | 0x2 /* lwa */), +/* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | UPDATE_REQ | 0x2 /* lwa */), /* s i w x s */ HI(31) | LO(183) /* stwux */, /* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */), @@ -748,74 +835,48 @@ static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) { sljit_ins inst; -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - sljit_si tmp_reg; -#endif + /* Should work when (arg & REG_MASK) == 0. */ + SLJIT_COMPILE_ASSERT(A(0) == 0, a0_must_be_0); 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, reg) | IMM(argw)); - return -1; - } -#endif - return 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | IMM(argw)); - return -1; - } -#endif - } - else if (!(argw & 0x3)) { + if (arg & OFFS_REG_MASK) { + if (argw & 0x3) + return 0; 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, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B((arg >> 4) & 0xf)); + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); + FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(OFFS_REG(arg)))); return -1; } - return 0; + + if (SLJIT_UNLIKELY(!(arg & REG_MASK))) + inp_flags &= ~WRITE_BACK; + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + inst = data_transfer_insts[inp_flags & MEM_MASK]; + SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ)); + + if (argw > SIMM_MAX || argw < SIMM_MIN || ((inst & INT_ALIGNED) && (argw & 0x3)) || (inst & UPDATE_REQ)) + return 0; + if (inp_flags & ARG_TEST) + return 1; +#endif + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + if (argw > SIMM_MAX || argw < SIMM_MIN) + return 0; + if (inp_flags & ARG_TEST) + return 1; + + inst = data_transfer_insts[inp_flags & MEM_MASK]; + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); +#endif + + FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | IMM(argw))); + return -1; } /* See getput_arg below. @@ -823,35 +884,50 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl uses word arguments without write back. */ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) { + sljit_sw high_short, next_high_short; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_sw diff; +#endif + SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); - if (!(arg & 0xf)) - return (next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX); + if (arg & OFFS_REG_MASK) + return ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && (argw & 0x3) == (next_argw & 0x3)); - if (arg & 0xf0) - return ((arg & 0xf0) == (next_arg & 0xf0) && (argw & 0x3) == (next_argw & 0x3)); + if (next_arg & OFFS_REG_MASK) + return 0; - if (argw <= SIMM_MAX && argw >= SIMM_MIN) { - if (arg == next_arg && (next_argw >= SIMM_MAX && next_argw <= SIMM_MIN)) +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff; + next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; + return high_short == next_high_short; +#else + if (argw <= 0x7fffffffl && argw >= -0x80000000l) { + high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff; + next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; + if (high_short == next_high_short) return 1; } - if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) + diff = argw - next_argw; + if (!(arg & REG_MASK)) + return diff <= SIMM_MAX && diff >= SIMM_MIN; + + if (arg == next_arg && diff <= SIMM_MAX && diff >= SIMM_MIN) return 1; return 0; +#endif } #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define ADJUST_CACHED_IMM(imm) \ - if ((inst & ADDR_MODE2) && (imm & 0x3)) { \ + if ((inst & INT_ALIGNED) && (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. */ @@ -859,24 +935,99 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, { sljit_si tmp_r; sljit_ins inst; + sljit_sw high_short, next_high_short; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_sw diff; +#endif SLJIT_ASSERT(arg & SLJIT_MEM); tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1; /* Special case for "mov reg, [reg, ... ]". */ - if ((arg & 0xf) == tmp_r) + if ((arg & REG_MASK) == tmp_r) tmp_r = TMP_REG1; - 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, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(argw)); + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + argw &= 0x3; + /* Otherwise getput_arg_fast would capture it. */ + SLJIT_ASSERT(argw); + + if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg && argw == compiler->cache_argw) + tmp_r = TMP_REG3; + else { + if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) { + compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1))); +#else + FAIL_IF(push_inst(compiler, RLDI(tmp_r, OFFS_REG(arg), argw, 63 - argw, 1))); +#endif + } + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r)); + } + + if (SLJIT_UNLIKELY(!(arg & REG_MASK))) + inp_flags &= ~WRITE_BACK; + + inst = data_transfer_insts[inp_flags & MEM_MASK]; + SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ)); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (argw <= 0x7fff7fffl && argw >= -0x80000000l + && (!(inst & INT_ALIGNED) || !(argw & 0x3)) && !(inst & UPDATE_REQ)) { +#endif + + arg &= REG_MASK; + high_short = (sljit_si)(argw + ((argw & 0x8000) << 1)) & ~0xffff; + /* The getput_arg_fast should handle this otherwise. */ +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l); +#else + SLJIT_ASSERT(high_short && !(inst & (INT_ALIGNED | UPDATE_REQ))); +#endif + + if (inp_flags & WRITE_BACK) { + if (arg == reg) { + FAIL_IF(push_inst(compiler, OR | S(reg) | A(tmp_r) | B(reg))); + reg = tmp_r; + } + tmp_r = arg; + FAIL_IF(push_inst(compiler, ADDIS | D(arg) | A(arg) | IMM(high_short >> 16))); + } + else if (compiler->cache_arg != arg || high_short != compiler->cache_argw) { + if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) { + next_high_short = (sljit_si)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; + if (high_short == next_high_short) { + compiler->cache_arg = SLJIT_IMM | arg; + compiler->cache_argw = next_high_short; + tmp_r = TMP_REG3; + } + } + FAIL_IF(push_inst(compiler, ADDIS | D(tmp_r) | A(arg & REG_MASK) | IMM(high_short >> 16))); + } + else + tmp_r = TMP_REG3; + + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r) | IMM(argw)); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + } + + /* Everything else is PPC-64 only. */ + if (SLJIT_UNLIKELY(!(arg & REG_MASK))) { + diff = argw - compiler->cache_argw; + if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { + ADJUST_CACHED_IMM(diff); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff)); } - if ((next_arg & SLJIT_MEM) && (argw - next_argw <= SIMM_MAX || next_argw - argw <= SIMM_MAX)) { + diff = argw - next_argw; + if ((next_arg & SLJIT_MEM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { SLJIT_ASSERT(inp_flags & LOAD_DATA); compiler->cache_arg = SLJIT_IMM; @@ -888,43 +1039,21 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r)); } - if (SLJIT_UNLIKELY(arg & 0xf0)) { - argw &= 0x3; - /* Otherwise getput_arg_fast would capture it. */ - SLJIT_ASSERT(argw); + diff = argw - compiler->cache_argw; + if (compiler->cache_arg == arg && diff <= SIMM_MAX && diff >= SIMM_MIN) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK) && !(inst & UPDATE_REQ)); + ADJUST_CACHED_IMM(diff); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff)); + } - if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg && argw == compiler->cache_argw) - tmp_r = TMP_REG3; - else { - if ((arg & 0xf0) == (next_arg & 0xf0) && argw == (next_argw & 0x3)) { - compiler->cache_arg = SLJIT_MEM | (arg & 0xf0); - compiler->cache_argw = argw; - tmp_r = TMP_REG3; - } -#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 + if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); + if (compiler->cache_argw != argw) { + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | IMM(diff))); + compiler->cache_argw = argw; } - inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; - SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, 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, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(TMP_REG3)); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3)); } if (argw == next_argw && (next_arg & SLJIT_MEM)) { @@ -935,14 +1064,15 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, compiler->cache_argw = argw; inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; - SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(TMP_REG3)); + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | 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)) { + diff = argw - next_argw; + if (arg == next_arg && !(inp_flags & WRITE_BACK) && diff <= SIMM_MAX && diff >= SIMM_MIN) { 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))); + FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & REG_MASK))); compiler->cache_arg = arg; compiler->cache_argw = argw; @@ -950,11 +1080,22 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3)); } + if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK) && diff <= SIMM_MAX && diff >= SIMM_MIN) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } + else + FAIL_IF(load_immediate(compiler, tmp_r, argw)); + /* 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, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(tmp_r)); + SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); + return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r)); +#endif } static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) @@ -990,7 +1131,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i return SLJIT_SUCCESS; dst_r = TMP_REG2; } - else if (dst <= ZERO_REG) { + else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) @@ -1009,7 +1150,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i } /* Source 1. */ - if (src1 <= ZERO_REG) { + if (FAST_IS_REG(src1)) { src1_r = src1; flags |= REG1_SOURCE; } @@ -1025,7 +1166,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i src1_r = 0; /* Source 2. */ - if (src2 <= ZERO_REG) { + if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) @@ -1095,38 +1236,42 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) { +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_si int_op = op & SLJIT_INT_OP; +#endif + CHECK_ERROR(); check_sljit_emit_op0(compiler, op); - switch (GET_OPCODE(op)) { + op = GET_OPCODE(op); + switch (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_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG1))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); - return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)); + return push_inst(compiler, (op == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)); #else FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); - return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)); + return push_inst(compiler, (op == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)); #endif case SLJIT_UDIV: case SLJIT_SDIV: FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_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_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + if (int_op) { + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); - return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); + } else { + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); } - FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); - FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); #else - FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); #endif @@ -1152,14 +1297,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler op = GET_OPCODE(op); if ((src & SLJIT_IMM) && srcw == 0) - src = ZERO_REG; + src = TMP_ZERO; if (op_flags & SLJIT_SET_O) - FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); + FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); if (op_flags & SLJIT_INT_OP) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { - if (src <= ZERO_REG && src == dst) { + if (op < SLJIT_NOT) { + if (FAST_IS_REG(src) && src == dst) { if (!TYPE_CAST_NEEDED(op)) return SLJIT_SUCCESS; } @@ -1268,7 +1413,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #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)) + (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l) #else #define TEST_SH_IMM(src, srcw) \ (((src) & SLJIT_IMM) && !((srcw) & 0xffff)) @@ -1279,7 +1424,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #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)) + (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l) #else #define TEST_ADD_IMM(src, srcw) \ ((src) & SLJIT_IMM) @@ -1307,9 +1452,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler ADJUST_LOCAL_OFFSET(src2, src2w); if ((src1 & SLJIT_IMM) && src1w == 0) - src1 = ZERO_REG; + src1 = TMP_ZERO; if ((src2 & SLJIT_IMM) && src2w == 0) - src2 = ZERO_REG; + src2 = TMP_ZERO; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) { @@ -1324,7 +1469,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler } #endif if (op & SLJIT_SET_O) - FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); + FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); if (src2 == TMP_REG2) flags |= ALT_KEEP_CACHE; @@ -1392,7 +1537,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return emit_op(compiler, SLJIT_ADD, 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 (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S)) && !(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)) { @@ -1418,7 +1563,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler } return emit_op(compiler, SLJIT_SUB, 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 (!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))) { if (TEST_SL_IMM(src2, -src2w)) { compiler->imm = (-src2w) & 0xffff; return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); @@ -1507,6 +1652,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) return reg_map[reg]; } +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + check_sljit_get_float_register_index(reg); + return reg; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_si size) { @@ -1523,8 +1674,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) { - /* Always available. */ +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#else + /* Available by default. */ return 1; +#endif } #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6)) @@ -1544,12 +1699,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile compiler->cache_argw = 0; if (GET_OPCODE(op) == SLJIT_CMPD) { - if (dst > SLJIT_FLOAT_REG6) { + if (dst & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw)); dst = TMP_FREG1; } - if (src > SLJIT_FLOAT_REG6) { + if (src & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0)); src = TMP_FREG2; } @@ -1557,9 +1712,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return push_inst(compiler, FCMPU | CRD(4) | FA(dst) | FB(src)); } - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + dst_fr = FAST_IS_REG(dst) ? dst : TMP_FREG1; - if (src > SLJIT_FLOAT_REG6) { + if (src & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw)); src = dst_fr; } @@ -1599,9 +1754,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->cache_arg = 0; compiler->cache_argw = 0; - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG2 : dst; + dst_fr = FAST_IS_REG(dst) ? dst : TMP_FREG2; - if (src1 > SLJIT_FLOAT_REG6) { + if (src1 & SLJIT_MEM) { if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { FAIL_IF(compiler->error); src1 = TMP_FREG1; @@ -1609,7 +1764,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile flags |= ALT_FORM1; } - if (src2 > SLJIT_FLOAT_REG6) { + if (src2 & SLJIT_MEM) { if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { FAIL_IF(compiler->error); src2 = TMP_FREG2; @@ -1678,7 +1833,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; - if (dst <= ZERO_REG) + if (FAST_IS_REG(dst)) return push_inst(compiler, MFLR | D(dst)); /* Memory. */ @@ -1692,7 +1847,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= ZERO_REG) + if (FAST_IS_REG(src)) FAIL_IF(push_inst(compiler, MTLR | S(src))); else { if (src & SLJIT_MEM) @@ -1805,11 +1960,15 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile type &= 0xff; /* In PPC, we don't need to touch the arguments. */ - if (type >= SLJIT_JUMP) - jump->flags |= UNCOND_B; + if (type < SLJIT_JUMP) + jump->flags |= IS_COND; +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) + if (type >= SLJIT_CALL0) + jump->flags |= IS_CALL; +#endif - PTR_FAIL_IF(emit_const(compiler, TMP_REG1, 0)); - PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_REG1))); + PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0)); + PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG))); jump->addr = compiler->size; PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0))); return jump; @@ -1824,20 +1983,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= ZERO_REG) + if (FAST_IS_REG(src)) { +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) + if (type >= SLJIT_CALL0) { + FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src))); + src_r = TMP_CALL_REG; + } + else + src_r = src; +#else src_r = src; - else if (src & SLJIT_IMM) { +#endif + } 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); + set_jump(jump, compiler, JUMP_ADDR); jump->u.target = srcw; - - FAIL_IF(emit_const(compiler, TMP_REG2, 0)); - src_r = TMP_REG2; +#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) + if (type >= SLJIT_CALL0) + jump->flags |= IS_CALL; +#endif + FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0)); + src_r = TMP_CALL_REG; } else { - FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); - src_r = TMP_REG2; + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw)); + src_r = TMP_CALL_REG; } FAIL_IF(push_inst(compiler, MTCTR | S(src_r))); @@ -1861,6 +2032,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com { sljit_si reg, input_flags; sljit_si flags = GET_ALL_FLAGS(op); + sljit_sw original_dstw = dstw; CHECK_ERROR(); check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); @@ -1870,7 +2042,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; op = GET_OPCODE(op); - reg = (op < SLJIT_ADD && dst <= ZERO_REG) ? dst : TMP_REG2; + reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2; compiler->cache_arg = 0; compiler->cache_argw = 0; @@ -1982,13 +2154,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com op = SLJIT_MOV; input_flags = WORD_DATA; #endif - return (reg == TMP_REG2) ? emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0) : SLJIT_SUCCESS; + if (reg != TMP_REG2) + return SLJIT_SUCCESS; + return emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); } #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif - return sljit_emit_op2(compiler, op | flags, dst, dstw, src, srcw, TMP_REG2, 0); + return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0); } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) @@ -2004,7 +2178,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = (dst <= ZERO_REG) ? dst : TMP_REG2; + reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; PTR_FAIL_IF(emit_const(compiler, reg, init_value)); diff --git a/tools/pcre/sljit/sljitNativeSPARC_common.c b/tools/pcre/sljit/sljitNativeSPARC_common.c index c6522be2..d6a1e12b 100644 --- a/tools/pcre/sljit/sljitNativeSPARC_common.c +++ b/tools/pcre/sljit/sljitNativeSPARC_common.c @@ -35,6 +35,30 @@ typedef sljit_ui sljit_ins; static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) { +#if defined(__SUNPRO_C) && __SUNPRO_C < 0x590 + __asm ( + /* if (from == to) return */ + "cmp %i0, %i1\n" + "be .leave\n" + "nop\n" + + /* loop until from >= to */ + ".mainloop:\n" + "flush %i0\n" + "add %i0, 8, %i0\n" + "cmp %i0, %i1\n" + "bcs .mainloop\n" + "nop\n" + + /* The comparison was done above. */ + "bne .leave\n" + /* nop is not necessary here, since the + sub operation has no side effect. */ + "sub %i0, 4, %i0\n" + "flush %i0\n" + ".leave:" + ); +#else if (SLJIT_UNLIKELY(from == to)) return; @@ -49,12 +73,13 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) if (from == to) { /* Flush the last word. */ - to --; + from --; __asm__ volatile ( "flush %0\n" - : : "r"(to) + : : "r"(from) ); } +#endif } /* TMP_REG2 is not used by getput_arg */ @@ -62,7 +87,7 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) #define TMP_REG2 (SLJIT_NO_REGISTERS + 2) #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) #define TMP_REG4 (SLJIT_NO_REGISTERS + 4) -#define LINK_REG (SLJIT_NO_REGISTERS + 5) +#define TMP_LINK (SLJIT_NO_REGISTERS + 5) #define TMP_FREG1 (0) #define TMP_FREG2 ((SLJIT_FLOAT_REG6 + 1) << 1) @@ -165,7 +190,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_ return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { sljit_sw diff; sljit_uw target_addr; @@ -286,7 +311,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #else jump->addr = (sljit_uw)(code_ptr - 6); #endif - code_ptr = optimize_jump(jump, code_ptr, code); + code_ptr = detect_jump_type(jump, code_ptr, code); jump = jump->next; } if (const_ && const_->addr == word_count) { @@ -344,7 +369,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = compiler->size * sizeof(sljit_ins); + compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); SLJIT_CACHE_FLUSH(code, code_ptr); return code; } @@ -440,7 +465,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); - if (op != SLJIT_MOV || !(src <= TMP_REG3)) { + if (op != SLJIT_MOV || !FAST_IS_REG(src)) { FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); src = SLJIT_SCRATCH_REG1; } @@ -491,15 +516,15 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, { SLJIT_ASSERT(arg & SLJIT_MEM); - if (!(flags & WRITE_BACK) || !(arg & 0xf)) { - if ((!(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) - || ((arg & 0xf0) && (argw & 0x3) == 0)) { + if (!(flags & WRITE_BACK) || !(arg & REG_MASK)) { + if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) + || ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) { /* Works for both absoulte and relative addresses (immediate case). */ if (SLJIT_UNLIKELY(flags & ARG_TEST)) return 1; FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg)) - | S1(arg & 0xf) | ((arg & 0xf0) ? S2((arg >> 4) & 0xf) : IMM(argw)), + | S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS)); return -1; } @@ -515,11 +540,11 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); /* Simple operation except for updates. */ - if (arg & 0xf0) { + if (arg & OFFS_REG_MASK) { argw &= 0x3; SLJIT_ASSERT(argw); next_argw &= 0x3; - if ((arg & 0xf0) == (next_arg & 0xf0) && argw == next_argw) + if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == next_argw) return 1; return 0; } @@ -541,25 +566,25 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji next_argw = 0; } - base = arg & 0xf; - if (SLJIT_UNLIKELY(arg & 0xf0)) { + base = arg & REG_MASK; + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { argw &= 0x3; SLJIT_ASSERT(argw != 0); /* Using the cache. */ - if (((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) && (argw == compiler->cache_argw)) + if (((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) && (argw == compiler->cache_argw)) arg2 = TMP_REG3; else { - if ((arg & 0xf0) == (next_arg & 0xf0) && argw == (next_argw & 0x3)) { - compiler->cache_arg = SLJIT_MEM | (arg & 0xf0); + if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) { + compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); compiler->cache_argw = argw; arg2 = TMP_REG3; } - else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && (reg << 4) != (arg & 0xf0)) + else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && reg != OFFS_REG(arg)) arg2 = reg; else /* It must be a mov operation, so tmp1 must be free to use. */ arg2 = TMP_REG1; - FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1((arg >> 4) & 0xf) | IMM_ARG | argw, DR(arg2))); + FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1(OFFS_REG(arg)) | IMM_ARG | argw, DR(arg2))); } } else { @@ -633,7 +658,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; } - else if (dst <= TMP_REG3) { + else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) @@ -664,7 +689,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } /* Source 1. */ - if (src1 <= TMP_REG3) + if (FAST_IS_REG(src1)) src1_r = src1; else if (src1 & SLJIT_IMM) { if (src1w) { @@ -683,7 +708,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } /* Source 2. */ - if (src2 <= TMP_REG3) { + if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) @@ -896,6 +921,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) return reg_map[reg]; } +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + check_sljit_get_float_register_index(reg); + return reg << 1; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_si size) { @@ -912,7 +943,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) { +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#else + /* Available by default. */ return 1; +#endif } #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) @@ -932,14 +968,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile compiler->cache_argw = 0; if (GET_OPCODE(op) == SLJIT_CMPD) { - if (dst > SLJIT_FLOAT_REG6) { + if (dst & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw)); dst = TMP_FREG1; } else dst <<= 1; - if (src > SLJIT_FLOAT_REG6) { + if (src & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0)); src = TMP_FREG2; } @@ -949,9 +985,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(dst) | S2A(src), FCC_IS_SET | MOVABLE_INS); } - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : (dst << 1); + dst_fr = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; - if (src > SLJIT_FLOAT_REG6) { + if (src & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw)); src = dst_fr; } @@ -1000,9 +1036,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->cache_arg = 0; compiler->cache_argw = 0; - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG2 : (dst << 1); + dst_fr = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2; - if (src1 > SLJIT_FLOAT_REG6) { + if (src1 & SLJIT_MEM) { if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { FAIL_IF(compiler->error); src1 = TMP_FREG1; @@ -1012,7 +1048,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile else src1 <<= 1; - if (src2 > SLJIT_FLOAT_REG6) { + if (src2 & SLJIT_MEM) { if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { FAIL_IF(compiler->error); src2 = TMP_FREG2; @@ -1083,11 +1119,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; - if (dst <= TMP_REG3) - return push_inst(compiler, OR | D(dst) | S1(0) | S2(LINK_REG), DR(dst)); + if (FAST_IS_REG(dst)) + return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst)); /* Memory. */ - return emit_op_mem(compiler, WORD_DATA, LINK_REG, dst, dstw); + return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw); } SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) @@ -1096,14 +1132,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= TMP_REG3) - FAIL_IF(push_inst(compiler, OR | D(LINK_REG) | S1(0) | S2(src), DR(LINK_REG))); + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK))); else if (src & SLJIT_MEM) - FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, LINK_REG, src, srcw)); + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw)); else if (src & SLJIT_IMM) - FAIL_IF(load_immediate(compiler, LINK_REG, srcw)); + FAIL_IF(load_immediate(compiler, TMP_LINK, srcw)); - FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(LINK_REG) | IMM(8), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS)); return push_inst(compiler, NOP, UNMOVABLE_INS); } @@ -1238,7 +1274,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile } PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); - PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? LINK_REG : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS)); + PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS)); jump->addr = compiler->size; PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); @@ -1254,7 +1290,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= TMP_REG3) + if (FAST_IS_REG(src)) src_r = src; else if (src & SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -1274,7 +1310,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil src_r = TMP_REG2; } - FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? LINK_REG : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS)); if (jump) jump->addr = compiler->size; return push_inst(compiler, NOP, UNMOVABLE_INS); @@ -1296,7 +1332,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) op = GET_OPCODE(op); - reg = (op < SLJIT_ADD && dst <= TMP_REG3) ? dst : TMP_REG2; + reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2; compiler->cache_arg = 0; compiler->cache_argw = 0; @@ -1337,12 +1373,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = (dst <= TMP_REG3) ? dst : TMP_REG2; + reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; PTR_FAIL_IF(emit_const(compiler, reg, init_value)); if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); - return const_; } diff --git a/tools/pcre/sljit/sljitNativeTILEGX-encoder.c b/tools/pcre/sljit/sljitNativeTILEGX-encoder.c new file mode 100644 index 00000000..71963290 --- /dev/null +++ b/tools/pcre/sljit/sljitNativeTILEGX-encoder.c @@ -0,0 +1,10159 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved. + * 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 code is owned by Tilera Corporation, and distributed as part + of multiple projects. In sljit, the code is under BSD licence. */ + +#include +#include +#include +#define BFD_RELOC(x) R_##x + +/* Special registers. */ +#define TREG_LR 55 +#define TREG_SN 56 +#define TREG_ZERO 63 + +/* Canonical name of each register. */ +const char *const tilegx_register_names[] = +{ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", + "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", + "r48", "r49", "r50", "r51", "r52", "tp", "sp", "lr", + "sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero" +}; + +enum +{ + R_NONE = 0, + R_TILEGX_NONE = 0, + R_TILEGX_64 = 1, + R_TILEGX_32 = 2, + R_TILEGX_16 = 3, + R_TILEGX_8 = 4, + R_TILEGX_64_PCREL = 5, + R_TILEGX_32_PCREL = 6, + R_TILEGX_16_PCREL = 7, + R_TILEGX_8_PCREL = 8, + R_TILEGX_HW0 = 9, + R_TILEGX_HW1 = 10, + R_TILEGX_HW2 = 11, + R_TILEGX_HW3 = 12, + R_TILEGX_HW0_LAST = 13, + R_TILEGX_HW1_LAST = 14, + R_TILEGX_HW2_LAST = 15, + R_TILEGX_COPY = 16, + R_TILEGX_GLOB_DAT = 17, + R_TILEGX_JMP_SLOT = 18, + R_TILEGX_RELATIVE = 19, + R_TILEGX_BROFF_X1 = 20, + R_TILEGX_JUMPOFF_X1 = 21, + R_TILEGX_JUMPOFF_X1_PLT = 22, + R_TILEGX_IMM8_X0 = 23, + R_TILEGX_IMM8_Y0 = 24, + R_TILEGX_IMM8_X1 = 25, + R_TILEGX_IMM8_Y1 = 26, + R_TILEGX_DEST_IMM8_X1 = 27, + R_TILEGX_MT_IMM14_X1 = 28, + R_TILEGX_MF_IMM14_X1 = 29, + R_TILEGX_MMSTART_X0 = 30, + R_TILEGX_MMEND_X0 = 31, + R_TILEGX_SHAMT_X0 = 32, + R_TILEGX_SHAMT_X1 = 33, + R_TILEGX_SHAMT_Y0 = 34, + R_TILEGX_SHAMT_Y1 = 35, + R_TILEGX_IMM16_X0_HW0 = 36, + R_TILEGX_IMM16_X1_HW0 = 37, + R_TILEGX_IMM16_X0_HW1 = 38, + R_TILEGX_IMM16_X1_HW1 = 39, + R_TILEGX_IMM16_X0_HW2 = 40, + R_TILEGX_IMM16_X1_HW2 = 41, + R_TILEGX_IMM16_X0_HW3 = 42, + R_TILEGX_IMM16_X1_HW3 = 43, + R_TILEGX_IMM16_X0_HW0_LAST = 44, + R_TILEGX_IMM16_X1_HW0_LAST = 45, + R_TILEGX_IMM16_X0_HW1_LAST = 46, + R_TILEGX_IMM16_X1_HW1_LAST = 47, + R_TILEGX_IMM16_X0_HW2_LAST = 48, + R_TILEGX_IMM16_X1_HW2_LAST = 49, + R_TILEGX_IMM16_X0_HW0_PCREL = 50, + R_TILEGX_IMM16_X1_HW0_PCREL = 51, + R_TILEGX_IMM16_X0_HW1_PCREL = 52, + R_TILEGX_IMM16_X1_HW1_PCREL = 53, + R_TILEGX_IMM16_X0_HW2_PCREL = 54, + R_TILEGX_IMM16_X1_HW2_PCREL = 55, + R_TILEGX_IMM16_X0_HW3_PCREL = 56, + R_TILEGX_IMM16_X1_HW3_PCREL = 57, + R_TILEGX_IMM16_X0_HW0_LAST_PCREL = 58, + R_TILEGX_IMM16_X1_HW0_LAST_PCREL = 59, + R_TILEGX_IMM16_X0_HW1_LAST_PCREL = 60, + R_TILEGX_IMM16_X1_HW1_LAST_PCREL = 61, + R_TILEGX_IMM16_X0_HW2_LAST_PCREL = 62, + R_TILEGX_IMM16_X1_HW2_LAST_PCREL = 63, + R_TILEGX_IMM16_X0_HW0_GOT = 64, + R_TILEGX_IMM16_X1_HW0_GOT = 65, + + R_TILEGX_IMM16_X0_HW0_PLT_PCREL = 66, + R_TILEGX_IMM16_X1_HW0_PLT_PCREL = 67, + R_TILEGX_IMM16_X0_HW1_PLT_PCREL = 68, + R_TILEGX_IMM16_X1_HW1_PLT_PCREL = 69, + R_TILEGX_IMM16_X0_HW2_PLT_PCREL = 70, + R_TILEGX_IMM16_X1_HW2_PLT_PCREL = 71, + + R_TILEGX_IMM16_X0_HW0_LAST_GOT = 72, + R_TILEGX_IMM16_X1_HW0_LAST_GOT = 73, + R_TILEGX_IMM16_X0_HW1_LAST_GOT = 74, + R_TILEGX_IMM16_X1_HW1_LAST_GOT = 75, + R_TILEGX_IMM16_X0_HW0_TLS_GD = 78, + R_TILEGX_IMM16_X1_HW0_TLS_GD = 79, + R_TILEGX_IMM16_X0_HW0_TLS_LE = 80, + R_TILEGX_IMM16_X1_HW0_TLS_LE = 81, + R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE = 82, + R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE = 83, + R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE = 84, + R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE = 85, + R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD = 86, + R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD = 87, + R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD = 88, + R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD = 89, + R_TILEGX_IMM16_X0_HW0_TLS_IE = 92, + R_TILEGX_IMM16_X1_HW0_TLS_IE = 93, + + R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL = 94, + R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL = 95, + R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL = 96, + R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL = 97, + R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL = 98, + R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL = 99, + + R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE = 100, + R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE = 101, + R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE = 102, + R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE = 103, + R_TILEGX_TLS_DTPMOD64 = 106, + R_TILEGX_TLS_DTPOFF64 = 107, + R_TILEGX_TLS_TPOFF64 = 108, + R_TILEGX_TLS_DTPMOD32 = 109, + R_TILEGX_TLS_DTPOFF32 = 110, + R_TILEGX_TLS_TPOFF32 = 111, + R_TILEGX_TLS_GD_CALL = 112, + R_TILEGX_IMM8_X0_TLS_GD_ADD = 113, + R_TILEGX_IMM8_X1_TLS_GD_ADD = 114, + R_TILEGX_IMM8_Y0_TLS_GD_ADD = 115, + R_TILEGX_IMM8_Y1_TLS_GD_ADD = 116, + R_TILEGX_TLS_IE_LOAD = 117, + R_TILEGX_IMM8_X0_TLS_ADD = 118, + R_TILEGX_IMM8_X1_TLS_ADD = 119, + R_TILEGX_IMM8_Y0_TLS_ADD = 120, + R_TILEGX_IMM8_Y1_TLS_ADD = 121, + R_TILEGX_GNU_VTINHERIT = 128, + R_TILEGX_GNU_VTENTRY = 129, + R_TILEGX_IRELATIVE = 130, + R_TILEGX_NUM = 131 +}; + +typedef enum +{ + TILEGX_PIPELINE_X0, + TILEGX_PIPELINE_X1, + TILEGX_PIPELINE_Y0, + TILEGX_PIPELINE_Y1, + TILEGX_PIPELINE_Y2, +} tilegx_pipeline; + +typedef unsigned long long tilegx_bundle_bits; + +/* These are the bits that determine if a bundle is in the X encoding. */ +#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62) + +enum +{ + /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */ + TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3, + + /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */ + TILEGX_NUM_PIPELINE_ENCODINGS = 5, + + /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */ + TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3, + + /* Instructions take this many bytes. */ + TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES, + + /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */ + TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3, + + /* Bundles should be aligned modulo this number of bytes. */ + TILEGX_BUNDLE_ALIGNMENT_IN_BYTES = + (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES), + + /* Number of registers (some are magic, such as network I/O). */ + TILEGX_NUM_REGISTERS = 64, +}; + +/* Make a few "tile_" variables to simplify common code between + architectures. */ + +typedef tilegx_bundle_bits tile_bundle_bits; +#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES +#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES +#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \ + TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES + +/* 64-bit pattern for a { bpt ; nop } bundle. */ +#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL + +typedef enum +{ + TILEGX_OP_TYPE_REGISTER, + TILEGX_OP_TYPE_IMMEDIATE, + TILEGX_OP_TYPE_ADDRESS, + TILEGX_OP_TYPE_SPR +} tilegx_operand_type; + +struct tilegx_operand +{ + /* Is this operand a register, immediate or address? */ + tilegx_operand_type type; + + /* The default relocation type for this operand. */ + signed int default_reloc : 16; + + /* How many bits is this value? (used for range checking) */ + unsigned int num_bits : 5; + + /* Is the value signed? (used for range checking) */ + unsigned int is_signed : 1; + + /* Is this operand a source register? */ + unsigned int is_src_reg : 1; + + /* Is this operand written? (i.e. is it a destination register) */ + unsigned int is_dest_reg : 1; + + /* Is this operand PC-relative? */ + unsigned int is_pc_relative : 1; + + /* By how many bits do we right shift the value before inserting? */ + unsigned int rightshift : 2; + + /* Return the bits for this operand to be ORed into an existing bundle. */ + tilegx_bundle_bits (*insert) (int op); + + /* Extract this operand and return it. */ + unsigned int (*extract) (tilegx_bundle_bits bundle); +}; + +typedef enum +{ + TILEGX_OPC_BPT, + TILEGX_OPC_INFO, + TILEGX_OPC_INFOL, + TILEGX_OPC_LD4S_TLS, + TILEGX_OPC_LD_TLS, + TILEGX_OPC_MOVE, + TILEGX_OPC_MOVEI, + TILEGX_OPC_MOVELI, + TILEGX_OPC_PREFETCH, + TILEGX_OPC_PREFETCH_ADD_L1, + TILEGX_OPC_PREFETCH_ADD_L1_FAULT, + TILEGX_OPC_PREFETCH_ADD_L2, + TILEGX_OPC_PREFETCH_ADD_L2_FAULT, + TILEGX_OPC_PREFETCH_ADD_L3, + TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + TILEGX_OPC_PREFETCH_L1, + TILEGX_OPC_PREFETCH_L1_FAULT, + TILEGX_OPC_PREFETCH_L2, + TILEGX_OPC_PREFETCH_L2_FAULT, + TILEGX_OPC_PREFETCH_L3, + TILEGX_OPC_PREFETCH_L3_FAULT, + TILEGX_OPC_RAISE, + TILEGX_OPC_ADD, + TILEGX_OPC_ADDI, + TILEGX_OPC_ADDLI, + TILEGX_OPC_ADDX, + TILEGX_OPC_ADDXI, + TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXSC, + TILEGX_OPC_AND, + TILEGX_OPC_ANDI, + TILEGX_OPC_BEQZ, + TILEGX_OPC_BEQZT, + TILEGX_OPC_BFEXTS, + TILEGX_OPC_BFEXTU, + TILEGX_OPC_BFINS, + TILEGX_OPC_BGEZ, + TILEGX_OPC_BGEZT, + TILEGX_OPC_BGTZ, + TILEGX_OPC_BGTZT, + TILEGX_OPC_BLBC, + TILEGX_OPC_BLBCT, + TILEGX_OPC_BLBS, + TILEGX_OPC_BLBST, + TILEGX_OPC_BLEZ, + TILEGX_OPC_BLEZT, + TILEGX_OPC_BLTZ, + TILEGX_OPC_BLTZT, + TILEGX_OPC_BNEZ, + TILEGX_OPC_BNEZT, + TILEGX_OPC_CLZ, + TILEGX_OPC_CMOVEQZ, + TILEGX_OPC_CMOVNEZ, + TILEGX_OPC_CMPEQ, + TILEGX_OPC_CMPEQI, + TILEGX_OPC_CMPEXCH, + TILEGX_OPC_CMPEXCH4, + TILEGX_OPC_CMPLES, + TILEGX_OPC_CMPLEU, + TILEGX_OPC_CMPLTS, + TILEGX_OPC_CMPLTSI, + TILEGX_OPC_CMPLTU, + TILEGX_OPC_CMPLTUI, + TILEGX_OPC_CMPNE, + TILEGX_OPC_CMUL, + TILEGX_OPC_CMULA, + TILEGX_OPC_CMULAF, + TILEGX_OPC_CMULF, + TILEGX_OPC_CMULFR, + TILEGX_OPC_CMULH, + TILEGX_OPC_CMULHR, + TILEGX_OPC_CRC32_32, + TILEGX_OPC_CRC32_8, + TILEGX_OPC_CTZ, + TILEGX_OPC_DBLALIGN, + TILEGX_OPC_DBLALIGN2, + TILEGX_OPC_DBLALIGN4, + TILEGX_OPC_DBLALIGN6, + TILEGX_OPC_DRAIN, + TILEGX_OPC_DTLBPR, + TILEGX_OPC_EXCH, + TILEGX_OPC_EXCH4, + TILEGX_OPC_FDOUBLE_ADD_FLAGS, + TILEGX_OPC_FDOUBLE_ADDSUB, + TILEGX_OPC_FDOUBLE_MUL_FLAGS, + TILEGX_OPC_FDOUBLE_PACK1, + TILEGX_OPC_FDOUBLE_PACK2, + TILEGX_OPC_FDOUBLE_SUB_FLAGS, + TILEGX_OPC_FDOUBLE_UNPACK_MAX, + TILEGX_OPC_FDOUBLE_UNPACK_MIN, + TILEGX_OPC_FETCHADD, + TILEGX_OPC_FETCHADD4, + TILEGX_OPC_FETCHADDGEZ, + TILEGX_OPC_FETCHADDGEZ4, + TILEGX_OPC_FETCHAND, + TILEGX_OPC_FETCHAND4, + TILEGX_OPC_FETCHOR, + TILEGX_OPC_FETCHOR4, + TILEGX_OPC_FINV, + TILEGX_OPC_FLUSH, + TILEGX_OPC_FLUSHWB, + TILEGX_OPC_FNOP, + TILEGX_OPC_FSINGLE_ADD1, + TILEGX_OPC_FSINGLE_ADDSUB2, + TILEGX_OPC_FSINGLE_MUL1, + TILEGX_OPC_FSINGLE_MUL2, + TILEGX_OPC_FSINGLE_PACK1, + TILEGX_OPC_FSINGLE_PACK2, + TILEGX_OPC_FSINGLE_SUB1, + TILEGX_OPC_ICOH, + TILEGX_OPC_ILL, + TILEGX_OPC_INV, + TILEGX_OPC_IRET, + TILEGX_OPC_J, + TILEGX_OPC_JAL, + TILEGX_OPC_JALR, + TILEGX_OPC_JALRP, + TILEGX_OPC_JR, + TILEGX_OPC_JRP, + TILEGX_OPC_LD, + TILEGX_OPC_LD1S, + TILEGX_OPC_LD1S_ADD, + TILEGX_OPC_LD1U, + TILEGX_OPC_LD1U_ADD, + TILEGX_OPC_LD2S, + TILEGX_OPC_LD2S_ADD, + TILEGX_OPC_LD2U, + TILEGX_OPC_LD2U_ADD, + TILEGX_OPC_LD4S, + TILEGX_OPC_LD4S_ADD, + TILEGX_OPC_LD4U, + TILEGX_OPC_LD4U_ADD, + TILEGX_OPC_LD_ADD, + TILEGX_OPC_LDNA, + TILEGX_OPC_LDNA_ADD, + TILEGX_OPC_LDNT, + TILEGX_OPC_LDNT1S, + TILEGX_OPC_LDNT1S_ADD, + TILEGX_OPC_LDNT1U, + TILEGX_OPC_LDNT1U_ADD, + TILEGX_OPC_LDNT2S, + TILEGX_OPC_LDNT2S_ADD, + TILEGX_OPC_LDNT2U, + TILEGX_OPC_LDNT2U_ADD, + TILEGX_OPC_LDNT4S, + TILEGX_OPC_LDNT4S_ADD, + TILEGX_OPC_LDNT4U, + TILEGX_OPC_LDNT4U_ADD, + TILEGX_OPC_LDNT_ADD, + TILEGX_OPC_LNK, + TILEGX_OPC_MF, + TILEGX_OPC_MFSPR, + TILEGX_OPC_MM, + TILEGX_OPC_MNZ, + TILEGX_OPC_MTSPR, + TILEGX_OPC_MUL_HS_HS, + TILEGX_OPC_MUL_HS_HU, + TILEGX_OPC_MUL_HS_LS, + TILEGX_OPC_MUL_HS_LU, + TILEGX_OPC_MUL_HU_HU, + TILEGX_OPC_MUL_HU_LS, + TILEGX_OPC_MUL_HU_LU, + TILEGX_OPC_MUL_LS_LS, + TILEGX_OPC_MUL_LS_LU, + TILEGX_OPC_MUL_LU_LU, + TILEGX_OPC_MULA_HS_HS, + TILEGX_OPC_MULA_HS_HU, + TILEGX_OPC_MULA_HS_LS, + TILEGX_OPC_MULA_HS_LU, + TILEGX_OPC_MULA_HU_HU, + TILEGX_OPC_MULA_HU_LS, + TILEGX_OPC_MULA_HU_LU, + TILEGX_OPC_MULA_LS_LS, + TILEGX_OPC_MULA_LS_LU, + TILEGX_OPC_MULA_LU_LU, + TILEGX_OPC_MULAX, + TILEGX_OPC_MULX, + TILEGX_OPC_MZ, + TILEGX_OPC_NAP, + TILEGX_OPC_NOP, + TILEGX_OPC_NOR, + TILEGX_OPC_OR, + TILEGX_OPC_ORI, + TILEGX_OPC_PCNT, + TILEGX_OPC_REVBITS, + TILEGX_OPC_REVBYTES, + TILEGX_OPC_ROTL, + TILEGX_OPC_ROTLI, + TILEGX_OPC_SHL, + TILEGX_OPC_SHL16INSLI, + TILEGX_OPC_SHL1ADD, + TILEGX_OPC_SHL1ADDX, + TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL2ADDX, + TILEGX_OPC_SHL3ADD, + TILEGX_OPC_SHL3ADDX, + TILEGX_OPC_SHLI, + TILEGX_OPC_SHLX, + TILEGX_OPC_SHLXI, + TILEGX_OPC_SHRS, + TILEGX_OPC_SHRSI, + TILEGX_OPC_SHRU, + TILEGX_OPC_SHRUI, + TILEGX_OPC_SHRUX, + TILEGX_OPC_SHRUXI, + TILEGX_OPC_SHUFFLEBYTES, + TILEGX_OPC_ST, + TILEGX_OPC_ST1, + TILEGX_OPC_ST1_ADD, + TILEGX_OPC_ST2, + TILEGX_OPC_ST2_ADD, + TILEGX_OPC_ST4, + TILEGX_OPC_ST4_ADD, + TILEGX_OPC_ST_ADD, + TILEGX_OPC_STNT, + TILEGX_OPC_STNT1, + TILEGX_OPC_STNT1_ADD, + TILEGX_OPC_STNT2, + TILEGX_OPC_STNT2_ADD, + TILEGX_OPC_STNT4, + TILEGX_OPC_STNT4_ADD, + TILEGX_OPC_STNT_ADD, + TILEGX_OPC_SUB, + TILEGX_OPC_SUBX, + TILEGX_OPC_SUBXSC, + TILEGX_OPC_SWINT0, + TILEGX_OPC_SWINT1, + TILEGX_OPC_SWINT2, + TILEGX_OPC_SWINT3, + TILEGX_OPC_TBLIDXB0, + TILEGX_OPC_TBLIDXB1, + TILEGX_OPC_TBLIDXB2, + TILEGX_OPC_TBLIDXB3, + TILEGX_OPC_V1ADD, + TILEGX_OPC_V1ADDI, + TILEGX_OPC_V1ADDUC, + TILEGX_OPC_V1ADIFFU, + TILEGX_OPC_V1AVGU, + TILEGX_OPC_V1CMPEQ, + TILEGX_OPC_V1CMPEQI, + TILEGX_OPC_V1CMPLES, + TILEGX_OPC_V1CMPLEU, + TILEGX_OPC_V1CMPLTS, + TILEGX_OPC_V1CMPLTSI, + TILEGX_OPC_V1CMPLTU, + TILEGX_OPC_V1CMPLTUI, + TILEGX_OPC_V1CMPNE, + TILEGX_OPC_V1DDOTPU, + TILEGX_OPC_V1DDOTPUA, + TILEGX_OPC_V1DDOTPUS, + TILEGX_OPC_V1DDOTPUSA, + TILEGX_OPC_V1DOTP, + TILEGX_OPC_V1DOTPA, + TILEGX_OPC_V1DOTPU, + TILEGX_OPC_V1DOTPUA, + TILEGX_OPC_V1DOTPUS, + TILEGX_OPC_V1DOTPUSA, + TILEGX_OPC_V1INT_H, + TILEGX_OPC_V1INT_L, + TILEGX_OPC_V1MAXU, + TILEGX_OPC_V1MAXUI, + TILEGX_OPC_V1MINU, + TILEGX_OPC_V1MINUI, + TILEGX_OPC_V1MNZ, + TILEGX_OPC_V1MULTU, + TILEGX_OPC_V1MULU, + TILEGX_OPC_V1MULUS, + TILEGX_OPC_V1MZ, + TILEGX_OPC_V1SADAU, + TILEGX_OPC_V1SADU, + TILEGX_OPC_V1SHL, + TILEGX_OPC_V1SHLI, + TILEGX_OPC_V1SHRS, + TILEGX_OPC_V1SHRSI, + TILEGX_OPC_V1SHRU, + TILEGX_OPC_V1SHRUI, + TILEGX_OPC_V1SUB, + TILEGX_OPC_V1SUBUC, + TILEGX_OPC_V2ADD, + TILEGX_OPC_V2ADDI, + TILEGX_OPC_V2ADDSC, + TILEGX_OPC_V2ADIFFS, + TILEGX_OPC_V2AVGS, + TILEGX_OPC_V2CMPEQ, + TILEGX_OPC_V2CMPEQI, + TILEGX_OPC_V2CMPLES, + TILEGX_OPC_V2CMPLEU, + TILEGX_OPC_V2CMPLTS, + TILEGX_OPC_V2CMPLTSI, + TILEGX_OPC_V2CMPLTU, + TILEGX_OPC_V2CMPLTUI, + TILEGX_OPC_V2CMPNE, + TILEGX_OPC_V2DOTP, + TILEGX_OPC_V2DOTPA, + TILEGX_OPC_V2INT_H, + TILEGX_OPC_V2INT_L, + TILEGX_OPC_V2MAXS, + TILEGX_OPC_V2MAXSI, + TILEGX_OPC_V2MINS, + TILEGX_OPC_V2MINSI, + TILEGX_OPC_V2MNZ, + TILEGX_OPC_V2MULFSC, + TILEGX_OPC_V2MULS, + TILEGX_OPC_V2MULTS, + TILEGX_OPC_V2MZ, + TILEGX_OPC_V2PACKH, + TILEGX_OPC_V2PACKL, + TILEGX_OPC_V2PACKUC, + TILEGX_OPC_V2SADAS, + TILEGX_OPC_V2SADAU, + TILEGX_OPC_V2SADS, + TILEGX_OPC_V2SADU, + TILEGX_OPC_V2SHL, + TILEGX_OPC_V2SHLI, + TILEGX_OPC_V2SHLSC, + TILEGX_OPC_V2SHRS, + TILEGX_OPC_V2SHRSI, + TILEGX_OPC_V2SHRU, + TILEGX_OPC_V2SHRUI, + TILEGX_OPC_V2SUB, + TILEGX_OPC_V2SUBSC, + TILEGX_OPC_V4ADD, + TILEGX_OPC_V4ADDSC, + TILEGX_OPC_V4INT_H, + TILEGX_OPC_V4INT_L, + TILEGX_OPC_V4PACKSC, + TILEGX_OPC_V4SHL, + TILEGX_OPC_V4SHLSC, + TILEGX_OPC_V4SHRS, + TILEGX_OPC_V4SHRU, + TILEGX_OPC_V4SUB, + TILEGX_OPC_V4SUBSC, + TILEGX_OPC_WH64, + TILEGX_OPC_XOR, + TILEGX_OPC_XORI, + TILEGX_OPC_NONE +} tilegx_mnemonic; + +enum +{ + TILEGX_MAX_OPERANDS = 4 /* bfexts */ +}; + +struct tilegx_opcode +{ + /* The opcode mnemonic, e.g. "add" */ + const char *name; + + /* The enum value for this mnemonic. */ + tilegx_mnemonic mnemonic; + + /* A bit mask of which of the five pipes this instruction + is compatible with: + X0 0x01 + X1 0x02 + Y0 0x04 + Y1 0x08 + Y2 0x10 */ + unsigned char pipes; + + /* How many operands are there? */ + unsigned char num_operands; + + /* Which register does this write implicitly, or TREG_ZERO if none? */ + unsigned char implicitly_written_register; + + /* Can this be bundled with other instructions (almost always true). */ + unsigned char can_bundle; + + /* The description of the operands. Each of these is an + * index into the tilegx_operands[] table. */ + unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS]; + + /* A mask of which bits have predefined values for each pipeline. + * This is useful for disassembly. */ + tilegx_bundle_bits fixed_bit_masks[TILEGX_NUM_PIPELINE_ENCODINGS]; + + /* For each bit set in fixed_bit_masks, what the value is for this + * instruction. */ + tilegx_bundle_bits fixed_bit_values[TILEGX_NUM_PIPELINE_ENCODINGS]; +}; + +/* Used for non-textual disassembly into structs. */ +struct tilegx_decoded_instruction +{ + const struct tilegx_opcode *opcode; + const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS]; + long long operand_values[TILEGX_MAX_OPERANDS]; +}; + +enum +{ + ADDI_IMM8_OPCODE_X0 = 1, + ADDI_IMM8_OPCODE_X1 = 1, + ADDI_OPCODE_Y0 = 0, + ADDI_OPCODE_Y1 = 1, + ADDLI_OPCODE_X0 = 1, + ADDLI_OPCODE_X1 = 0, + ADDXI_IMM8_OPCODE_X0 = 2, + ADDXI_IMM8_OPCODE_X1 = 2, + ADDXI_OPCODE_Y0 = 1, + ADDXI_OPCODE_Y1 = 2, + ADDXLI_OPCODE_X0 = 2, + ADDXLI_OPCODE_X1 = 1, + ADDXSC_RRR_0_OPCODE_X0 = 1, + ADDXSC_RRR_0_OPCODE_X1 = 1, + ADDX_RRR_0_OPCODE_X0 = 2, + ADDX_RRR_0_OPCODE_X1 = 2, + ADDX_RRR_0_OPCODE_Y0 = 0, + ADDX_SPECIAL_0_OPCODE_Y1 = 0, + ADD_RRR_0_OPCODE_X0 = 3, + ADD_RRR_0_OPCODE_X1 = 3, + ADD_RRR_0_OPCODE_Y0 = 1, + ADD_SPECIAL_0_OPCODE_Y1 = 1, + ANDI_IMM8_OPCODE_X0 = 3, + ANDI_IMM8_OPCODE_X1 = 3, + ANDI_OPCODE_Y0 = 2, + ANDI_OPCODE_Y1 = 3, + AND_RRR_0_OPCODE_X0 = 4, + AND_RRR_0_OPCODE_X1 = 4, + AND_RRR_5_OPCODE_Y0 = 0, + AND_RRR_5_OPCODE_Y1 = 0, + BEQZT_BRANCH_OPCODE_X1 = 16, + BEQZ_BRANCH_OPCODE_X1 = 17, + BFEXTS_BF_OPCODE_X0 = 4, + BFEXTU_BF_OPCODE_X0 = 5, + BFINS_BF_OPCODE_X0 = 6, + BF_OPCODE_X0 = 3, + BGEZT_BRANCH_OPCODE_X1 = 18, + BGEZ_BRANCH_OPCODE_X1 = 19, + BGTZT_BRANCH_OPCODE_X1 = 20, + BGTZ_BRANCH_OPCODE_X1 = 21, + BLBCT_BRANCH_OPCODE_X1 = 22, + BLBC_BRANCH_OPCODE_X1 = 23, + BLBST_BRANCH_OPCODE_X1 = 24, + BLBS_BRANCH_OPCODE_X1 = 25, + BLEZT_BRANCH_OPCODE_X1 = 26, + BLEZ_BRANCH_OPCODE_X1 = 27, + BLTZT_BRANCH_OPCODE_X1 = 28, + BLTZ_BRANCH_OPCODE_X1 = 29, + BNEZT_BRANCH_OPCODE_X1 = 30, + BNEZ_BRANCH_OPCODE_X1 = 31, + BRANCH_OPCODE_X1 = 2, + CMOVEQZ_RRR_0_OPCODE_X0 = 5, + CMOVEQZ_RRR_4_OPCODE_Y0 = 0, + CMOVNEZ_RRR_0_OPCODE_X0 = 6, + CMOVNEZ_RRR_4_OPCODE_Y0 = 1, + CMPEQI_IMM8_OPCODE_X0 = 4, + CMPEQI_IMM8_OPCODE_X1 = 4, + CMPEQI_OPCODE_Y0 = 3, + CMPEQI_OPCODE_Y1 = 4, + CMPEQ_RRR_0_OPCODE_X0 = 7, + CMPEQ_RRR_0_OPCODE_X1 = 5, + CMPEQ_RRR_3_OPCODE_Y0 = 0, + CMPEQ_RRR_3_OPCODE_Y1 = 2, + CMPEXCH4_RRR_0_OPCODE_X1 = 6, + CMPEXCH_RRR_0_OPCODE_X1 = 7, + CMPLES_RRR_0_OPCODE_X0 = 8, + CMPLES_RRR_0_OPCODE_X1 = 8, + CMPLES_RRR_2_OPCODE_Y0 = 0, + CMPLES_RRR_2_OPCODE_Y1 = 0, + CMPLEU_RRR_0_OPCODE_X0 = 9, + CMPLEU_RRR_0_OPCODE_X1 = 9, + CMPLEU_RRR_2_OPCODE_Y0 = 1, + CMPLEU_RRR_2_OPCODE_Y1 = 1, + CMPLTSI_IMM8_OPCODE_X0 = 5, + CMPLTSI_IMM8_OPCODE_X1 = 5, + CMPLTSI_OPCODE_Y0 = 4, + CMPLTSI_OPCODE_Y1 = 5, + CMPLTS_RRR_0_OPCODE_X0 = 10, + CMPLTS_RRR_0_OPCODE_X1 = 10, + CMPLTS_RRR_2_OPCODE_Y0 = 2, + CMPLTS_RRR_2_OPCODE_Y1 = 2, + CMPLTUI_IMM8_OPCODE_X0 = 6, + CMPLTUI_IMM8_OPCODE_X1 = 6, + CMPLTU_RRR_0_OPCODE_X0 = 11, + CMPLTU_RRR_0_OPCODE_X1 = 11, + CMPLTU_RRR_2_OPCODE_Y0 = 3, + CMPLTU_RRR_2_OPCODE_Y1 = 3, + CMPNE_RRR_0_OPCODE_X0 = 12, + CMPNE_RRR_0_OPCODE_X1 = 12, + CMPNE_RRR_3_OPCODE_Y0 = 1, + CMPNE_RRR_3_OPCODE_Y1 = 3, + CMULAF_RRR_0_OPCODE_X0 = 13, + CMULA_RRR_0_OPCODE_X0 = 14, + CMULFR_RRR_0_OPCODE_X0 = 15, + CMULF_RRR_0_OPCODE_X0 = 16, + CMULHR_RRR_0_OPCODE_X0 = 17, + CMULH_RRR_0_OPCODE_X0 = 18, + CMUL_RRR_0_OPCODE_X0 = 19, + CNTLZ_UNARY_OPCODE_X0 = 1, + CNTLZ_UNARY_OPCODE_Y0 = 1, + CNTTZ_UNARY_OPCODE_X0 = 2, + CNTTZ_UNARY_OPCODE_Y0 = 2, + CRC32_32_RRR_0_OPCODE_X0 = 20, + CRC32_8_RRR_0_OPCODE_X0 = 21, + DBLALIGN2_RRR_0_OPCODE_X0 = 22, + DBLALIGN2_RRR_0_OPCODE_X1 = 13, + DBLALIGN4_RRR_0_OPCODE_X0 = 23, + DBLALIGN4_RRR_0_OPCODE_X1 = 14, + DBLALIGN6_RRR_0_OPCODE_X0 = 24, + DBLALIGN6_RRR_0_OPCODE_X1 = 15, + DBLALIGN_RRR_0_OPCODE_X0 = 25, + DRAIN_UNARY_OPCODE_X1 = 1, + DTLBPR_UNARY_OPCODE_X1 = 2, + EXCH4_RRR_0_OPCODE_X1 = 16, + EXCH_RRR_0_OPCODE_X1 = 17, + FDOUBLE_ADDSUB_RRR_0_OPCODE_X0 = 26, + FDOUBLE_ADD_FLAGS_RRR_0_OPCODE_X0 = 27, + FDOUBLE_MUL_FLAGS_RRR_0_OPCODE_X0 = 28, + FDOUBLE_PACK1_RRR_0_OPCODE_X0 = 29, + FDOUBLE_PACK2_RRR_0_OPCODE_X0 = 30, + FDOUBLE_SUB_FLAGS_RRR_0_OPCODE_X0 = 31, + FDOUBLE_UNPACK_MAX_RRR_0_OPCODE_X0 = 32, + FDOUBLE_UNPACK_MIN_RRR_0_OPCODE_X0 = 33, + FETCHADD4_RRR_0_OPCODE_X1 = 18, + FETCHADDGEZ4_RRR_0_OPCODE_X1 = 19, + FETCHADDGEZ_RRR_0_OPCODE_X1 = 20, + FETCHADD_RRR_0_OPCODE_X1 = 21, + FETCHAND4_RRR_0_OPCODE_X1 = 22, + FETCHAND_RRR_0_OPCODE_X1 = 23, + FETCHOR4_RRR_0_OPCODE_X1 = 24, + FETCHOR_RRR_0_OPCODE_X1 = 25, + FINV_UNARY_OPCODE_X1 = 3, + FLUSHWB_UNARY_OPCODE_X1 = 4, + FLUSH_UNARY_OPCODE_X1 = 5, + FNOP_UNARY_OPCODE_X0 = 3, + FNOP_UNARY_OPCODE_X1 = 6, + FNOP_UNARY_OPCODE_Y0 = 3, + FNOP_UNARY_OPCODE_Y1 = 8, + FSINGLE_ADD1_RRR_0_OPCODE_X0 = 34, + FSINGLE_ADDSUB2_RRR_0_OPCODE_X0 = 35, + FSINGLE_MUL1_RRR_0_OPCODE_X0 = 36, + FSINGLE_MUL2_RRR_0_OPCODE_X0 = 37, + FSINGLE_PACK1_UNARY_OPCODE_X0 = 4, + FSINGLE_PACK1_UNARY_OPCODE_Y0 = 4, + FSINGLE_PACK2_RRR_0_OPCODE_X0 = 38, + FSINGLE_SUB1_RRR_0_OPCODE_X0 = 39, + ICOH_UNARY_OPCODE_X1 = 7, + ILL_UNARY_OPCODE_X1 = 8, + ILL_UNARY_OPCODE_Y1 = 9, + IMM8_OPCODE_X0 = 4, + IMM8_OPCODE_X1 = 3, + INV_UNARY_OPCODE_X1 = 9, + IRET_UNARY_OPCODE_X1 = 10, + JALRP_UNARY_OPCODE_X1 = 11, + JALRP_UNARY_OPCODE_Y1 = 10, + JALR_UNARY_OPCODE_X1 = 12, + JALR_UNARY_OPCODE_Y1 = 11, + JAL_JUMP_OPCODE_X1 = 0, + JRP_UNARY_OPCODE_X1 = 13, + JRP_UNARY_OPCODE_Y1 = 12, + JR_UNARY_OPCODE_X1 = 14, + JR_UNARY_OPCODE_Y1 = 13, + JUMP_OPCODE_X1 = 4, + J_JUMP_OPCODE_X1 = 1, + LD1S_ADD_IMM8_OPCODE_X1 = 7, + LD1S_OPCODE_Y2 = 0, + LD1S_UNARY_OPCODE_X1 = 15, + LD1U_ADD_IMM8_OPCODE_X1 = 8, + LD1U_OPCODE_Y2 = 1, + LD1U_UNARY_OPCODE_X1 = 16, + LD2S_ADD_IMM8_OPCODE_X1 = 9, + LD2S_OPCODE_Y2 = 2, + LD2S_UNARY_OPCODE_X1 = 17, + LD2U_ADD_IMM8_OPCODE_X1 = 10, + LD2U_OPCODE_Y2 = 3, + LD2U_UNARY_OPCODE_X1 = 18, + LD4S_ADD_IMM8_OPCODE_X1 = 11, + LD4S_OPCODE_Y2 = 1, + LD4S_UNARY_OPCODE_X1 = 19, + LD4U_ADD_IMM8_OPCODE_X1 = 12, + LD4U_OPCODE_Y2 = 2, + LD4U_UNARY_OPCODE_X1 = 20, + LDNA_UNARY_OPCODE_X1 = 21, + LDNT1S_ADD_IMM8_OPCODE_X1 = 13, + LDNT1S_UNARY_OPCODE_X1 = 22, + LDNT1U_ADD_IMM8_OPCODE_X1 = 14, + LDNT1U_UNARY_OPCODE_X1 = 23, + LDNT2S_ADD_IMM8_OPCODE_X1 = 15, + LDNT2S_UNARY_OPCODE_X1 = 24, + LDNT2U_ADD_IMM8_OPCODE_X1 = 16, + LDNT2U_UNARY_OPCODE_X1 = 25, + LDNT4S_ADD_IMM8_OPCODE_X1 = 17, + LDNT4S_UNARY_OPCODE_X1 = 26, + LDNT4U_ADD_IMM8_OPCODE_X1 = 18, + LDNT4U_UNARY_OPCODE_X1 = 27, + LDNT_ADD_IMM8_OPCODE_X1 = 19, + LDNT_UNARY_OPCODE_X1 = 28, + LD_ADD_IMM8_OPCODE_X1 = 20, + LD_OPCODE_Y2 = 3, + LD_UNARY_OPCODE_X1 = 29, + LNK_UNARY_OPCODE_X1 = 30, + LNK_UNARY_OPCODE_Y1 = 14, + LWNA_ADD_IMM8_OPCODE_X1 = 21, + MFSPR_IMM8_OPCODE_X1 = 22, + MF_UNARY_OPCODE_X1 = 31, + MM_BF_OPCODE_X0 = 7, + MNZ_RRR_0_OPCODE_X0 = 40, + MNZ_RRR_0_OPCODE_X1 = 26, + MNZ_RRR_4_OPCODE_Y0 = 2, + MNZ_RRR_4_OPCODE_Y1 = 2, + MODE_OPCODE_YA2 = 1, + MODE_OPCODE_YB2 = 2, + MODE_OPCODE_YC2 = 3, + MTSPR_IMM8_OPCODE_X1 = 23, + MULAX_RRR_0_OPCODE_X0 = 41, + MULAX_RRR_3_OPCODE_Y0 = 2, + MULA_HS_HS_RRR_0_OPCODE_X0 = 42, + MULA_HS_HS_RRR_9_OPCODE_Y0 = 0, + MULA_HS_HU_RRR_0_OPCODE_X0 = 43, + MULA_HS_LS_RRR_0_OPCODE_X0 = 44, + MULA_HS_LU_RRR_0_OPCODE_X0 = 45, + MULA_HU_HU_RRR_0_OPCODE_X0 = 46, + MULA_HU_HU_RRR_9_OPCODE_Y0 = 1, + MULA_HU_LS_RRR_0_OPCODE_X0 = 47, + MULA_HU_LU_RRR_0_OPCODE_X0 = 48, + MULA_LS_LS_RRR_0_OPCODE_X0 = 49, + MULA_LS_LS_RRR_9_OPCODE_Y0 = 2, + MULA_LS_LU_RRR_0_OPCODE_X0 = 50, + MULA_LU_LU_RRR_0_OPCODE_X0 = 51, + MULA_LU_LU_RRR_9_OPCODE_Y0 = 3, + MULX_RRR_0_OPCODE_X0 = 52, + MULX_RRR_3_OPCODE_Y0 = 3, + MUL_HS_HS_RRR_0_OPCODE_X0 = 53, + MUL_HS_HS_RRR_8_OPCODE_Y0 = 0, + MUL_HS_HU_RRR_0_OPCODE_X0 = 54, + MUL_HS_LS_RRR_0_OPCODE_X0 = 55, + MUL_HS_LU_RRR_0_OPCODE_X0 = 56, + MUL_HU_HU_RRR_0_OPCODE_X0 = 57, + MUL_HU_HU_RRR_8_OPCODE_Y0 = 1, + MUL_HU_LS_RRR_0_OPCODE_X0 = 58, + MUL_HU_LU_RRR_0_OPCODE_X0 = 59, + MUL_LS_LS_RRR_0_OPCODE_X0 = 60, + MUL_LS_LS_RRR_8_OPCODE_Y0 = 2, + MUL_LS_LU_RRR_0_OPCODE_X0 = 61, + MUL_LU_LU_RRR_0_OPCODE_X0 = 62, + MUL_LU_LU_RRR_8_OPCODE_Y0 = 3, + MZ_RRR_0_OPCODE_X0 = 63, + MZ_RRR_0_OPCODE_X1 = 27, + MZ_RRR_4_OPCODE_Y0 = 3, + MZ_RRR_4_OPCODE_Y1 = 3, + NAP_UNARY_OPCODE_X1 = 32, + NOP_UNARY_OPCODE_X0 = 5, + NOP_UNARY_OPCODE_X1 = 33, + NOP_UNARY_OPCODE_Y0 = 5, + NOP_UNARY_OPCODE_Y1 = 15, + NOR_RRR_0_OPCODE_X0 = 64, + NOR_RRR_0_OPCODE_X1 = 28, + NOR_RRR_5_OPCODE_Y0 = 1, + NOR_RRR_5_OPCODE_Y1 = 1, + ORI_IMM8_OPCODE_X0 = 7, + ORI_IMM8_OPCODE_X1 = 24, + OR_RRR_0_OPCODE_X0 = 65, + OR_RRR_0_OPCODE_X1 = 29, + OR_RRR_5_OPCODE_Y0 = 2, + OR_RRR_5_OPCODE_Y1 = 2, + PCNT_UNARY_OPCODE_X0 = 6, + PCNT_UNARY_OPCODE_Y0 = 6, + REVBITS_UNARY_OPCODE_X0 = 7, + REVBITS_UNARY_OPCODE_Y0 = 7, + REVBYTES_UNARY_OPCODE_X0 = 8, + REVBYTES_UNARY_OPCODE_Y0 = 8, + ROTLI_SHIFT_OPCODE_X0 = 1, + ROTLI_SHIFT_OPCODE_X1 = 1, + ROTLI_SHIFT_OPCODE_Y0 = 0, + ROTLI_SHIFT_OPCODE_Y1 = 0, + ROTL_RRR_0_OPCODE_X0 = 66, + ROTL_RRR_0_OPCODE_X1 = 30, + ROTL_RRR_6_OPCODE_Y0 = 0, + ROTL_RRR_6_OPCODE_Y1 = 0, + RRR_0_OPCODE_X0 = 5, + RRR_0_OPCODE_X1 = 5, + RRR_0_OPCODE_Y0 = 5, + RRR_0_OPCODE_Y1 = 6, + RRR_1_OPCODE_Y0 = 6, + RRR_1_OPCODE_Y1 = 7, + RRR_2_OPCODE_Y0 = 7, + RRR_2_OPCODE_Y1 = 8, + RRR_3_OPCODE_Y0 = 8, + RRR_3_OPCODE_Y1 = 9, + RRR_4_OPCODE_Y0 = 9, + RRR_4_OPCODE_Y1 = 10, + RRR_5_OPCODE_Y0 = 10, + RRR_5_OPCODE_Y1 = 11, + RRR_6_OPCODE_Y0 = 11, + RRR_6_OPCODE_Y1 = 12, + RRR_7_OPCODE_Y0 = 12, + RRR_7_OPCODE_Y1 = 13, + RRR_8_OPCODE_Y0 = 13, + RRR_9_OPCODE_Y0 = 14, + SHIFT_OPCODE_X0 = 6, + SHIFT_OPCODE_X1 = 6, + SHIFT_OPCODE_Y0 = 15, + SHIFT_OPCODE_Y1 = 14, + SHL16INSLI_OPCODE_X0 = 7, + SHL16INSLI_OPCODE_X1 = 7, + SHL1ADDX_RRR_0_OPCODE_X0 = 67, + SHL1ADDX_RRR_0_OPCODE_X1 = 31, + SHL1ADDX_RRR_7_OPCODE_Y0 = 1, + SHL1ADDX_RRR_7_OPCODE_Y1 = 1, + SHL1ADD_RRR_0_OPCODE_X0 = 68, + SHL1ADD_RRR_0_OPCODE_X1 = 32, + SHL1ADD_RRR_1_OPCODE_Y0 = 0, + SHL1ADD_RRR_1_OPCODE_Y1 = 0, + SHL2ADDX_RRR_0_OPCODE_X0 = 69, + SHL2ADDX_RRR_0_OPCODE_X1 = 33, + SHL2ADDX_RRR_7_OPCODE_Y0 = 2, + SHL2ADDX_RRR_7_OPCODE_Y1 = 2, + SHL2ADD_RRR_0_OPCODE_X0 = 70, + SHL2ADD_RRR_0_OPCODE_X1 = 34, + SHL2ADD_RRR_1_OPCODE_Y0 = 1, + SHL2ADD_RRR_1_OPCODE_Y1 = 1, + SHL3ADDX_RRR_0_OPCODE_X0 = 71, + SHL3ADDX_RRR_0_OPCODE_X1 = 35, + SHL3ADDX_RRR_7_OPCODE_Y0 = 3, + SHL3ADDX_RRR_7_OPCODE_Y1 = 3, + SHL3ADD_RRR_0_OPCODE_X0 = 72, + SHL3ADD_RRR_0_OPCODE_X1 = 36, + SHL3ADD_RRR_1_OPCODE_Y0 = 2, + SHL3ADD_RRR_1_OPCODE_Y1 = 2, + SHLI_SHIFT_OPCODE_X0 = 2, + SHLI_SHIFT_OPCODE_X1 = 2, + SHLI_SHIFT_OPCODE_Y0 = 1, + SHLI_SHIFT_OPCODE_Y1 = 1, + SHLXI_SHIFT_OPCODE_X0 = 3, + SHLXI_SHIFT_OPCODE_X1 = 3, + SHLX_RRR_0_OPCODE_X0 = 73, + SHLX_RRR_0_OPCODE_X1 = 37, + SHL_RRR_0_OPCODE_X0 = 74, + SHL_RRR_0_OPCODE_X1 = 38, + SHL_RRR_6_OPCODE_Y0 = 1, + SHL_RRR_6_OPCODE_Y1 = 1, + SHRSI_SHIFT_OPCODE_X0 = 4, + SHRSI_SHIFT_OPCODE_X1 = 4, + SHRSI_SHIFT_OPCODE_Y0 = 2, + SHRSI_SHIFT_OPCODE_Y1 = 2, + SHRS_RRR_0_OPCODE_X0 = 75, + SHRS_RRR_0_OPCODE_X1 = 39, + SHRS_RRR_6_OPCODE_Y0 = 2, + SHRS_RRR_6_OPCODE_Y1 = 2, + SHRUI_SHIFT_OPCODE_X0 = 5, + SHRUI_SHIFT_OPCODE_X1 = 5, + SHRUI_SHIFT_OPCODE_Y0 = 3, + SHRUI_SHIFT_OPCODE_Y1 = 3, + SHRUXI_SHIFT_OPCODE_X0 = 6, + SHRUXI_SHIFT_OPCODE_X1 = 6, + SHRUX_RRR_0_OPCODE_X0 = 76, + SHRUX_RRR_0_OPCODE_X1 = 40, + SHRU_RRR_0_OPCODE_X0 = 77, + SHRU_RRR_0_OPCODE_X1 = 41, + SHRU_RRR_6_OPCODE_Y0 = 3, + SHRU_RRR_6_OPCODE_Y1 = 3, + SHUFFLEBYTES_RRR_0_OPCODE_X0 = 78, + ST1_ADD_IMM8_OPCODE_X1 = 25, + ST1_OPCODE_Y2 = 0, + ST1_RRR_0_OPCODE_X1 = 42, + ST2_ADD_IMM8_OPCODE_X1 = 26, + ST2_OPCODE_Y2 = 1, + ST2_RRR_0_OPCODE_X1 = 43, + ST4_ADD_IMM8_OPCODE_X1 = 27, + ST4_OPCODE_Y2 = 2, + ST4_RRR_0_OPCODE_X1 = 44, + STNT1_ADD_IMM8_OPCODE_X1 = 28, + STNT1_RRR_0_OPCODE_X1 = 45, + STNT2_ADD_IMM8_OPCODE_X1 = 29, + STNT2_RRR_0_OPCODE_X1 = 46, + STNT4_ADD_IMM8_OPCODE_X1 = 30, + STNT4_RRR_0_OPCODE_X1 = 47, + STNT_ADD_IMM8_OPCODE_X1 = 31, + STNT_RRR_0_OPCODE_X1 = 48, + ST_ADD_IMM8_OPCODE_X1 = 32, + ST_OPCODE_Y2 = 3, + ST_RRR_0_OPCODE_X1 = 49, + SUBXSC_RRR_0_OPCODE_X0 = 79, + SUBXSC_RRR_0_OPCODE_X1 = 50, + SUBX_RRR_0_OPCODE_X0 = 80, + SUBX_RRR_0_OPCODE_X1 = 51, + SUBX_RRR_0_OPCODE_Y0 = 2, + SUBX_RRR_0_OPCODE_Y1 = 2, + SUB_RRR_0_OPCODE_X0 = 81, + SUB_RRR_0_OPCODE_X1 = 52, + SUB_RRR_0_OPCODE_Y0 = 3, + SUB_RRR_0_OPCODE_Y1 = 3, + SWINT0_UNARY_OPCODE_X1 = 34, + SWINT1_UNARY_OPCODE_X1 = 35, + SWINT2_UNARY_OPCODE_X1 = 36, + SWINT3_UNARY_OPCODE_X1 = 37, + TBLIDXB0_UNARY_OPCODE_X0 = 9, + TBLIDXB0_UNARY_OPCODE_Y0 = 9, + TBLIDXB1_UNARY_OPCODE_X0 = 10, + TBLIDXB1_UNARY_OPCODE_Y0 = 10, + TBLIDXB2_UNARY_OPCODE_X0 = 11, + TBLIDXB2_UNARY_OPCODE_Y0 = 11, + TBLIDXB3_UNARY_OPCODE_X0 = 12, + TBLIDXB3_UNARY_OPCODE_Y0 = 12, + UNARY_RRR_0_OPCODE_X0 = 82, + UNARY_RRR_0_OPCODE_X1 = 53, + UNARY_RRR_1_OPCODE_Y0 = 3, + UNARY_RRR_1_OPCODE_Y1 = 3, + V1ADDI_IMM8_OPCODE_X0 = 8, + V1ADDI_IMM8_OPCODE_X1 = 33, + V1ADDUC_RRR_0_OPCODE_X0 = 83, + V1ADDUC_RRR_0_OPCODE_X1 = 54, + V1ADD_RRR_0_OPCODE_X0 = 84, + V1ADD_RRR_0_OPCODE_X1 = 55, + V1ADIFFU_RRR_0_OPCODE_X0 = 85, + V1AVGU_RRR_0_OPCODE_X0 = 86, + V1CMPEQI_IMM8_OPCODE_X0 = 9, + V1CMPEQI_IMM8_OPCODE_X1 = 34, + V1CMPEQ_RRR_0_OPCODE_X0 = 87, + V1CMPEQ_RRR_0_OPCODE_X1 = 56, + V1CMPLES_RRR_0_OPCODE_X0 = 88, + V1CMPLES_RRR_0_OPCODE_X1 = 57, + V1CMPLEU_RRR_0_OPCODE_X0 = 89, + V1CMPLEU_RRR_0_OPCODE_X1 = 58, + V1CMPLTSI_IMM8_OPCODE_X0 = 10, + V1CMPLTSI_IMM8_OPCODE_X1 = 35, + V1CMPLTS_RRR_0_OPCODE_X0 = 90, + V1CMPLTS_RRR_0_OPCODE_X1 = 59, + V1CMPLTUI_IMM8_OPCODE_X0 = 11, + V1CMPLTUI_IMM8_OPCODE_X1 = 36, + V1CMPLTU_RRR_0_OPCODE_X0 = 91, + V1CMPLTU_RRR_0_OPCODE_X1 = 60, + V1CMPNE_RRR_0_OPCODE_X0 = 92, + V1CMPNE_RRR_0_OPCODE_X1 = 61, + V1DDOTPUA_RRR_0_OPCODE_X0 = 161, + V1DDOTPUSA_RRR_0_OPCODE_X0 = 93, + V1DDOTPUS_RRR_0_OPCODE_X0 = 94, + V1DDOTPU_RRR_0_OPCODE_X0 = 162, + V1DOTPA_RRR_0_OPCODE_X0 = 95, + V1DOTPUA_RRR_0_OPCODE_X0 = 163, + V1DOTPUSA_RRR_0_OPCODE_X0 = 96, + V1DOTPUS_RRR_0_OPCODE_X0 = 97, + V1DOTPU_RRR_0_OPCODE_X0 = 164, + V1DOTP_RRR_0_OPCODE_X0 = 98, + V1INT_H_RRR_0_OPCODE_X0 = 99, + V1INT_H_RRR_0_OPCODE_X1 = 62, + V1INT_L_RRR_0_OPCODE_X0 = 100, + V1INT_L_RRR_0_OPCODE_X1 = 63, + V1MAXUI_IMM8_OPCODE_X0 = 12, + V1MAXUI_IMM8_OPCODE_X1 = 37, + V1MAXU_RRR_0_OPCODE_X0 = 101, + V1MAXU_RRR_0_OPCODE_X1 = 64, + V1MINUI_IMM8_OPCODE_X0 = 13, + V1MINUI_IMM8_OPCODE_X1 = 38, + V1MINU_RRR_0_OPCODE_X0 = 102, + V1MINU_RRR_0_OPCODE_X1 = 65, + V1MNZ_RRR_0_OPCODE_X0 = 103, + V1MNZ_RRR_0_OPCODE_X1 = 66, + V1MULTU_RRR_0_OPCODE_X0 = 104, + V1MULUS_RRR_0_OPCODE_X0 = 105, + V1MULU_RRR_0_OPCODE_X0 = 106, + V1MZ_RRR_0_OPCODE_X0 = 107, + V1MZ_RRR_0_OPCODE_X1 = 67, + V1SADAU_RRR_0_OPCODE_X0 = 108, + V1SADU_RRR_0_OPCODE_X0 = 109, + V1SHLI_SHIFT_OPCODE_X0 = 7, + V1SHLI_SHIFT_OPCODE_X1 = 7, + V1SHL_RRR_0_OPCODE_X0 = 110, + V1SHL_RRR_0_OPCODE_X1 = 68, + V1SHRSI_SHIFT_OPCODE_X0 = 8, + V1SHRSI_SHIFT_OPCODE_X1 = 8, + V1SHRS_RRR_0_OPCODE_X0 = 111, + V1SHRS_RRR_0_OPCODE_X1 = 69, + V1SHRUI_SHIFT_OPCODE_X0 = 9, + V1SHRUI_SHIFT_OPCODE_X1 = 9, + V1SHRU_RRR_0_OPCODE_X0 = 112, + V1SHRU_RRR_0_OPCODE_X1 = 70, + V1SUBUC_RRR_0_OPCODE_X0 = 113, + V1SUBUC_RRR_0_OPCODE_X1 = 71, + V1SUB_RRR_0_OPCODE_X0 = 114, + V1SUB_RRR_0_OPCODE_X1 = 72, + V2ADDI_IMM8_OPCODE_X0 = 14, + V2ADDI_IMM8_OPCODE_X1 = 39, + V2ADDSC_RRR_0_OPCODE_X0 = 115, + V2ADDSC_RRR_0_OPCODE_X1 = 73, + V2ADD_RRR_0_OPCODE_X0 = 116, + V2ADD_RRR_0_OPCODE_X1 = 74, + V2ADIFFS_RRR_0_OPCODE_X0 = 117, + V2AVGS_RRR_0_OPCODE_X0 = 118, + V2CMPEQI_IMM8_OPCODE_X0 = 15, + V2CMPEQI_IMM8_OPCODE_X1 = 40, + V2CMPEQ_RRR_0_OPCODE_X0 = 119, + V2CMPEQ_RRR_0_OPCODE_X1 = 75, + V2CMPLES_RRR_0_OPCODE_X0 = 120, + V2CMPLES_RRR_0_OPCODE_X1 = 76, + V2CMPLEU_RRR_0_OPCODE_X0 = 121, + V2CMPLEU_RRR_0_OPCODE_X1 = 77, + V2CMPLTSI_IMM8_OPCODE_X0 = 16, + V2CMPLTSI_IMM8_OPCODE_X1 = 41, + V2CMPLTS_RRR_0_OPCODE_X0 = 122, + V2CMPLTS_RRR_0_OPCODE_X1 = 78, + V2CMPLTUI_IMM8_OPCODE_X0 = 17, + V2CMPLTUI_IMM8_OPCODE_X1 = 42, + V2CMPLTU_RRR_0_OPCODE_X0 = 123, + V2CMPLTU_RRR_0_OPCODE_X1 = 79, + V2CMPNE_RRR_0_OPCODE_X0 = 124, + V2CMPNE_RRR_0_OPCODE_X1 = 80, + V2DOTPA_RRR_0_OPCODE_X0 = 125, + V2DOTP_RRR_0_OPCODE_X0 = 126, + V2INT_H_RRR_0_OPCODE_X0 = 127, + V2INT_H_RRR_0_OPCODE_X1 = 81, + V2INT_L_RRR_0_OPCODE_X0 = 128, + V2INT_L_RRR_0_OPCODE_X1 = 82, + V2MAXSI_IMM8_OPCODE_X0 = 18, + V2MAXSI_IMM8_OPCODE_X1 = 43, + V2MAXS_RRR_0_OPCODE_X0 = 129, + V2MAXS_RRR_0_OPCODE_X1 = 83, + V2MINSI_IMM8_OPCODE_X0 = 19, + V2MINSI_IMM8_OPCODE_X1 = 44, + V2MINS_RRR_0_OPCODE_X0 = 130, + V2MINS_RRR_0_OPCODE_X1 = 84, + V2MNZ_RRR_0_OPCODE_X0 = 131, + V2MNZ_RRR_0_OPCODE_X1 = 85, + V2MULFSC_RRR_0_OPCODE_X0 = 132, + V2MULS_RRR_0_OPCODE_X0 = 133, + V2MULTS_RRR_0_OPCODE_X0 = 134, + V2MZ_RRR_0_OPCODE_X0 = 135, + V2MZ_RRR_0_OPCODE_X1 = 86, + V2PACKH_RRR_0_OPCODE_X0 = 136, + V2PACKH_RRR_0_OPCODE_X1 = 87, + V2PACKL_RRR_0_OPCODE_X0 = 137, + V2PACKL_RRR_0_OPCODE_X1 = 88, + V2PACKUC_RRR_0_OPCODE_X0 = 138, + V2PACKUC_RRR_0_OPCODE_X1 = 89, + V2SADAS_RRR_0_OPCODE_X0 = 139, + V2SADAU_RRR_0_OPCODE_X0 = 140, + V2SADS_RRR_0_OPCODE_X0 = 141, + V2SADU_RRR_0_OPCODE_X0 = 142, + V2SHLI_SHIFT_OPCODE_X0 = 10, + V2SHLI_SHIFT_OPCODE_X1 = 10, + V2SHLSC_RRR_0_OPCODE_X0 = 143, + V2SHLSC_RRR_0_OPCODE_X1 = 90, + V2SHL_RRR_0_OPCODE_X0 = 144, + V2SHL_RRR_0_OPCODE_X1 = 91, + V2SHRSI_SHIFT_OPCODE_X0 = 11, + V2SHRSI_SHIFT_OPCODE_X1 = 11, + V2SHRS_RRR_0_OPCODE_X0 = 145, + V2SHRS_RRR_0_OPCODE_X1 = 92, + V2SHRUI_SHIFT_OPCODE_X0 = 12, + V2SHRUI_SHIFT_OPCODE_X1 = 12, + V2SHRU_RRR_0_OPCODE_X0 = 146, + V2SHRU_RRR_0_OPCODE_X1 = 93, + V2SUBSC_RRR_0_OPCODE_X0 = 147, + V2SUBSC_RRR_0_OPCODE_X1 = 94, + V2SUB_RRR_0_OPCODE_X0 = 148, + V2SUB_RRR_0_OPCODE_X1 = 95, + V4ADDSC_RRR_0_OPCODE_X0 = 149, + V4ADDSC_RRR_0_OPCODE_X1 = 96, + V4ADD_RRR_0_OPCODE_X0 = 150, + V4ADD_RRR_0_OPCODE_X1 = 97, + V4INT_H_RRR_0_OPCODE_X0 = 151, + V4INT_H_RRR_0_OPCODE_X1 = 98, + V4INT_L_RRR_0_OPCODE_X0 = 152, + V4INT_L_RRR_0_OPCODE_X1 = 99, + V4PACKSC_RRR_0_OPCODE_X0 = 153, + V4PACKSC_RRR_0_OPCODE_X1 = 100, + V4SHLSC_RRR_0_OPCODE_X0 = 154, + V4SHLSC_RRR_0_OPCODE_X1 = 101, + V4SHL_RRR_0_OPCODE_X0 = 155, + V4SHL_RRR_0_OPCODE_X1 = 102, + V4SHRS_RRR_0_OPCODE_X0 = 156, + V4SHRS_RRR_0_OPCODE_X1 = 103, + V4SHRU_RRR_0_OPCODE_X0 = 157, + V4SHRU_RRR_0_OPCODE_X1 = 104, + V4SUBSC_RRR_0_OPCODE_X0 = 158, + V4SUBSC_RRR_0_OPCODE_X1 = 105, + V4SUB_RRR_0_OPCODE_X0 = 159, + V4SUB_RRR_0_OPCODE_X1 = 106, + WH64_UNARY_OPCODE_X1 = 38, + XORI_IMM8_OPCODE_X0 = 20, + XORI_IMM8_OPCODE_X1 = 45, + XOR_RRR_0_OPCODE_X0 = 160, + XOR_RRR_0_OPCODE_X1 = 107, + XOR_RRR_5_OPCODE_Y0 = 3, + XOR_RRR_5_OPCODE_Y1 = 3 +}; + +static __inline unsigned int +get_BFEnd_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_BFOpcodeExtension_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 24)) & 0xf); +} + +static __inline unsigned int +get_BFStart_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 18)) & 0x3f); +} + +static __inline unsigned int +get_BrOff_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x0000003f) | + (((unsigned int)(n >> 37)) & 0x0001ffc0); +} + +static __inline unsigned int +get_BrType_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 54)) & 0x1f); +} + +static __inline unsigned int +get_Dest_Imm8_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x0000003f) | + (((unsigned int)(n >> 43)) & 0x000000c0); +} + +static __inline unsigned int +get_Dest_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 0)) & 0x3f); +} + +static __inline unsigned int +get_Dest_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x3f); +} + +static __inline unsigned int +get_Dest_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 0)) & 0x3f); +} + +static __inline unsigned int +get_Dest_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x3f); +} + +static __inline unsigned int +get_Imm16_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0xffff); +} + +static __inline unsigned int +get_Imm16_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0xffff); +} + +static __inline unsigned int +get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 20)) & 0xff); +} + +static __inline unsigned int +get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 51)) & 0xff); +} + +static __inline unsigned int +get_Imm8_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0xff); +} + +static __inline unsigned int +get_Imm8_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0xff); +} + +static __inline unsigned int +get_Imm8_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0xff); +} + +static __inline unsigned int +get_Imm8_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0xff); +} + +static __inline unsigned int +get_JumpOff_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x7ffffff); +} + +static __inline unsigned int +get_JumpOpcodeExtension_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 58)) & 0x1); +} + +static __inline unsigned int +get_MF_Imm14_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 37)) & 0x3fff); +} + +static __inline unsigned int +get_MT_Imm14_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 31)) & 0x0000003f) | + (((unsigned int)(n >> 37)) & 0x00003fc0); +} + +static __inline unsigned int +get_Mode(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 62)) & 0x3); +} + +static __inline unsigned int +get_Opcode_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 28)) & 0x7); +} + +static __inline unsigned int +get_Opcode_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 59)) & 0x7); +} + +static __inline unsigned int +get_Opcode_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 27)) & 0xf); +} + +static __inline unsigned int +get_Opcode_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 58)) & 0xf); +} + +static __inline unsigned int +get_Opcode_Y2(tilegx_bundle_bits n) +{ + return (((n >> 26)) & 0x00000001) | + (((unsigned int)(n >> 56)) & 0x00000002); +} + +static __inline unsigned int +get_RRROpcodeExtension_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 18)) & 0x3ff); +} + +static __inline unsigned int +get_RRROpcodeExtension_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 49)) & 0x3ff); +} + +static __inline unsigned int +get_RRROpcodeExtension_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 18)) & 0x3); +} + +static __inline unsigned int +get_RRROpcodeExtension_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 49)) & 0x3); +} + +static __inline unsigned int +get_ShAmt_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_ShAmt_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline unsigned int +get_ShAmt_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_ShAmt_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline unsigned int +get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 18)) & 0x3ff); +} + +static __inline unsigned int +get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 49)) & 0x3ff); +} + +static __inline unsigned int +get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 18)) & 0x3); +} + +static __inline unsigned int +get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 49)) & 0x3); +} + +static __inline unsigned int +get_SrcA_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 6)) & 0x3f); +} + +static __inline unsigned int +get_SrcA_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 37)) & 0x3f); +} + +static __inline unsigned int +get_SrcA_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 6)) & 0x3f); +} + +static __inline unsigned int +get_SrcA_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 37)) & 0x3f); +} + +static __inline unsigned int +get_SrcA_Y2(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 20)) & 0x3f); +} + +static __inline unsigned int +get_SrcBDest_Y2(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 51)) & 0x3f); +} + +static __inline unsigned int +get_SrcB_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_SrcB_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline unsigned int +get_SrcB_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_SrcB_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline unsigned int +get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline unsigned int +get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num) +{ + const unsigned int n = (unsigned int)num; + return (((n >> 12)) & 0x3f); +} + +static __inline unsigned int +get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n) +{ + return (((unsigned int)(n >> 43)) & 0x3f); +} + +static __inline int +sign_extend(int n, int num_bits) +{ + int shift = (int)(sizeof(int) * 8 - num_bits); + return (n << shift) >> shift; +} + +static __inline tilegx_bundle_bits +create_BFEnd_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_BFOpcodeExtension_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xf) << 24); +} + +static __inline tilegx_bundle_bits +create_BFStart_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 18); +} + +static __inline tilegx_bundle_bits +create_BrOff_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | + (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37); +} + +static __inline tilegx_bundle_bits +create_BrType_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x1f)) << 54); +} + +static __inline tilegx_bundle_bits +create_Dest_Imm8_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | + (((tilegx_bundle_bits)(n & 0x000000c0)) << 43); +} + +static __inline tilegx_bundle_bits +create_Dest_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 0); +} + +static __inline tilegx_bundle_bits +create_Dest_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 31); +} + +static __inline tilegx_bundle_bits +create_Dest_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 0); +} + +static __inline tilegx_bundle_bits +create_Dest_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 31); +} + +static __inline tilegx_bundle_bits +create_Imm16_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xffff) << 12); +} + +static __inline tilegx_bundle_bits +create_Imm16_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0xffff)) << 43); +} + +static __inline tilegx_bundle_bits +create_Imm8OpcodeExtension_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xff) << 20); +} + +static __inline tilegx_bundle_bits +create_Imm8OpcodeExtension_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0xff)) << 51); +} + +static __inline tilegx_bundle_bits +create_Imm8_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xff) << 12); +} + +static __inline tilegx_bundle_bits +create_Imm8_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0xff)) << 43); +} + +static __inline tilegx_bundle_bits +create_Imm8_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xff) << 12); +} + +static __inline tilegx_bundle_bits +create_Imm8_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0xff)) << 43); +} + +static __inline tilegx_bundle_bits +create_JumpOff_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31); +} + +static __inline tilegx_bundle_bits +create_JumpOpcodeExtension_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x1)) << 58); +} + +static __inline tilegx_bundle_bits +create_MF_Imm14_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3fff)) << 37); +} + +static __inline tilegx_bundle_bits +create_MT_Imm14_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) | + (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37); +} + +static __inline tilegx_bundle_bits +create_Mode(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3)) << 62); +} + +static __inline tilegx_bundle_bits +create_Opcode_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x7) << 28); +} + +static __inline tilegx_bundle_bits +create_Opcode_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x7)) << 59); +} + +static __inline tilegx_bundle_bits +create_Opcode_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0xf) << 27); +} + +static __inline tilegx_bundle_bits +create_Opcode_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0xf)) << 58); +} + +static __inline tilegx_bundle_bits +create_Opcode_Y2(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x00000001) << 26) | + (((tilegx_bundle_bits)(n & 0x00000002)) << 56); +} + +static __inline tilegx_bundle_bits +create_RRROpcodeExtension_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3ff) << 18); +} + +static __inline tilegx_bundle_bits +create_RRROpcodeExtension_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3ff)) << 49); +} + +static __inline tilegx_bundle_bits +create_RRROpcodeExtension_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3) << 18); +} + +static __inline tilegx_bundle_bits +create_RRROpcodeExtension_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3)) << 49); +} + +static __inline tilegx_bundle_bits +create_ShAmt_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_ShAmt_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +static __inline tilegx_bundle_bits +create_ShAmt_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_ShAmt_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +static __inline tilegx_bundle_bits +create_ShiftOpcodeExtension_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3ff) << 18); +} + +static __inline tilegx_bundle_bits +create_ShiftOpcodeExtension_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3ff)) << 49); +} + +static __inline tilegx_bundle_bits +create_ShiftOpcodeExtension_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3) << 18); +} + +static __inline tilegx_bundle_bits +create_ShiftOpcodeExtension_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3)) << 49); +} + +static __inline tilegx_bundle_bits +create_SrcA_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 6); +} + +static __inline tilegx_bundle_bits +create_SrcA_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 37); +} + +static __inline tilegx_bundle_bits +create_SrcA_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 6); +} + +static __inline tilegx_bundle_bits +create_SrcA_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 37); +} + +static __inline tilegx_bundle_bits +create_SrcA_Y2(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 20); +} + +static __inline tilegx_bundle_bits +create_SrcBDest_Y2(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 51); +} + +static __inline tilegx_bundle_bits +create_SrcB_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_SrcB_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +static __inline tilegx_bundle_bits +create_SrcB_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_SrcB_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +static __inline tilegx_bundle_bits +create_UnaryOpcodeExtension_X0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_UnaryOpcodeExtension_X1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +static __inline tilegx_bundle_bits +create_UnaryOpcodeExtension_Y0(int num) +{ + const unsigned int n = (unsigned int)num; + return ((n & 0x3f) << 12); +} + +static __inline tilegx_bundle_bits +create_UnaryOpcodeExtension_Y1(int num) +{ + const unsigned int n = (unsigned int)num; + return (((tilegx_bundle_bits)(n & 0x3f)) << 43); +} + +const struct tilegx_opcode tilegx_opcodes[336] = +{ + { "bpt", TILEGX_OPC_BPT, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffffffff80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a44ae00000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "info", TILEGX_OPC_INFO, 0xf, 1, TREG_ZERO, 1, + { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00fffULL, + 0xfff807ff80000000ULL, + 0x0000000078000fffULL, + 0x3c0007ff80000000ULL, + 0ULL + }, + { + 0x0000000040300fffULL, + 0x181807ff80000000ULL, + 0x0000000010000fffULL, + 0x0c0007ff80000000ULL, + -1ULL + } +#endif + }, + { "infol", TILEGX_OPC_INFOL, 0x3, 1, TREG_ZERO, 1, + { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc000000070000fffULL, + 0xf80007ff80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000070000fffULL, + 0x380007ff80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld4s_tls", TILEGX_OPC_LD4S_TLS, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1858000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld_tls", TILEGX_OPC_LD_TLS, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18a0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "move", TILEGX_OPC_MOVE, 0xf, 2, TREG_ZERO, 1, + { { 8, 9 }, { 6, 7 }, { 10, 11 }, { 12, 13 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0xfffff80000000000ULL, + 0x00000000780ff000ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + 0x000000005107f000ULL, + 0x283bf80000000000ULL, + 0x00000000500bf000ULL, + 0x2c05f80000000000ULL, + -1ULL + } +#endif + }, + { "movei", TILEGX_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1, + { { 8, 0 }, { 6, 1 }, { 10, 2 }, { 12, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00fc0ULL, + 0xfff807e000000000ULL, + 0x0000000078000fc0ULL, + 0x3c0007e000000000ULL, + 0ULL + }, + { + 0x0000000040100fc0ULL, + 0x180807e000000000ULL, + 0x0000000000000fc0ULL, + 0x040007e000000000ULL, + -1ULL + } +#endif + }, + { "moveli", TILEGX_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1, + { { 8, 4 }, { 6, 5 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc000000070000fc0ULL, + 0xf80007e000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000010000fc0ULL, + 0x000007e000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch", TILEGX_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a801f80000000ULL, + -1ULL, + -1ULL, + 0x41f8000004000000ULL + } +#endif + }, + { "prefetch_add_l1", TILEGX_OPC_PREFETCH_ADD_L1, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1840001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_add_l1_fault", TILEGX_OPC_PREFETCH_ADD_L1_FAULT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1838001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_add_l2", TILEGX_OPC_PREFETCH_ADD_L2, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1850001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_add_l2_fault", TILEGX_OPC_PREFETCH_ADD_L2_FAULT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1848001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_add_l3", TILEGX_OPC_PREFETCH_ADD_L3, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1860001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_add_l3_fault", TILEGX_OPC_PREFETCH_ADD_L3_FAULT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8001f80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1858001f80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "prefetch_l1", TILEGX_OPC_PREFETCH_L1, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a801f80000000ULL, + -1ULL, + -1ULL, + 0x41f8000004000000ULL + } +#endif + }, + { "prefetch_l1_fault", TILEGX_OPC_PREFETCH_L1_FAULT, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a781f80000000ULL, + -1ULL, + -1ULL, + 0x41f8000000000000ULL + } +#endif + }, + { "prefetch_l2", TILEGX_OPC_PREFETCH_L2, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a901f80000000ULL, + -1ULL, + -1ULL, + 0x43f8000004000000ULL + } +#endif + }, + { "prefetch_l2_fault", TILEGX_OPC_PREFETCH_L2_FAULT, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a881f80000000ULL, + -1ULL, + -1ULL, + 0x43f8000000000000ULL + } +#endif + }, + { "prefetch_l3", TILEGX_OPC_PREFETCH_L3, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286aa01f80000000ULL, + -1ULL, + -1ULL, + 0x83f8000000000000ULL + } +#endif + }, + { "prefetch_l3_fault", TILEGX_OPC_PREFETCH_L3_FAULT, 0x12, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff81f80000000ULL, + 0ULL, + 0ULL, + 0xc3f8000004000000ULL + }, + { + -1ULL, + 0x286a981f80000000ULL, + -1ULL, + -1ULL, + 0x81f8000004000000ULL + } +#endif + }, + { "raise", TILEGX_OPC_RAISE, 0x2, 0, TREG_ZERO, 1, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffffffff80000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a44ae80000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "add", TILEGX_OPC_ADD, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000500c0000ULL, + 0x2806000000000000ULL, + 0x0000000028040000ULL, + 0x1802000000000000ULL, + -1ULL + } +#endif + }, + { "addi", TILEGX_OPC_ADDI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0x0000000078000000ULL, + 0x3c00000000000000ULL, + 0ULL + }, + { + 0x0000000040100000ULL, + 0x1808000000000000ULL, + 0ULL, + 0x0400000000000000ULL, + -1ULL + } +#endif + }, + { "addli", TILEGX_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc000000070000000ULL, + 0xf800000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000010000000ULL, + 0ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "addx", TILEGX_OPC_ADDX, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050080000ULL, + 0x2804000000000000ULL, + 0x0000000028000000ULL, + 0x1800000000000000ULL, + -1ULL + } +#endif + }, + { "addxi", TILEGX_OPC_ADDXI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0x0000000078000000ULL, + 0x3c00000000000000ULL, + 0ULL + }, + { + 0x0000000040200000ULL, + 0x1810000000000000ULL, + 0x0000000008000000ULL, + 0x0800000000000000ULL, + -1ULL + } +#endif + }, + { "addxli", TILEGX_OPC_ADDXLI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc000000070000000ULL, + 0xf800000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000020000000ULL, + 0x0800000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "addxsc", TILEGX_OPC_ADDXSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050040000ULL, + 0x2802000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "and", TILEGX_OPC_AND, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050100000ULL, + 0x2808000000000000ULL, + 0x0000000050000000ULL, + 0x2c00000000000000ULL, + -1ULL + } +#endif + }, + { "andi", TILEGX_OPC_ANDI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0x0000000078000000ULL, + 0x3c00000000000000ULL, + 0ULL + }, + { + 0x0000000040300000ULL, + 0x1818000000000000ULL, + 0x0000000010000000ULL, + 0x0c00000000000000ULL, + -1ULL + } +#endif + }, + { "beqz", TILEGX_OPC_BEQZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1440000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "beqzt", TILEGX_OPC_BEQZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1400000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bfexts", TILEGX_OPC_BFEXTS, 0x1, 4, TREG_ZERO, 1, + { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007f000000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000034000000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bfextu", TILEGX_OPC_BFEXTU, 0x1, 4, TREG_ZERO, 1, + { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007f000000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000035000000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bfins", TILEGX_OPC_BFINS, 0x1, 4, TREG_ZERO, 1, + { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007f000000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000036000000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bgez", TILEGX_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x14c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bgezt", TILEGX_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1480000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bgtz", TILEGX_OPC_BGTZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1540000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bgtzt", TILEGX_OPC_BGTZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1500000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blbc", TILEGX_OPC_BLBC, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x15c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blbct", TILEGX_OPC_BLBCT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1580000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blbs", TILEGX_OPC_BLBS, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1640000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blbst", TILEGX_OPC_BLBST, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1600000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blez", TILEGX_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x16c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "blezt", TILEGX_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1680000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bltz", TILEGX_OPC_BLTZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1740000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bltzt", TILEGX_OPC_BLTZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1700000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bnez", TILEGX_OPC_BNEZ, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x17c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "bnezt", TILEGX_OPC_BNEZT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xffc0000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1780000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "clz", TILEGX_OPC_CLZ, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051481000ULL, + -1ULL, + 0x00000000300c1000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmoveqz", TILEGX_OPC_CMOVEQZ, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050140000ULL, + -1ULL, + 0x0000000048000000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmovnez", TILEGX_OPC_CMOVNEZ, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050180000ULL, + -1ULL, + 0x0000000048040000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmpeq", TILEGX_OPC_CMPEQ, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000501c0000ULL, + 0x280a000000000000ULL, + 0x0000000040000000ULL, + 0x2404000000000000ULL, + -1ULL + } +#endif + }, + { "cmpeqi", TILEGX_OPC_CMPEQI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0x0000000078000000ULL, + 0x3c00000000000000ULL, + 0ULL + }, + { + 0x0000000040400000ULL, + 0x1820000000000000ULL, + 0x0000000018000000ULL, + 0x1000000000000000ULL, + -1ULL + } +#endif + }, + { "cmpexch", TILEGX_OPC_CMPEXCH, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x280e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmpexch4", TILEGX_OPC_CMPEXCH4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x280c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmples", TILEGX_OPC_CMPLES, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050200000ULL, + 0x2810000000000000ULL, + 0x0000000038000000ULL, + 0x2000000000000000ULL, + -1ULL + } +#endif + }, + { "cmpleu", TILEGX_OPC_CMPLEU, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050240000ULL, + 0x2812000000000000ULL, + 0x0000000038040000ULL, + 0x2002000000000000ULL, + -1ULL + } +#endif + }, + { "cmplts", TILEGX_OPC_CMPLTS, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050280000ULL, + 0x2814000000000000ULL, + 0x0000000038080000ULL, + 0x2004000000000000ULL, + -1ULL + } +#endif + }, + { "cmpltsi", TILEGX_OPC_CMPLTSI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0x0000000078000000ULL, + 0x3c00000000000000ULL, + 0ULL + }, + { + 0x0000000040500000ULL, + 0x1828000000000000ULL, + 0x0000000020000000ULL, + 0x1400000000000000ULL, + -1ULL + } +#endif + }, + { "cmpltu", TILEGX_OPC_CMPLTU, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000502c0000ULL, + 0x2816000000000000ULL, + 0x00000000380c0000ULL, + 0x2006000000000000ULL, + -1ULL + } +#endif + }, + { "cmpltui", TILEGX_OPC_CMPLTUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040600000ULL, + 0x1830000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmpne", TILEGX_OPC_CMPNE, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050300000ULL, + 0x2818000000000000ULL, + 0x0000000040040000ULL, + 0x2406000000000000ULL, + -1ULL + } +#endif + }, + { "cmul", TILEGX_OPC_CMUL, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000504c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmula", TILEGX_OPC_CMULA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050380000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmulaf", TILEGX_OPC_CMULAF, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050340000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmulf", TILEGX_OPC_CMULF, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050400000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmulfr", TILEGX_OPC_CMULFR, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000503c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmulh", TILEGX_OPC_CMULH, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050480000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "cmulhr", TILEGX_OPC_CMULHR, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050440000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "crc32_32", TILEGX_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050500000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "crc32_8", TILEGX_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050540000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ctz", TILEGX_OPC_CTZ, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051482000ULL, + -1ULL, + 0x00000000300c2000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "dblalign", TILEGX_OPC_DBLALIGN, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050640000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "dblalign2", TILEGX_OPC_DBLALIGN2, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050580000ULL, + 0x281a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "dblalign4", TILEGX_OPC_DBLALIGN4, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000505c0000ULL, + 0x281c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "dblalign6", TILEGX_OPC_DBLALIGN6, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050600000ULL, + 0x281e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "drain", TILEGX_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a080000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "dtlbpr", TILEGX_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a100000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "exch", TILEGX_OPC_EXCH, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2822000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "exch4", TILEGX_OPC_EXCH4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2820000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_add_flags", TILEGX_OPC_FDOUBLE_ADD_FLAGS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000506c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_addsub", TILEGX_OPC_FDOUBLE_ADDSUB, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050680000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_mul_flags", TILEGX_OPC_FDOUBLE_MUL_FLAGS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050700000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_pack1", TILEGX_OPC_FDOUBLE_PACK1, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050740000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_pack2", TILEGX_OPC_FDOUBLE_PACK2, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050780000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_sub_flags", TILEGX_OPC_FDOUBLE_SUB_FLAGS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000507c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_unpack_max", TILEGX_OPC_FDOUBLE_UNPACK_MAX, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050800000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fdouble_unpack_min", TILEGX_OPC_FDOUBLE_UNPACK_MIN, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050840000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchadd", TILEGX_OPC_FETCHADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x282a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchadd4", TILEGX_OPC_FETCHADD4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2824000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchaddgez", TILEGX_OPC_FETCHADDGEZ, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2828000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchaddgez4", TILEGX_OPC_FETCHADDGEZ4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2826000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchand", TILEGX_OPC_FETCHAND, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x282e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchand4", TILEGX_OPC_FETCHAND4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x282c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchor", TILEGX_OPC_FETCHOR, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2832000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fetchor4", TILEGX_OPC_FETCHOR4, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2830000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "finv", TILEGX_OPC_FINV, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a180000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "flush", TILEGX_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a280000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "flushwb", TILEGX_OPC_FLUSHWB, 0x2, 0, TREG_ZERO, 1, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a200000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fnop", TILEGX_OPC_FNOP, 0xf, 0, TREG_ZERO, 1, + { { }, { }, { }, { }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0xfffff80000000000ULL, + 0x00000000780ff000ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + 0x0000000051483000ULL, + 0x286a300000000000ULL, + 0x00000000300c3000ULL, + 0x1c06400000000000ULL, + -1ULL + } +#endif + }, + { "fsingle_add1", TILEGX_OPC_FSINGLE_ADD1, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050880000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_addsub2", TILEGX_OPC_FSINGLE_ADDSUB2, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000508c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_mul1", TILEGX_OPC_FSINGLE_MUL1, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050900000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_mul2", TILEGX_OPC_FSINGLE_MUL2, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050940000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_pack1", TILEGX_OPC_FSINGLE_PACK1, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051484000ULL, + -1ULL, + 0x00000000300c4000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_pack2", TILEGX_OPC_FSINGLE_PACK2, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050980000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "fsingle_sub1", TILEGX_OPC_FSINGLE_SUB1, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000509c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "icoh", TILEGX_OPC_ICOH, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a380000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ill", TILEGX_OPC_ILL, 0xa, 0, TREG_ZERO, 1, + { { 0, }, { }, { 0, }, { }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286a400000000000ULL, + -1ULL, + 0x1c06480000000000ULL, + -1ULL + } +#endif + }, + { "inv", TILEGX_OPC_INV, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a480000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "iret", TILEGX_OPC_IRET, 0x2, 0, TREG_ZERO, 1, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286a500000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "j", TILEGX_OPC_J, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfc00000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2400000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "jal", TILEGX_OPC_JAL, 0x2, 1, TREG_LR, 1, + { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfc00000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2000000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "jalr", TILEGX_OPC_JALR, 0xa, 1, TREG_LR, 1, + { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286a600000000000ULL, + -1ULL, + 0x1c06580000000000ULL, + -1ULL + } +#endif + }, + { "jalrp", TILEGX_OPC_JALRP, 0xa, 1, TREG_LR, 1, + { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286a580000000000ULL, + -1ULL, + 0x1c06500000000000ULL, + -1ULL + } +#endif + }, + { "jr", TILEGX_OPC_JR, 0xa, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286a700000000000ULL, + -1ULL, + 0x1c06680000000000ULL, + -1ULL + } +#endif + }, + { "jrp", TILEGX_OPC_JRP, 0xa, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286a680000000000ULL, + -1ULL, + 0x1c06600000000000ULL, + -1ULL + } +#endif + }, + { "ld", TILEGX_OPC_LD, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286ae80000000000ULL, + -1ULL, + -1ULL, + 0x8200000004000000ULL + } +#endif + }, + { "ld1s", TILEGX_OPC_LD1S, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286a780000000000ULL, + -1ULL, + -1ULL, + 0x4000000000000000ULL + } +#endif + }, + { "ld1s_add", TILEGX_OPC_LD1S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1838000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld1u", TILEGX_OPC_LD1U, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286a800000000000ULL, + -1ULL, + -1ULL, + 0x4000000004000000ULL + } +#endif + }, + { "ld1u_add", TILEGX_OPC_LD1U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1840000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld2s", TILEGX_OPC_LD2S, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286a880000000000ULL, + -1ULL, + -1ULL, + 0x4200000000000000ULL + } +#endif + }, + { "ld2s_add", TILEGX_OPC_LD2S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1848000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld2u", TILEGX_OPC_LD2U, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286a900000000000ULL, + -1ULL, + -1ULL, + 0x4200000004000000ULL + } +#endif + }, + { "ld2u_add", TILEGX_OPC_LD2U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1850000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld4s", TILEGX_OPC_LD4S, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286a980000000000ULL, + -1ULL, + -1ULL, + 0x8000000004000000ULL + } +#endif + }, + { "ld4s_add", TILEGX_OPC_LD4S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1858000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld4u", TILEGX_OPC_LD4U, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x286aa00000000000ULL, + -1ULL, + -1ULL, + 0x8200000000000000ULL + } +#endif + }, + { "ld4u_add", TILEGX_OPC_LD4U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1860000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ld_add", TILEGX_OPC_LD_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18a0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldna", TILEGX_OPC_LDNA, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286aa80000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldna_add", TILEGX_OPC_LDNA_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18a8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt", TILEGX_OPC_LDNT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ae00000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt1s", TILEGX_OPC_LDNT1S, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ab00000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt1s_add", TILEGX_OPC_LDNT1S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1868000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt1u", TILEGX_OPC_LDNT1U, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ab80000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt1u_add", TILEGX_OPC_LDNT1U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1870000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt2s", TILEGX_OPC_LDNT2S, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ac00000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt2s_add", TILEGX_OPC_LDNT2S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1878000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt2u", TILEGX_OPC_LDNT2U, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ac80000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt2u_add", TILEGX_OPC_LDNT2U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1880000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt4s", TILEGX_OPC_LDNT4S, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ad00000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt4s_add", TILEGX_OPC_LDNT4S_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1888000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt4u", TILEGX_OPC_LDNT4U, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286ad80000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt4u_add", TILEGX_OPC_LDNT4U_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1890000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "ldnt_add", TILEGX_OPC_LDNT_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1898000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "lnk", TILEGX_OPC_LNK, 0xa, 1, TREG_ZERO, 1, + { { 0, }, { 6 }, { 0, }, { 12 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + -1ULL, + 0x286af00000000000ULL, + -1ULL, + 0x1c06700000000000ULL, + -1ULL + } +#endif + }, + { "mf", TILEGX_OPC_MF, 0x2, 0, TREG_ZERO, 1, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286af80000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mfspr", TILEGX_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 6, 27 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18b0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mm", TILEGX_OPC_MM, 0x1, 4, TREG_ZERO, 1, + { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007f000000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000037000000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mnz", TILEGX_OPC_MNZ, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050a00000ULL, + 0x2834000000000000ULL, + 0x0000000048080000ULL, + 0x2804000000000000ULL, + -1ULL + } +#endif + }, + { "mtspr", TILEGX_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 28, 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18b8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hs_hs", TILEGX_OPC_MUL_HS_HS, 0x5, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050d40000ULL, + -1ULL, + 0x0000000068000000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hs_hu", TILEGX_OPC_MUL_HS_HU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050d80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hs_ls", TILEGX_OPC_MUL_HS_LS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050dc0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hs_lu", TILEGX_OPC_MUL_HS_LU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050e00000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hu_hu", TILEGX_OPC_MUL_HU_HU, 0x5, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050e40000ULL, + -1ULL, + 0x0000000068040000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hu_ls", TILEGX_OPC_MUL_HU_LS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050e80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_hu_lu", TILEGX_OPC_MUL_HU_LU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050ec0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_ls_ls", TILEGX_OPC_MUL_LS_LS, 0x5, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050f00000ULL, + -1ULL, + 0x0000000068080000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_ls_lu", TILEGX_OPC_MUL_LS_LU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050f40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mul_lu_lu", TILEGX_OPC_MUL_LU_LU, 0x5, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050f80000ULL, + -1ULL, + 0x00000000680c0000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hs_hs", TILEGX_OPC_MULA_HS_HS, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050a80000ULL, + -1ULL, + 0x0000000070000000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hs_hu", TILEGX_OPC_MULA_HS_HU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050ac0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hs_ls", TILEGX_OPC_MULA_HS_LS, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050b00000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hs_lu", TILEGX_OPC_MULA_HS_LU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050b40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hu_hu", TILEGX_OPC_MULA_HU_HU, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050b80000ULL, + -1ULL, + 0x0000000070040000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hu_ls", TILEGX_OPC_MULA_HU_LS, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050bc0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_hu_lu", TILEGX_OPC_MULA_HU_LU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050c00000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_ls_ls", TILEGX_OPC_MULA_LS_LS, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050c40000ULL, + -1ULL, + 0x0000000070080000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_ls_lu", TILEGX_OPC_MULA_LS_LU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050c80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mula_lu_lu", TILEGX_OPC_MULA_LU_LU, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050cc0000ULL, + -1ULL, + 0x00000000700c0000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mulax", TILEGX_OPC_MULAX, 0x5, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050a40000ULL, + -1ULL, + 0x0000000040080000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mulx", TILEGX_OPC_MULX, 0x5, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0x00000000780c0000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000050d00000ULL, + -1ULL, + 0x00000000400c0000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "mz", TILEGX_OPC_MZ, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000050fc0000ULL, + 0x2836000000000000ULL, + 0x00000000480c0000ULL, + 0x2806000000000000ULL, + -1ULL + } +#endif + }, + { "nap", TILEGX_OPC_NAP, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "nop", TILEGX_OPC_NOP, 0xf, 0, TREG_ZERO, 1, + { { }, { }, { }, { }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0xfffff80000000000ULL, + 0x00000000780ff000ULL, + 0x3c07f80000000000ULL, + 0ULL + }, + { + 0x0000000051485000ULL, + 0x286b080000000000ULL, + 0x00000000300c5000ULL, + 0x1c06780000000000ULL, + -1ULL + } +#endif + }, + { "nor", TILEGX_OPC_NOR, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051000000ULL, + 0x2838000000000000ULL, + 0x0000000050040000ULL, + 0x2c02000000000000ULL, + -1ULL + } +#endif + }, + { "or", TILEGX_OPC_OR, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051040000ULL, + 0x283a000000000000ULL, + 0x0000000050080000ULL, + 0x2c04000000000000ULL, + -1ULL + } +#endif + }, + { "ori", TILEGX_OPC_ORI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040700000ULL, + 0x18c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "pcnt", TILEGX_OPC_PCNT, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051486000ULL, + -1ULL, + 0x00000000300c6000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "revbits", TILEGX_OPC_REVBITS, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051487000ULL, + -1ULL, + 0x00000000300c7000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "revbytes", TILEGX_OPC_REVBYTES, 0x5, 2, TREG_ZERO, 1, + { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051488000ULL, + -1ULL, + 0x00000000300c8000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "rotl", TILEGX_OPC_ROTL, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051080000ULL, + 0x283c000000000000ULL, + 0x0000000058000000ULL, + 0x3000000000000000ULL, + -1ULL + } +#endif + }, + { "rotli", TILEGX_OPC_ROTLI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000060040000ULL, + 0x3002000000000000ULL, + 0x0000000078000000ULL, + 0x3800000000000000ULL, + -1ULL + } +#endif + }, + { "shl", TILEGX_OPC_SHL, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051280000ULL, + 0x284c000000000000ULL, + 0x0000000058040000ULL, + 0x3002000000000000ULL, + -1ULL + } +#endif + }, + { "shl16insli", TILEGX_OPC_SHL16INSLI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc000000070000000ULL, + 0xf800000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000070000000ULL, + 0x3800000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "shl1add", TILEGX_OPC_SHL1ADD, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051100000ULL, + 0x2840000000000000ULL, + 0x0000000030000000ULL, + 0x1c00000000000000ULL, + -1ULL + } +#endif + }, + { "shl1addx", TILEGX_OPC_SHL1ADDX, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000510c0000ULL, + 0x283e000000000000ULL, + 0x0000000060040000ULL, + 0x3402000000000000ULL, + -1ULL + } +#endif + }, + { "shl2add", TILEGX_OPC_SHL2ADD, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051180000ULL, + 0x2844000000000000ULL, + 0x0000000030040000ULL, + 0x1c02000000000000ULL, + -1ULL + } +#endif + }, + { "shl2addx", TILEGX_OPC_SHL2ADDX, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051140000ULL, + 0x2842000000000000ULL, + 0x0000000060080000ULL, + 0x3404000000000000ULL, + -1ULL + } +#endif + }, + { "shl3add", TILEGX_OPC_SHL3ADD, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051200000ULL, + 0x2848000000000000ULL, + 0x0000000030080000ULL, + 0x1c04000000000000ULL, + -1ULL + } +#endif + }, + { "shl3addx", TILEGX_OPC_SHL3ADDX, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000511c0000ULL, + 0x2846000000000000ULL, + 0x00000000600c0000ULL, + 0x3406000000000000ULL, + -1ULL + } +#endif + }, + { "shli", TILEGX_OPC_SHLI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000060080000ULL, + 0x3004000000000000ULL, + 0x0000000078040000ULL, + 0x3802000000000000ULL, + -1ULL + } +#endif + }, + { "shlx", TILEGX_OPC_SHLX, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051240000ULL, + 0x284a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "shlxi", TILEGX_OPC_SHLXI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000600c0000ULL, + 0x3006000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "shrs", TILEGX_OPC_SHRS, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x00000000512c0000ULL, + 0x284e000000000000ULL, + 0x0000000058080000ULL, + 0x3004000000000000ULL, + -1ULL + } +#endif + }, + { "shrsi", TILEGX_OPC_SHRSI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000060100000ULL, + 0x3008000000000000ULL, + 0x0000000078080000ULL, + 0x3804000000000000ULL, + -1ULL + } +#endif + }, + { "shru", TILEGX_OPC_SHRU, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051340000ULL, + 0x2852000000000000ULL, + 0x00000000580c0000ULL, + 0x3006000000000000ULL, + -1ULL + } +#endif + }, + { "shrui", TILEGX_OPC_SHRUI, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000060140000ULL, + 0x300a000000000000ULL, + 0x00000000780c0000ULL, + 0x3806000000000000ULL, + -1ULL + } +#endif + }, + { "shrux", TILEGX_OPC_SHRUX, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051300000ULL, + 0x2850000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "shruxi", TILEGX_OPC_SHRUXI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000060180000ULL, + 0x300c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "shufflebytes", TILEGX_OPC_SHUFFLEBYTES, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051380000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "st", TILEGX_OPC_ST, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x2862000000000000ULL, + -1ULL, + -1ULL, + 0xc200000004000000ULL + } +#endif + }, + { "st1", TILEGX_OPC_ST1, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x2854000000000000ULL, + -1ULL, + -1ULL, + 0xc000000000000000ULL + } +#endif + }, + { "st1_add", TILEGX_OPC_ST1_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18c8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "st2", TILEGX_OPC_ST2, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x2856000000000000ULL, + -1ULL, + -1ULL, + 0xc000000004000000ULL + } +#endif + }, + { "st2_add", TILEGX_OPC_ST2_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18d0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "st4", TILEGX_OPC_ST4, 0x12, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0xc200000004000000ULL + }, + { + -1ULL, + 0x2858000000000000ULL, + -1ULL, + -1ULL, + 0xc200000000000000ULL + } +#endif + }, + { "st4_add", TILEGX_OPC_ST4_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18d8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "st_add", TILEGX_OPC_ST_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x1900000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt", TILEGX_OPC_STNT, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x2860000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt1", TILEGX_OPC_STNT1, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x285a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt1_add", TILEGX_OPC_STNT1_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18e0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt2", TILEGX_OPC_STNT2, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x285c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt2_add", TILEGX_OPC_STNT2_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18e8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt4", TILEGX_OPC_STNT4, 0x2, 2, TREG_ZERO, 1, + { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x285e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt4_add", TILEGX_OPC_STNT4_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18f0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "stnt_add", TILEGX_OPC_STNT_ADD, 0x2, 3, TREG_ZERO, 1, + { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x18f8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "sub", TILEGX_OPC_SUB, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051440000ULL, + 0x2868000000000000ULL, + 0x00000000280c0000ULL, + 0x1806000000000000ULL, + -1ULL + } +#endif + }, + { "subx", TILEGX_OPC_SUBX, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000051400000ULL, + 0x2866000000000000ULL, + 0x0000000028080000ULL, + 0x1804000000000000ULL, + -1ULL + } +#endif + }, + { "subxsc", TILEGX_OPC_SUBXSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000513c0000ULL, + 0x2864000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "swint0", TILEGX_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b100000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "swint1", TILEGX_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b180000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "swint2", TILEGX_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b200000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "swint3", TILEGX_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0, + { { 0, }, { }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b280000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "tblidxb0", TILEGX_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1, + { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051489000ULL, + -1ULL, + 0x00000000300c9000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "tblidxb1", TILEGX_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1, + { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x000000005148a000ULL, + -1ULL, + 0x00000000300ca000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "tblidxb2", TILEGX_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1, + { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x000000005148b000ULL, + -1ULL, + 0x00000000300cb000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "tblidxb3", TILEGX_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1, + { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffff000ULL, + 0ULL, + 0x00000000780ff000ULL, + 0ULL, + 0ULL + }, + { + 0x000000005148c000ULL, + -1ULL, + 0x00000000300cc000ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1add", TILEGX_OPC_V1ADD, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051500000ULL, + 0x286e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1addi", TILEGX_OPC_V1ADDI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040800000ULL, + 0x1908000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1adduc", TILEGX_OPC_V1ADDUC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000514c0000ULL, + 0x286c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1adiffu", TILEGX_OPC_V1ADIFFU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051540000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1avgu", TILEGX_OPC_V1AVGU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051580000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpeq", TILEGX_OPC_V1CMPEQ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000515c0000ULL, + 0x2870000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpeqi", TILEGX_OPC_V1CMPEQI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040900000ULL, + 0x1910000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmples", TILEGX_OPC_V1CMPLES, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051600000ULL, + 0x2872000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpleu", TILEGX_OPC_V1CMPLEU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051640000ULL, + 0x2874000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmplts", TILEGX_OPC_V1CMPLTS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051680000ULL, + 0x2876000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpltsi", TILEGX_OPC_V1CMPLTSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040a00000ULL, + 0x1918000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpltu", TILEGX_OPC_V1CMPLTU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000516c0000ULL, + 0x2878000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpltui", TILEGX_OPC_V1CMPLTUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040b00000ULL, + 0x1920000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1cmpne", TILEGX_OPC_V1CMPNE, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051700000ULL, + 0x287a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1ddotpu", TILEGX_OPC_V1DDOTPU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052880000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1ddotpua", TILEGX_OPC_V1DDOTPUA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052840000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1ddotpus", TILEGX_OPC_V1DDOTPUS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051780000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1ddotpusa", TILEGX_OPC_V1DDOTPUSA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051740000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotp", TILEGX_OPC_V1DOTP, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051880000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotpa", TILEGX_OPC_V1DOTPA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000517c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotpu", TILEGX_OPC_V1DOTPU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052900000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotpua", TILEGX_OPC_V1DOTPUA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000528c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotpus", TILEGX_OPC_V1DOTPUS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051840000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1dotpusa", TILEGX_OPC_V1DOTPUSA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051800000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1int_h", TILEGX_OPC_V1INT_H, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000518c0000ULL, + 0x287c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1int_l", TILEGX_OPC_V1INT_L, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051900000ULL, + 0x287e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1maxu", TILEGX_OPC_V1MAXU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051940000ULL, + 0x2880000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1maxui", TILEGX_OPC_V1MAXUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040c00000ULL, + 0x1928000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1minu", TILEGX_OPC_V1MINU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051980000ULL, + 0x2882000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1minui", TILEGX_OPC_V1MINUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040d00000ULL, + 0x1930000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1mnz", TILEGX_OPC_V1MNZ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000519c0000ULL, + 0x2884000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1multu", TILEGX_OPC_V1MULTU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051a00000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1mulu", TILEGX_OPC_V1MULU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051a80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1mulus", TILEGX_OPC_V1MULUS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051a40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1mz", TILEGX_OPC_V1MZ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051ac0000ULL, + 0x2886000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1sadau", TILEGX_OPC_V1SADAU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051b00000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1sadu", TILEGX_OPC_V1SADU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051b40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shl", TILEGX_OPC_V1SHL, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051b80000ULL, + 0x2888000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shli", TILEGX_OPC_V1SHLI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000601c0000ULL, + 0x300e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shrs", TILEGX_OPC_V1SHRS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051bc0000ULL, + 0x288a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shrsi", TILEGX_OPC_V1SHRSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000060200000ULL, + 0x3010000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shru", TILEGX_OPC_V1SHRU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051c00000ULL, + 0x288c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1shrui", TILEGX_OPC_V1SHRUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000060240000ULL, + 0x3012000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1sub", TILEGX_OPC_V1SUB, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051c80000ULL, + 0x2890000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v1subuc", TILEGX_OPC_V1SUBUC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051c40000ULL, + 0x288e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2add", TILEGX_OPC_V2ADD, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051d00000ULL, + 0x2894000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2addi", TILEGX_OPC_V2ADDI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040e00000ULL, + 0x1938000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2addsc", TILEGX_OPC_V2ADDSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051cc0000ULL, + 0x2892000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2adiffs", TILEGX_OPC_V2ADIFFS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051d40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2avgs", TILEGX_OPC_V2AVGS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051d80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpeq", TILEGX_OPC_V2CMPEQ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051dc0000ULL, + 0x2896000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpeqi", TILEGX_OPC_V2CMPEQI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000040f00000ULL, + 0x1940000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmples", TILEGX_OPC_V2CMPLES, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051e00000ULL, + 0x2898000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpleu", TILEGX_OPC_V2CMPLEU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051e40000ULL, + 0x289a000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmplts", TILEGX_OPC_V2CMPLTS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051e80000ULL, + 0x289c000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpltsi", TILEGX_OPC_V2CMPLTSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000041000000ULL, + 0x1948000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpltu", TILEGX_OPC_V2CMPLTU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051ec0000ULL, + 0x289e000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpltui", TILEGX_OPC_V2CMPLTUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000041100000ULL, + 0x1950000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2cmpne", TILEGX_OPC_V2CMPNE, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051f00000ULL, + 0x28a0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2dotp", TILEGX_OPC_V2DOTP, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051f80000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2dotpa", TILEGX_OPC_V2DOTPA, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051f40000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2int_h", TILEGX_OPC_V2INT_H, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000051fc0000ULL, + 0x28a2000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2int_l", TILEGX_OPC_V2INT_L, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052000000ULL, + 0x28a4000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2maxs", TILEGX_OPC_V2MAXS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052040000ULL, + 0x28a6000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2maxsi", TILEGX_OPC_V2MAXSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000041200000ULL, + 0x1958000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2mins", TILEGX_OPC_V2MINS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052080000ULL, + 0x28a8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2minsi", TILEGX_OPC_V2MINSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000041300000ULL, + 0x1960000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2mnz", TILEGX_OPC_V2MNZ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000520c0000ULL, + 0x28aa000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2mulfsc", TILEGX_OPC_V2MULFSC, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052100000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2muls", TILEGX_OPC_V2MULS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052140000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2mults", TILEGX_OPC_V2MULTS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052180000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2mz", TILEGX_OPC_V2MZ, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000521c0000ULL, + 0x28ac000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2packh", TILEGX_OPC_V2PACKH, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052200000ULL, + 0x28ae000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2packl", TILEGX_OPC_V2PACKL, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052240000ULL, + 0x28b0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2packuc", TILEGX_OPC_V2PACKUC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052280000ULL, + 0x28b2000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2sadas", TILEGX_OPC_V2SADAS, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000522c0000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2sadau", TILEGX_OPC_V2SADAU, 0x1, 3, TREG_ZERO, 1, + { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052300000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2sads", TILEGX_OPC_V2SADS, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052340000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2sadu", TILEGX_OPC_V2SADU, 0x1, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052380000ULL, + -1ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shl", TILEGX_OPC_V2SHL, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052400000ULL, + 0x28b6000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shli", TILEGX_OPC_V2SHLI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000060280000ULL, + 0x3014000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shlsc", TILEGX_OPC_V2SHLSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000523c0000ULL, + 0x28b4000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shrs", TILEGX_OPC_V2SHRS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052440000ULL, + 0x28b8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shrsi", TILEGX_OPC_V2SHRSI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000602c0000ULL, + 0x3016000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shru", TILEGX_OPC_V2SHRU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052480000ULL, + 0x28ba000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2shrui", TILEGX_OPC_V2SHRUI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000060300000ULL, + 0x3018000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2sub", TILEGX_OPC_V2SUB, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052500000ULL, + 0x28be000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v2subsc", TILEGX_OPC_V2SUBSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000524c0000ULL, + 0x28bc000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4add", TILEGX_OPC_V4ADD, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052580000ULL, + 0x28c2000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4addsc", TILEGX_OPC_V4ADDSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052540000ULL, + 0x28c0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4int_h", TILEGX_OPC_V4INT_H, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000525c0000ULL, + 0x28c4000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4int_l", TILEGX_OPC_V4INT_L, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052600000ULL, + 0x28c6000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4packsc", TILEGX_OPC_V4PACKSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052640000ULL, + 0x28c8000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4shl", TILEGX_OPC_V4SHL, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000526c0000ULL, + 0x28cc000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4shlsc", TILEGX_OPC_V4SHLSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052680000ULL, + 0x28ca000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4shrs", TILEGX_OPC_V4SHRS, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052700000ULL, + 0x28ce000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4shru", TILEGX_OPC_V4SHRU, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052740000ULL, + 0x28d0000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4sub", TILEGX_OPC_V4SUB, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x00000000527c0000ULL, + 0x28d4000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "v4subsc", TILEGX_OPC_V4SUBSC, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000052780000ULL, + 0x28d2000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "wh64", TILEGX_OPC_WH64, 0x2, 1, TREG_ZERO, 1, + { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0ULL, + 0xfffff80000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + -1ULL, + 0x286b300000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { "xor", TILEGX_OPC_XOR, 0xf, 3, TREG_ZERO, 1, + { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ffc0000ULL, + 0xfffe000000000000ULL, + 0x00000000780c0000ULL, + 0x3c06000000000000ULL, + 0ULL + }, + { + 0x0000000052800000ULL, + 0x28d6000000000000ULL, + 0x00000000500c0000ULL, + 0x2c06000000000000ULL, + -1ULL + } +#endif + }, + { "xori", TILEGX_OPC_XORI, 0x3, 3, TREG_ZERO, 1, + { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } }, +#ifndef DISASM_ONLY + { + 0xc00000007ff00000ULL, + 0xfff8000000000000ULL, + 0ULL, + 0ULL, + 0ULL + }, + { + 0x0000000041400000ULL, + 0x1968000000000000ULL, + -1ULL, + -1ULL, + -1ULL + } +#endif + }, + { NULL, TILEGX_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } }, +#ifndef DISASM_ONLY + { 0, }, { 0, } +#endif + } +}; + +#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6)) +#define CHILD(array_index) (TILEGX_OPC_NONE + (array_index)) + +static const unsigned short decode_X0_fsm[936] = +{ + BITFIELD(22, 9) /* index 0 */, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BFEXTS, + TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTU, + TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFINS, + TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_MM, + TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(528), CHILD(578), + CHILD(583), CHILD(588), CHILD(593), CHILD(598), TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, CHILD(603), CHILD(620), CHILD(637), CHILD(654), CHILD(671), + CHILD(703), CHILD(797), CHILD(814), CHILD(831), CHILD(848), CHILD(865), + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, CHILD(889), TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), + BITFIELD(6, 2) /* index 513 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518), + BITFIELD(8, 2) /* index 518 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523), + BITFIELD(10, 2) /* index 523 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI, + BITFIELD(20, 2) /* index 528 */, + TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548), + BITFIELD(6, 2) /* index 533 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538), + BITFIELD(8, 2) /* index 538 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543), + BITFIELD(10, 2) /* index 543 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, + BITFIELD(0, 2) /* index 548 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553), + BITFIELD(2, 2) /* index 553 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558), + BITFIELD(4, 2) /* index 558 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563), + BITFIELD(6, 2) /* index 563 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568), + BITFIELD(8, 2) /* index 568 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573), + BITFIELD(10, 2) /* index 573 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, + BITFIELD(20, 2) /* index 578 */, + TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, TILEGX_OPC_ORI, + BITFIELD(20, 2) /* index 583 */, + TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, TILEGX_OPC_V1CMPLTSI, + TILEGX_OPC_V1CMPLTUI, + BITFIELD(20, 2) /* index 588 */, + TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, TILEGX_OPC_V2ADDI, + TILEGX_OPC_V2CMPEQI, + BITFIELD(20, 2) /* index 593 */, + TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, TILEGX_OPC_V2MAXSI, + TILEGX_OPC_V2MINSI, + BITFIELD(20, 2) /* index 598 */, + TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(18, 4) /* index 603 */, + TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD, + TILEGX_OPC_AND, TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_CMPEQ, + TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, + TILEGX_OPC_CMPNE, TILEGX_OPC_CMULAF, TILEGX_OPC_CMULA, TILEGX_OPC_CMULFR, + BITFIELD(18, 4) /* index 620 */, + TILEGX_OPC_CMULF, TILEGX_OPC_CMULHR, TILEGX_OPC_CMULH, TILEGX_OPC_CMUL, + TILEGX_OPC_CRC32_32, TILEGX_OPC_CRC32_8, TILEGX_OPC_DBLALIGN2, + TILEGX_OPC_DBLALIGN4, TILEGX_OPC_DBLALIGN6, TILEGX_OPC_DBLALIGN, + TILEGX_OPC_FDOUBLE_ADDSUB, TILEGX_OPC_FDOUBLE_ADD_FLAGS, + TILEGX_OPC_FDOUBLE_MUL_FLAGS, TILEGX_OPC_FDOUBLE_PACK1, + TILEGX_OPC_FDOUBLE_PACK2, TILEGX_OPC_FDOUBLE_SUB_FLAGS, + BITFIELD(18, 4) /* index 637 */, + TILEGX_OPC_FDOUBLE_UNPACK_MAX, TILEGX_OPC_FDOUBLE_UNPACK_MIN, + TILEGX_OPC_FSINGLE_ADD1, TILEGX_OPC_FSINGLE_ADDSUB2, + TILEGX_OPC_FSINGLE_MUL1, TILEGX_OPC_FSINGLE_MUL2, TILEGX_OPC_FSINGLE_PACK2, + TILEGX_OPC_FSINGLE_SUB1, TILEGX_OPC_MNZ, TILEGX_OPC_MULAX, + TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HS_HU, TILEGX_OPC_MULA_HS_LS, + TILEGX_OPC_MULA_HS_LU, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_HU_LS, + BITFIELD(18, 4) /* index 654 */, + TILEGX_OPC_MULA_HU_LU, TILEGX_OPC_MULA_LS_LS, TILEGX_OPC_MULA_LS_LU, + TILEGX_OPC_MULA_LU_LU, TILEGX_OPC_MULX, TILEGX_OPC_MUL_HS_HS, + TILEGX_OPC_MUL_HS_HU, TILEGX_OPC_MUL_HS_LS, TILEGX_OPC_MUL_HS_LU, + TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_HU_LS, TILEGX_OPC_MUL_HU_LU, + TILEGX_OPC_MUL_LS_LS, TILEGX_OPC_MUL_LS_LU, TILEGX_OPC_MUL_LU_LU, + TILEGX_OPC_MZ, + BITFIELD(18, 4) /* index 671 */, + TILEGX_OPC_NOR, CHILD(688), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL, + TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_SHUFFLEBYTES, + TILEGX_OPC_SUBXSC, + BITFIELD(12, 2) /* index 688 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(693), + BITFIELD(14, 2) /* index 693 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(698), + BITFIELD(16, 2) /* index 698 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, + BITFIELD(18, 4) /* index 703 */, + TILEGX_OPC_SUBX, TILEGX_OPC_SUB, CHILD(720), TILEGX_OPC_V1ADDUC, + TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADIFFU, TILEGX_OPC_V1AVGU, + TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU, + TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE, + TILEGX_OPC_V1DDOTPUSA, TILEGX_OPC_V1DDOTPUS, TILEGX_OPC_V1DOTPA, + BITFIELD(12, 4) /* index 720 */, + TILEGX_OPC_NONE, CHILD(737), CHILD(742), CHILD(747), CHILD(752), CHILD(757), + CHILD(762), CHILD(767), CHILD(772), CHILD(777), CHILD(782), CHILD(787), + CHILD(792), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 737 */, + TILEGX_OPC_CLZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 742 */, + TILEGX_OPC_CTZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 747 */, + TILEGX_OPC_FNOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 752 */, + TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 757 */, + TILEGX_OPC_NOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 762 */, + TILEGX_OPC_PCNT, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 767 */, + TILEGX_OPC_REVBITS, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 772 */, + TILEGX_OPC_REVBYTES, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 777 */, + TILEGX_OPC_TBLIDXB0, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 782 */, + TILEGX_OPC_TBLIDXB1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 787 */, + TILEGX_OPC_TBLIDXB2, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(16, 2) /* index 792 */, + TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(18, 4) /* index 797 */, + TILEGX_OPC_V1DOTPUSA, TILEGX_OPC_V1DOTPUS, TILEGX_OPC_V1DOTP, + TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1MAXU, + TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MULTU, TILEGX_OPC_V1MULUS, + TILEGX_OPC_V1MULU, TILEGX_OPC_V1MZ, TILEGX_OPC_V1SADAU, TILEGX_OPC_V1SADU, + TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, + BITFIELD(18, 4) /* index 814 */, + TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, + TILEGX_OPC_V2ADD, TILEGX_OPC_V2ADIFFS, TILEGX_OPC_V2AVGS, + TILEGX_OPC_V2CMPEQ, TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, + TILEGX_OPC_V2CMPLTS, TILEGX_OPC_V2CMPLTU, TILEGX_OPC_V2CMPNE, + TILEGX_OPC_V2DOTPA, TILEGX_OPC_V2DOTP, TILEGX_OPC_V2INT_H, + BITFIELD(18, 4) /* index 831 */, + TILEGX_OPC_V2INT_L, TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, + TILEGX_OPC_V2MULFSC, TILEGX_OPC_V2MULS, TILEGX_OPC_V2MULTS, TILEGX_OPC_V2MZ, + TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC, + TILEGX_OPC_V2SADAS, TILEGX_OPC_V2SADAU, TILEGX_OPC_V2SADS, + TILEGX_OPC_V2SADU, TILEGX_OPC_V2SHLSC, + BITFIELD(18, 4) /* index 848 */, + TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, TILEGX_OPC_V2SUBSC, + TILEGX_OPC_V2SUB, TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H, + TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC, + TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC, + TILEGX_OPC_V4SUB, + BITFIELD(18, 3) /* index 865 */, + CHILD(874), CHILD(877), CHILD(880), CHILD(883), CHILD(886), TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(21, 1) /* index 874 */, + TILEGX_OPC_XOR, TILEGX_OPC_NONE, + BITFIELD(21, 1) /* index 877 */, + TILEGX_OPC_V1DDOTPUA, TILEGX_OPC_NONE, + BITFIELD(21, 1) /* index 880 */, + TILEGX_OPC_V1DDOTPU, TILEGX_OPC_NONE, + BITFIELD(21, 1) /* index 883 */, + TILEGX_OPC_V1DOTPUA, TILEGX_OPC_NONE, + BITFIELD(21, 1) /* index 886 */, + TILEGX_OPC_V1DOTPU, TILEGX_OPC_NONE, + BITFIELD(18, 4) /* index 889 */, + TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI, + TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI, + TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI, + TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, + BITFIELD(0, 2) /* index 906 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(911), + BITFIELD(2, 2) /* index 911 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(916), + BITFIELD(4, 2) /* index 916 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(921), + BITFIELD(6, 2) /* index 921 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(926), + BITFIELD(8, 2) /* index 926 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(931), + BITFIELD(10, 2) /* index 931 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + TILEGX_OPC_INFOL, +}; + +static const unsigned short decode_X1_fsm[1266] = +{ + BITFIELD(53, 9) /* index 0 */, + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), + CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, + TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BEQZT, + TILEGX_OPC_BEQZT, TILEGX_OPC_BEQZ, TILEGX_OPC_BEQZ, TILEGX_OPC_BGEZT, + TILEGX_OPC_BGEZT, TILEGX_OPC_BGEZ, TILEGX_OPC_BGEZ, TILEGX_OPC_BGTZT, + TILEGX_OPC_BGTZT, TILEGX_OPC_BGTZ, TILEGX_OPC_BGTZ, TILEGX_OPC_BLBCT, + TILEGX_OPC_BLBCT, TILEGX_OPC_BLBC, TILEGX_OPC_BLBC, TILEGX_OPC_BLBST, + TILEGX_OPC_BLBST, TILEGX_OPC_BLBS, TILEGX_OPC_BLBS, TILEGX_OPC_BLEZT, + TILEGX_OPC_BLEZT, TILEGX_OPC_BLEZ, TILEGX_OPC_BLEZ, TILEGX_OPC_BLTZT, + TILEGX_OPC_BLTZT, TILEGX_OPC_BLTZ, TILEGX_OPC_BLTZ, TILEGX_OPC_BNEZT, + TILEGX_OPC_BNEZT, TILEGX_OPC_BNEZ, TILEGX_OPC_BNEZ, CHILD(528), CHILD(578), + CHILD(598), CHILD(703), CHILD(723), CHILD(728), CHILD(753), CHILD(758), + CHILD(763), CHILD(768), CHILD(773), CHILD(778), TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, + TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, + CHILD(783), CHILD(800), CHILD(832), CHILD(849), CHILD(1168), CHILD(1185), + CHILD(1202), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1219), TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), + CHILD(1236), + BITFIELD(37, 2) /* index 513 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518), + BITFIELD(39, 2) /* index 518 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523), + BITFIELD(41, 2) /* index 523 */, + TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI, + BITFIELD(51, 2) /* index 528 */, + TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548), + BITFIELD(37, 2) /* index 533 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538), + BITFIELD(39, 2) /* index 538 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543), + BITFIELD(41, 2) /* index 543 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, + BITFIELD(31, 2) /* index 548 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553), + BITFIELD(33, 2) /* index 553 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558), + BITFIELD(35, 2) /* index 558 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563), + BITFIELD(37, 2) /* index 563 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568), + BITFIELD(39, 2) /* index 568 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573), + BITFIELD(41, 2) /* index 573 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, + BITFIELD(51, 2) /* index 578 */, + TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, CHILD(583), + BITFIELD(31, 2) /* index 583 */, + TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(588), + BITFIELD(33, 2) /* index 588 */, + TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(593), + BITFIELD(35, 2) /* index 593 */, + TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, + TILEGX_OPC_PREFETCH_ADD_L1_FAULT, + BITFIELD(51, 2) /* index 598 */, + CHILD(603), CHILD(618), CHILD(633), CHILD(648), + BITFIELD(31, 2) /* index 603 */, + TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(608), + BITFIELD(33, 2) /* index 608 */, + TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(613), + BITFIELD(35, 2) /* index 613 */, + TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, + TILEGX_OPC_PREFETCH_ADD_L1, + BITFIELD(31, 2) /* index 618 */, + TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(623), + BITFIELD(33, 2) /* index 623 */, + TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(628), + BITFIELD(35, 2) /* index 628 */, + TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, + TILEGX_OPC_PREFETCH_ADD_L2_FAULT, + BITFIELD(31, 2) /* index 633 */, + TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(638), + BITFIELD(33, 2) /* index 638 */, + TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(643), + BITFIELD(35, 2) /* index 643 */, + TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, + TILEGX_OPC_PREFETCH_ADD_L2, + BITFIELD(31, 2) /* index 648 */, + CHILD(653), CHILD(653), CHILD(653), CHILD(673), + BITFIELD(43, 2) /* index 653 */, + CHILD(658), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, + BITFIELD(45, 2) /* index 658 */, + CHILD(663), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, + BITFIELD(47, 2) /* index 663 */, + CHILD(668), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, + BITFIELD(49, 2) /* index 668 */, + TILEGX_OPC_LD4S_TLS, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, + TILEGX_OPC_LD4S_ADD, + BITFIELD(33, 2) /* index 673 */, + CHILD(653), CHILD(653), CHILD(653), CHILD(678), + BITFIELD(35, 2) /* index 678 */, + CHILD(653), CHILD(653), CHILD(653), CHILD(683), + BITFIELD(43, 2) /* index 683 */, + CHILD(688), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + BITFIELD(45, 2) /* index 688 */, + CHILD(693), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + BITFIELD(47, 2) /* index 693 */, + CHILD(698), TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + BITFIELD(49, 2) /* index 698 */, + TILEGX_OPC_LD4S_TLS, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT, + BITFIELD(51, 2) /* index 703 */, + CHILD(708), TILEGX_OPC_LDNT1S_ADD, TILEGX_OPC_LDNT1U_ADD, + TILEGX_OPC_LDNT2S_ADD, + BITFIELD(31, 2) /* index 708 */, + TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(713), + BITFIELD(33, 2) /* index 713 */, + TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(718), + BITFIELD(35, 2) /* index 718 */, + TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, + TILEGX_OPC_PREFETCH_ADD_L3, + BITFIELD(51, 2) /* index 723 */, + TILEGX_OPC_LDNT2U_ADD, TILEGX_OPC_LDNT4S_ADD, TILEGX_OPC_LDNT4U_ADD, + TILEGX_OPC_LDNT_ADD, + BITFIELD(51, 2) /* index 728 */, + CHILD(733), TILEGX_OPC_LDNA_ADD, TILEGX_OPC_MFSPR, TILEGX_OPC_MTSPR, + BITFIELD(43, 2) /* index 733 */, + CHILD(738), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, + BITFIELD(45, 2) /* index 738 */, + CHILD(743), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, + BITFIELD(47, 2) /* index 743 */, + CHILD(748), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, + BITFIELD(49, 2) /* index 748 */, + TILEGX_OPC_LD_TLS, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, + BITFIELD(51, 2) /* index 753 */, + TILEGX_OPC_ORI, TILEGX_OPC_ST1_ADD, TILEGX_OPC_ST2_ADD, TILEGX_OPC_ST4_ADD, + BITFIELD(51, 2) /* index 758 */, + TILEGX_OPC_STNT1_ADD, TILEGX_OPC_STNT2_ADD, TILEGX_OPC_STNT4_ADD, + TILEGX_OPC_STNT_ADD, + BITFIELD(51, 2) /* index 763 */, + TILEGX_OPC_ST_ADD, TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, + TILEGX_OPC_V1CMPLTSI, + BITFIELD(51, 2) /* index 768 */, + TILEGX_OPC_V1CMPLTUI, TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, + TILEGX_OPC_V2ADDI, + BITFIELD(51, 2) /* index 773 */, + TILEGX_OPC_V2CMPEQI, TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, + TILEGX_OPC_V2MAXSI, + BITFIELD(51, 2) /* index 778 */, + TILEGX_OPC_V2MINSI, TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(49, 4) /* index 783 */, + TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD, + TILEGX_OPC_AND, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPEXCH4, TILEGX_OPC_CMPEXCH, + TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, + TILEGX_OPC_CMPNE, TILEGX_OPC_DBLALIGN2, TILEGX_OPC_DBLALIGN4, + TILEGX_OPC_DBLALIGN6, + BITFIELD(49, 4) /* index 800 */, + TILEGX_OPC_EXCH4, TILEGX_OPC_EXCH, TILEGX_OPC_FETCHADD4, + TILEGX_OPC_FETCHADDGEZ4, TILEGX_OPC_FETCHADDGEZ, TILEGX_OPC_FETCHADD, + TILEGX_OPC_FETCHAND4, TILEGX_OPC_FETCHAND, TILEGX_OPC_FETCHOR4, + TILEGX_OPC_FETCHOR, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, TILEGX_OPC_NOR, + CHILD(817), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX, + BITFIELD(43, 2) /* index 817 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(822), + BITFIELD(45, 2) /* index 822 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(827), + BITFIELD(47, 2) /* index 827 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, + BITFIELD(49, 4) /* index 832 */, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL, + TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_ST1, + TILEGX_OPC_ST2, TILEGX_OPC_ST4, TILEGX_OPC_STNT1, TILEGX_OPC_STNT2, + TILEGX_OPC_STNT4, + BITFIELD(46, 7) /* index 849 */, + TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, + TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, + TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, + TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_SUBXSC, + TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, + TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBX, + TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, + TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, + TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, + TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, CHILD(978), CHILD(987), + CHILD(1066), CHILD(1150), CHILD(1159), TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, + TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, + TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, + TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, + TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, + TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, + TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, + TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, + TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, + TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU, + TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, + TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, + TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, + TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, + TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, + TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, + TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, + TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE, + TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, + TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, + TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, + TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, + TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, + TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, + TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, + TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, + BITFIELD(43, 3) /* index 978 */, + TILEGX_OPC_NONE, TILEGX_OPC_DRAIN, TILEGX_OPC_DTLBPR, TILEGX_OPC_FINV, + TILEGX_OPC_FLUSHWB, TILEGX_OPC_FLUSH, TILEGX_OPC_FNOP, TILEGX_OPC_ICOH, + BITFIELD(43, 3) /* index 987 */, + CHILD(996), TILEGX_OPC_INV, TILEGX_OPC_IRET, TILEGX_OPC_JALRP, + TILEGX_OPC_JALR, TILEGX_OPC_JRP, TILEGX_OPC_JR, CHILD(1051), + BITFIELD(31, 2) /* index 996 */, + CHILD(1001), CHILD(1026), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(33, 2) /* index 1001 */, + TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1006), + BITFIELD(35, 2) /* index 1006 */, + TILEGX_OPC_ILL, CHILD(1011), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(37, 2) /* index 1011 */, + TILEGX_OPC_ILL, CHILD(1016), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(39, 2) /* index 1016 */, + TILEGX_OPC_ILL, CHILD(1021), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(41, 2) /* index 1021 */, + TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_BPT, TILEGX_OPC_ILL, + BITFIELD(33, 2) /* index 1026 */, + TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1031), + BITFIELD(35, 2) /* index 1031 */, + TILEGX_OPC_ILL, CHILD(1036), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(37, 2) /* index 1036 */, + TILEGX_OPC_ILL, CHILD(1041), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(39, 2) /* index 1041 */, + TILEGX_OPC_ILL, CHILD(1046), TILEGX_OPC_ILL, TILEGX_OPC_ILL, + BITFIELD(41, 2) /* index 1046 */, + TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_RAISE, TILEGX_OPC_ILL, + BITFIELD(31, 2) /* index 1051 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1056), + BITFIELD(33, 2) /* index 1056 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1061), + BITFIELD(35, 2) /* index 1061 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, + TILEGX_OPC_PREFETCH_L1_FAULT, + BITFIELD(43, 3) /* index 1066 */, + CHILD(1075), CHILD(1090), CHILD(1105), CHILD(1120), CHILD(1135), + TILEGX_OPC_LDNA, TILEGX_OPC_LDNT1S, TILEGX_OPC_LDNT1U, + BITFIELD(31, 2) /* index 1075 */, + TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1080), + BITFIELD(33, 2) /* index 1080 */, + TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1085), + BITFIELD(35, 2) /* index 1085 */, + TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH, + BITFIELD(31, 2) /* index 1090 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1095), + BITFIELD(33, 2) /* index 1095 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1100), + BITFIELD(35, 2) /* index 1100 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, + TILEGX_OPC_PREFETCH_L2_FAULT, + BITFIELD(31, 2) /* index 1105 */, + TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1110), + BITFIELD(33, 2) /* index 1110 */, + TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1115), + BITFIELD(35, 2) /* index 1115 */, + TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2, + BITFIELD(31, 2) /* index 1120 */, + TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1125), + BITFIELD(33, 2) /* index 1125 */, + TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1130), + BITFIELD(35, 2) /* index 1130 */, + TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, + TILEGX_OPC_PREFETCH_L3_FAULT, + BITFIELD(31, 2) /* index 1135 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1140), + BITFIELD(33, 2) /* index 1140 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1145), + BITFIELD(35, 2) /* index 1145 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3, + BITFIELD(43, 3) /* index 1150 */, + TILEGX_OPC_LDNT2S, TILEGX_OPC_LDNT2U, TILEGX_OPC_LDNT4S, TILEGX_OPC_LDNT4U, + TILEGX_OPC_LDNT, TILEGX_OPC_LD, TILEGX_OPC_LNK, TILEGX_OPC_MF, + BITFIELD(43, 3) /* index 1159 */, + TILEGX_OPC_NAP, TILEGX_OPC_NOP, TILEGX_OPC_SWINT0, TILEGX_OPC_SWINT1, + TILEGX_OPC_SWINT2, TILEGX_OPC_SWINT3, TILEGX_OPC_WH64, TILEGX_OPC_NONE, + BITFIELD(49, 4) /* index 1168 */, + TILEGX_OPC_V1MAXU, TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MZ, + TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, + TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, TILEGX_OPC_V2ADD, TILEGX_OPC_V2CMPEQ, + TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, TILEGX_OPC_V2CMPLTS, + TILEGX_OPC_V2CMPLTU, + BITFIELD(49, 4) /* index 1185 */, + TILEGX_OPC_V2CMPNE, TILEGX_OPC_V2INT_H, TILEGX_OPC_V2INT_L, + TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, TILEGX_OPC_V2MZ, + TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC, + TILEGX_OPC_V2SHLSC, TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, + TILEGX_OPC_V2SUBSC, TILEGX_OPC_V2SUB, + BITFIELD(49, 4) /* index 1202 */, + TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H, + TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC, + TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC, + TILEGX_OPC_V4SUB, TILEGX_OPC_XOR, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(49, 4) /* index 1219 */, + TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI, + TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI, + TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI, + TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, + BITFIELD(31, 2) /* index 1236 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(1241), + BITFIELD(33, 2) /* index 1241 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(1246), + BITFIELD(35, 2) /* index 1246 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(1251), + BITFIELD(37, 2) /* index 1251 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(1256), + BITFIELD(39, 2) /* index 1256 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + CHILD(1261), + BITFIELD(41, 2) /* index 1261 */, + TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, + TILEGX_OPC_INFOL, +}; + +static const unsigned short decode_Y0_fsm[178] = +{ + BITFIELD(27, 4) /* index 0 */, + CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI, + TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(118), CHILD(123), + CHILD(128), CHILD(133), CHILD(153), CHILD(158), CHILD(163), CHILD(168), + CHILD(173), + BITFIELD(6, 2) /* index 17 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22), + BITFIELD(8, 2) /* index 22 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27), + BITFIELD(10, 2) /* index 27 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, + BITFIELD(0, 2) /* index 32 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37), + BITFIELD(2, 2) /* index 37 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42), + BITFIELD(4, 2) /* index 42 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47), + BITFIELD(6, 2) /* index 47 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52), + BITFIELD(8, 2) /* index 52 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57), + BITFIELD(10, 2) /* index 57 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, + BITFIELD(18, 2) /* index 62 */, + TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, + BITFIELD(15, 5) /* index 67 */, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, + TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, + TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(100), + CHILD(109), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(12, 3) /* index 100 */, + TILEGX_OPC_NONE, TILEGX_OPC_CLZ, TILEGX_OPC_CTZ, TILEGX_OPC_FNOP, + TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NOP, TILEGX_OPC_PCNT, + TILEGX_OPC_REVBITS, + BITFIELD(12, 3) /* index 109 */, + TILEGX_OPC_REVBYTES, TILEGX_OPC_TBLIDXB0, TILEGX_OPC_TBLIDXB1, + TILEGX_OPC_TBLIDXB2, TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + TILEGX_OPC_NONE, + BITFIELD(18, 2) /* index 118 */, + TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, + BITFIELD(18, 2) /* index 123 */, + TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, TILEGX_OPC_MULAX, TILEGX_OPC_MULX, + BITFIELD(18, 2) /* index 128 */, + TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, + BITFIELD(18, 2) /* index 133 */, + TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(138), TILEGX_OPC_XOR, + BITFIELD(12, 2) /* index 138 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(143), + BITFIELD(14, 2) /* index 143 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(148), + BITFIELD(16, 2) /* index 148 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, + BITFIELD(18, 2) /* index 153 */, + TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU, + BITFIELD(18, 2) /* index 158 */, + TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX, + TILEGX_OPC_SHL3ADDX, + BITFIELD(18, 2) /* index 163 */, + TILEGX_OPC_MUL_HS_HS, TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_LS_LS, + TILEGX_OPC_MUL_LU_LU, + BITFIELD(18, 2) /* index 168 */, + TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_LS_LS, + TILEGX_OPC_MULA_LU_LU, + BITFIELD(18, 2) /* index 173 */, + TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, +}; + +static const unsigned short decode_Y1_fsm[167] = +{ + BITFIELD(58, 4) /* index 0 */, + TILEGX_OPC_NONE, CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI, + TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(117), CHILD(122), + CHILD(127), CHILD(132), CHILD(152), CHILD(157), CHILD(162), TILEGX_OPC_NONE, + BITFIELD(37, 2) /* index 17 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22), + BITFIELD(39, 2) /* index 22 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27), + BITFIELD(41, 2) /* index 27 */, + TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI, + BITFIELD(31, 2) /* index 32 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37), + BITFIELD(33, 2) /* index 37 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42), + BITFIELD(35, 2) /* index 42 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47), + BITFIELD(37, 2) /* index 47 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52), + BITFIELD(39, 2) /* index 52 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57), + BITFIELD(41, 2) /* index 57 */, + TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO, + BITFIELD(49, 2) /* index 62 */, + TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB, + BITFIELD(47, 4) /* index 67 */, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, + TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, + TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, + TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(84), + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, + BITFIELD(43, 3) /* index 84 */, + CHILD(93), CHILD(96), CHILD(99), CHILD(102), CHILD(105), CHILD(108), + CHILD(111), CHILD(114), + BITFIELD(46, 1) /* index 93 */, + TILEGX_OPC_NONE, TILEGX_OPC_FNOP, + BITFIELD(46, 1) /* index 96 */, + TILEGX_OPC_NONE, TILEGX_OPC_ILL, + BITFIELD(46, 1) /* index 99 */, + TILEGX_OPC_NONE, TILEGX_OPC_JALRP, + BITFIELD(46, 1) /* index 102 */, + TILEGX_OPC_NONE, TILEGX_OPC_JALR, + BITFIELD(46, 1) /* index 105 */, + TILEGX_OPC_NONE, TILEGX_OPC_JRP, + BITFIELD(46, 1) /* index 108 */, + TILEGX_OPC_NONE, TILEGX_OPC_JR, + BITFIELD(46, 1) /* index 111 */, + TILEGX_OPC_NONE, TILEGX_OPC_LNK, + BITFIELD(46, 1) /* index 114 */, + TILEGX_OPC_NONE, TILEGX_OPC_NOP, + BITFIELD(49, 2) /* index 117 */, + TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU, + BITFIELD(49, 2) /* index 122 */, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, + BITFIELD(49, 2) /* index 127 */, + TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, + BITFIELD(49, 2) /* index 132 */, + TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(137), TILEGX_OPC_XOR, + BITFIELD(43, 2) /* index 137 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(142), + BITFIELD(45, 2) /* index 142 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(147), + BITFIELD(47, 2) /* index 147 */, + TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE, + BITFIELD(49, 2) /* index 152 */, + TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU, + BITFIELD(49, 2) /* index 157 */, + TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX, + TILEGX_OPC_SHL3ADDX, + BITFIELD(49, 2) /* index 162 */, + TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, +}; + +static const unsigned short decode_Y2_fsm[118] = +{ + BITFIELD(62, 2) /* index 0 */, + TILEGX_OPC_NONE, CHILD(5), CHILD(66), CHILD(109), + BITFIELD(55, 3) /* index 5 */, + CHILD(14), CHILD(14), CHILD(14), CHILD(17), CHILD(40), CHILD(40), CHILD(40), + CHILD(43), + BITFIELD(26, 1) /* index 14 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1U, + BITFIELD(26, 1) /* index 17 */, + CHILD(20), CHILD(30), + BITFIELD(51, 2) /* index 20 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(25), + BITFIELD(53, 2) /* index 25 */, + TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, + TILEGX_OPC_PREFETCH_L1_FAULT, + BITFIELD(51, 2) /* index 30 */, + TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(35), + BITFIELD(53, 2) /* index 35 */, + TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH, + BITFIELD(26, 1) /* index 40 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2U, + BITFIELD(26, 1) /* index 43 */, + CHILD(46), CHILD(56), + BITFIELD(51, 2) /* index 46 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(51), + BITFIELD(53, 2) /* index 51 */, + TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, + TILEGX_OPC_PREFETCH_L2_FAULT, + BITFIELD(51, 2) /* index 56 */, + TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(61), + BITFIELD(53, 2) /* index 61 */, + TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2, + BITFIELD(56, 2) /* index 66 */, + CHILD(71), CHILD(74), CHILD(90), CHILD(93), + BITFIELD(26, 1) /* index 71 */, + TILEGX_OPC_NONE, TILEGX_OPC_LD4S, + BITFIELD(26, 1) /* index 74 */, + TILEGX_OPC_NONE, CHILD(77), + BITFIELD(51, 2) /* index 77 */, + TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(82), + BITFIELD(53, 2) /* index 82 */, + TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(87), + BITFIELD(55, 1) /* index 87 */, + TILEGX_OPC_LD4S, TILEGX_OPC_PREFETCH_L3_FAULT, + BITFIELD(26, 1) /* index 90 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD, + BITFIELD(26, 1) /* index 93 */, + CHILD(96), TILEGX_OPC_LD, + BITFIELD(51, 2) /* index 96 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(101), + BITFIELD(53, 2) /* index 101 */, + TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(106), + BITFIELD(55, 1) /* index 106 */, + TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3, + BITFIELD(26, 1) /* index 109 */, + CHILD(112), CHILD(115), + BITFIELD(57, 1) /* index 112 */, + TILEGX_OPC_ST1, TILEGX_OPC_ST4, + BITFIELD(57, 1) /* index 115 */, + TILEGX_OPC_ST2, TILEGX_OPC_ST, +}; + +#undef BITFIELD +#undef CHILD + +const unsigned short * const +tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS] = +{ + decode_X0_fsm, + decode_X1_fsm, + decode_Y0_fsm, + decode_Y1_fsm, + decode_Y2_fsm +}; + +const struct tilegx_operand tilegx_operands[35] = +{ + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X0), + 8, 1, 0, 0, 0, 0, + create_Imm8_X0, get_Imm8_X0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X1), + 8, 1, 0, 0, 0, 0, + create_Imm8_X1, get_Imm8_X1 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y0), + 8, 1, 0, 0, 0, 0, + create_Imm8_Y0, get_Imm8_Y0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y1), + 8, 1, 0, 0, 0, 0, + create_Imm8_Y1, get_Imm8_Y1 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X0_HW0_LAST), + 16, 1, 0, 0, 0, 0, + create_Imm16_X0, get_Imm16_X0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X1_HW0_LAST), + 16, 1, 0, 0, 0, 0, + create_Imm16_X1, get_Imm16_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 0, 1, 0, 0, + create_Dest_X1, get_Dest_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcA_X1, get_SrcA_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 0, 1, 0, 0, + create_Dest_X0, get_Dest_X0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcA_X0, get_SrcA_X0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 0, 1, 0, 0, + create_Dest_Y0, get_Dest_Y0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcA_Y0, get_SrcA_Y0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 0, 1, 0, 0, + create_Dest_Y1, get_Dest_Y1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcA_Y1, get_SrcA_Y1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcA_Y2, get_SrcA_Y2 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 1, 0, 0, + create_SrcA_X1, get_SrcA_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcB_X0, get_SrcB_X0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcB_X1, get_SrcB_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcB_Y0, get_SrcB_Y0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcB_Y1, get_SrcB_Y1 + }, + { + TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_BROFF_X1), + 17, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, + create_BrOff_X1, get_BrOff_X1 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMSTART_X0), + 6, 0, 0, 0, 0, 0, + create_BFStart_X0, get_BFStart_X0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMEND_X0), + 6, 0, 0, 0, 0, 0, + create_BFEnd_X0, get_BFEnd_X0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 1, 0, 0, + create_Dest_X0, get_Dest_X0 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 1, 0, 0, + create_Dest_Y0, get_Dest_Y0 + }, + { + TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_JUMPOFF_X1), + 27, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, + create_JumpOff_X1, get_JumpOff_X1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 0, 1, 0, 0, + create_SrcBDest_Y2, get_SrcBDest_Y2 + }, + { + TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MF_IMM14_X1), + 14, 0, 0, 0, 0, 0, + create_MF_Imm14_X1, get_MF_Imm14_X1 + }, + { + TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MT_IMM14_X1), + 14, 0, 0, 0, 0, 0, + create_MT_Imm14_X1, get_MT_Imm14_X1 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X0), + 6, 0, 0, 0, 0, 0, + create_ShAmt_X0, get_ShAmt_X0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X1), + 6, 0, 0, 0, 0, 0, + create_ShAmt_X1, get_ShAmt_X1 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y0), + 6, 0, 0, 0, 0, 0, + create_ShAmt_Y0, get_ShAmt_Y0 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y1), + 6, 0, 0, 0, 0, 0, + create_ShAmt_Y1, get_ShAmt_Y1 + }, + { + TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE), + 6, 0, 1, 0, 0, 0, + create_SrcBDest_Y2, get_SrcBDest_Y2 + }, + { + TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_DEST_IMM8_X1), + 8, 1, 0, 0, 0, 0, + create_Dest_Imm8_X1, get_Dest_Imm8_X1 + } +}; + +/* Given a set of bundle bits and a specific pipe, returns which + * instruction the bundle contains in that pipe. + */ +const struct tilegx_opcode * +find_opcode(tilegx_bundle_bits bits, tilegx_pipeline pipe) +{ + const unsigned short *table = tilegx_bundle_decoder_fsms[pipe]; + int index = 0; + + while (1) + { + unsigned short bitspec = table[index]; + unsigned int bitfield = + ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6); + + unsigned short next = table[index + 1 + bitfield]; + if (next <= TILEGX_OPC_NONE) + return &tilegx_opcodes[next]; + + index = next - TILEGX_OPC_NONE; + } +} + +int +parse_insn_tilegx(tilegx_bundle_bits bits, + unsigned long long pc, + struct tilegx_decoded_instruction + decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]) +{ + int num_instructions = 0; + int pipe; + + int min_pipe, max_pipe; + if ((bits & TILEGX_BUNDLE_MODE_MASK) == 0) + { + min_pipe = TILEGX_PIPELINE_X0; + max_pipe = TILEGX_PIPELINE_X1; + } + else + { + min_pipe = TILEGX_PIPELINE_Y0; + max_pipe = TILEGX_PIPELINE_Y2; + } + + /* For each pipe, find an instruction that fits. */ + for (pipe = min_pipe; pipe <= max_pipe; pipe++) + { + const struct tilegx_opcode *opc; + struct tilegx_decoded_instruction *d; + int i; + + d = &decoded[num_instructions++]; + opc = find_opcode (bits, (tilegx_pipeline)pipe); + d->opcode = opc; + + /* Decode each operand, sign extending, etc. as appropriate. */ + for (i = 0; i < opc->num_operands; i++) + { + const struct tilegx_operand *op = + &tilegx_operands[opc->operands[pipe][i]]; + int raw_opval = op->extract (bits); + long long opval; + + if (op->is_signed) + { + /* Sign-extend the operand. */ + int shift = (int)((sizeof(int) * 8) - op->num_bits); + raw_opval = (raw_opval << shift) >> shift; + } + + /* Adjust PC-relative scaled branch offsets. */ + if (op->type == TILEGX_OP_TYPE_ADDRESS) + opval = (raw_opval * TILEGX_BUNDLE_SIZE_IN_BYTES) + pc; + else + opval = raw_opval; + + /* Record the final value. */ + d->operands[i] = op; + d->operand_values[i] = opval; + } + } + + return num_instructions; +} + +struct tilegx_spr +{ + /* The number */ + int number; + + /* The name */ + const char *name; +}; + +static int +tilegx_spr_compare (const void *a_ptr, const void *b_ptr) +{ + const struct tilegx_spr *a = (const struct tilegx_spr *) a_ptr; + const struct tilegx_spr *b = (const struct tilegx_spr *) b_ptr; + return (a->number - b->number); +} + +const struct tilegx_spr tilegx_sprs[] = { + { 0, "MPL_MEM_ERROR_SET_0" }, + { 1, "MPL_MEM_ERROR_SET_1" }, + { 2, "MPL_MEM_ERROR_SET_2" }, + { 3, "MPL_MEM_ERROR_SET_3" }, + { 4, "MPL_MEM_ERROR" }, + { 5, "MEM_ERROR_CBOX_ADDR" }, + { 6, "MEM_ERROR_CBOX_STATUS" }, + { 7, "MEM_ERROR_ENABLE" }, + { 8, "MEM_ERROR_MBOX_ADDR" }, + { 9, "MEM_ERROR_MBOX_STATUS" }, + { 10, "SBOX_ERROR" }, + { 11, "XDN_DEMUX_ERROR" }, + { 256, "MPL_SINGLE_STEP_3_SET_0" }, + { 257, "MPL_SINGLE_STEP_3_SET_1" }, + { 258, "MPL_SINGLE_STEP_3_SET_2" }, + { 259, "MPL_SINGLE_STEP_3_SET_3" }, + { 260, "MPL_SINGLE_STEP_3" }, + { 261, "SINGLE_STEP_CONTROL_3" }, + { 512, "MPL_SINGLE_STEP_2_SET_0" }, + { 513, "MPL_SINGLE_STEP_2_SET_1" }, + { 514, "MPL_SINGLE_STEP_2_SET_2" }, + { 515, "MPL_SINGLE_STEP_2_SET_3" }, + { 516, "MPL_SINGLE_STEP_2" }, + { 517, "SINGLE_STEP_CONTROL_2" }, + { 768, "MPL_SINGLE_STEP_1_SET_0" }, + { 769, "MPL_SINGLE_STEP_1_SET_1" }, + { 770, "MPL_SINGLE_STEP_1_SET_2" }, + { 771, "MPL_SINGLE_STEP_1_SET_3" }, + { 772, "MPL_SINGLE_STEP_1" }, + { 773, "SINGLE_STEP_CONTROL_1" }, + { 1024, "MPL_SINGLE_STEP_0_SET_0" }, + { 1025, "MPL_SINGLE_STEP_0_SET_1" }, + { 1026, "MPL_SINGLE_STEP_0_SET_2" }, + { 1027, "MPL_SINGLE_STEP_0_SET_3" }, + { 1028, "MPL_SINGLE_STEP_0" }, + { 1029, "SINGLE_STEP_CONTROL_0" }, + { 1280, "MPL_IDN_COMPLETE_SET_0" }, + { 1281, "MPL_IDN_COMPLETE_SET_1" }, + { 1282, "MPL_IDN_COMPLETE_SET_2" }, + { 1283, "MPL_IDN_COMPLETE_SET_3" }, + { 1284, "MPL_IDN_COMPLETE" }, + { 1285, "IDN_COMPLETE_PENDING" }, + { 1536, "MPL_UDN_COMPLETE_SET_0" }, + { 1537, "MPL_UDN_COMPLETE_SET_1" }, + { 1538, "MPL_UDN_COMPLETE_SET_2" }, + { 1539, "MPL_UDN_COMPLETE_SET_3" }, + { 1540, "MPL_UDN_COMPLETE" }, + { 1541, "UDN_COMPLETE_PENDING" }, + { 1792, "MPL_ITLB_MISS_SET_0" }, + { 1793, "MPL_ITLB_MISS_SET_1" }, + { 1794, "MPL_ITLB_MISS_SET_2" }, + { 1795, "MPL_ITLB_MISS_SET_3" }, + { 1796, "MPL_ITLB_MISS" }, + { 1797, "ITLB_TSB_BASE_ADDR_0" }, + { 1798, "ITLB_TSB_BASE_ADDR_1" }, + { 1920, "ITLB_CURRENT_ATTR" }, + { 1921, "ITLB_CURRENT_PA" }, + { 1922, "ITLB_CURRENT_VA" }, + { 1923, "ITLB_INDEX" }, + { 1924, "ITLB_MATCH_0" }, + { 1925, "ITLB_PERF" }, + { 1926, "ITLB_PR" }, + { 1927, "ITLB_TSB_ADDR_0" }, + { 1928, "ITLB_TSB_ADDR_1" }, + { 1929, "ITLB_TSB_FILL_CURRENT_ATTR" }, + { 1930, "ITLB_TSB_FILL_MATCH" }, + { 1931, "NUMBER_ITLB" }, + { 1932, "REPLACEMENT_ITLB" }, + { 1933, "WIRED_ITLB" }, + { 2048, "MPL_ILL_SET_0" }, + { 2049, "MPL_ILL_SET_1" }, + { 2050, "MPL_ILL_SET_2" }, + { 2051, "MPL_ILL_SET_3" }, + { 2052, "MPL_ILL" }, + { 2304, "MPL_GPV_SET_0" }, + { 2305, "MPL_GPV_SET_1" }, + { 2306, "MPL_GPV_SET_2" }, + { 2307, "MPL_GPV_SET_3" }, + { 2308, "MPL_GPV" }, + { 2309, "GPV_REASON" }, + { 2560, "MPL_IDN_ACCESS_SET_0" }, + { 2561, "MPL_IDN_ACCESS_SET_1" }, + { 2562, "MPL_IDN_ACCESS_SET_2" }, + { 2563, "MPL_IDN_ACCESS_SET_3" }, + { 2564, "MPL_IDN_ACCESS" }, + { 2565, "IDN_DEMUX_COUNT_0" }, + { 2566, "IDN_DEMUX_COUNT_1" }, + { 2567, "IDN_FLUSH_EGRESS" }, + { 2568, "IDN_PENDING" }, + { 2569, "IDN_ROUTE_ORDER" }, + { 2570, "IDN_SP_FIFO_CNT" }, + { 2688, "IDN_DATA_AVAIL" }, + { 2816, "MPL_UDN_ACCESS_SET_0" }, + { 2817, "MPL_UDN_ACCESS_SET_1" }, + { 2818, "MPL_UDN_ACCESS_SET_2" }, + { 2819, "MPL_UDN_ACCESS_SET_3" }, + { 2820, "MPL_UDN_ACCESS" }, + { 2821, "UDN_DEMUX_COUNT_0" }, + { 2822, "UDN_DEMUX_COUNT_1" }, + { 2823, "UDN_DEMUX_COUNT_2" }, + { 2824, "UDN_DEMUX_COUNT_3" }, + { 2825, "UDN_FLUSH_EGRESS" }, + { 2826, "UDN_PENDING" }, + { 2827, "UDN_ROUTE_ORDER" }, + { 2828, "UDN_SP_FIFO_CNT" }, + { 2944, "UDN_DATA_AVAIL" }, + { 3072, "MPL_SWINT_3_SET_0" }, + { 3073, "MPL_SWINT_3_SET_1" }, + { 3074, "MPL_SWINT_3_SET_2" }, + { 3075, "MPL_SWINT_3_SET_3" }, + { 3076, "MPL_SWINT_3" }, + { 3328, "MPL_SWINT_2_SET_0" }, + { 3329, "MPL_SWINT_2_SET_1" }, + { 3330, "MPL_SWINT_2_SET_2" }, + { 3331, "MPL_SWINT_2_SET_3" }, + { 3332, "MPL_SWINT_2" }, + { 3584, "MPL_SWINT_1_SET_0" }, + { 3585, "MPL_SWINT_1_SET_1" }, + { 3586, "MPL_SWINT_1_SET_2" }, + { 3587, "MPL_SWINT_1_SET_3" }, + { 3588, "MPL_SWINT_1" }, + { 3840, "MPL_SWINT_0_SET_0" }, + { 3841, "MPL_SWINT_0_SET_1" }, + { 3842, "MPL_SWINT_0_SET_2" }, + { 3843, "MPL_SWINT_0_SET_3" }, + { 3844, "MPL_SWINT_0" }, + { 4096, "MPL_ILL_TRANS_SET_0" }, + { 4097, "MPL_ILL_TRANS_SET_1" }, + { 4098, "MPL_ILL_TRANS_SET_2" }, + { 4099, "MPL_ILL_TRANS_SET_3" }, + { 4100, "MPL_ILL_TRANS" }, + { 4101, "ILL_TRANS_REASON" }, + { 4102, "ILL_VA_PC" }, + { 4352, "MPL_UNALIGN_DATA_SET_0" }, + { 4353, "MPL_UNALIGN_DATA_SET_1" }, + { 4354, "MPL_UNALIGN_DATA_SET_2" }, + { 4355, "MPL_UNALIGN_DATA_SET_3" }, + { 4356, "MPL_UNALIGN_DATA" }, + { 4608, "MPL_DTLB_MISS_SET_0" }, + { 4609, "MPL_DTLB_MISS_SET_1" }, + { 4610, "MPL_DTLB_MISS_SET_2" }, + { 4611, "MPL_DTLB_MISS_SET_3" }, + { 4612, "MPL_DTLB_MISS" }, + { 4613, "DTLB_TSB_BASE_ADDR_0" }, + { 4614, "DTLB_TSB_BASE_ADDR_1" }, + { 4736, "AAR" }, + { 4737, "CACHE_PINNED_WAYS" }, + { 4738, "DTLB_BAD_ADDR" }, + { 4739, "DTLB_BAD_ADDR_REASON" }, + { 4740, "DTLB_CURRENT_ATTR" }, + { 4741, "DTLB_CURRENT_PA" }, + { 4742, "DTLB_CURRENT_VA" }, + { 4743, "DTLB_INDEX" }, + { 4744, "DTLB_MATCH_0" }, + { 4745, "DTLB_PERF" }, + { 4746, "DTLB_TSB_ADDR_0" }, + { 4747, "DTLB_TSB_ADDR_1" }, + { 4748, "DTLB_TSB_FILL_CURRENT_ATTR" }, + { 4749, "DTLB_TSB_FILL_MATCH" }, + { 4750, "NUMBER_DTLB" }, + { 4751, "REPLACEMENT_DTLB" }, + { 4752, "WIRED_DTLB" }, + { 4864, "MPL_DTLB_ACCESS_SET_0" }, + { 4865, "MPL_DTLB_ACCESS_SET_1" }, + { 4866, "MPL_DTLB_ACCESS_SET_2" }, + { 4867, "MPL_DTLB_ACCESS_SET_3" }, + { 4868, "MPL_DTLB_ACCESS" }, + { 5120, "MPL_IDN_FIREWALL_SET_0" }, + { 5121, "MPL_IDN_FIREWALL_SET_1" }, + { 5122, "MPL_IDN_FIREWALL_SET_2" }, + { 5123, "MPL_IDN_FIREWALL_SET_3" }, + { 5124, "MPL_IDN_FIREWALL" }, + { 5125, "IDN_DIRECTION_PROTECT" }, + { 5376, "MPL_UDN_FIREWALL_SET_0" }, + { 5377, "MPL_UDN_FIREWALL_SET_1" }, + { 5378, "MPL_UDN_FIREWALL_SET_2" }, + { 5379, "MPL_UDN_FIREWALL_SET_3" }, + { 5380, "MPL_UDN_FIREWALL" }, + { 5381, "UDN_DIRECTION_PROTECT" }, + { 5632, "MPL_TILE_TIMER_SET_0" }, + { 5633, "MPL_TILE_TIMER_SET_1" }, + { 5634, "MPL_TILE_TIMER_SET_2" }, + { 5635, "MPL_TILE_TIMER_SET_3" }, + { 5636, "MPL_TILE_TIMER" }, + { 5637, "TILE_TIMER_CONTROL" }, + { 5888, "MPL_AUX_TILE_TIMER_SET_0" }, + { 5889, "MPL_AUX_TILE_TIMER_SET_1" }, + { 5890, "MPL_AUX_TILE_TIMER_SET_2" }, + { 5891, "MPL_AUX_TILE_TIMER_SET_3" }, + { 5892, "MPL_AUX_TILE_TIMER" }, + { 5893, "AUX_TILE_TIMER_CONTROL" }, + { 6144, "MPL_IDN_TIMER_SET_0" }, + { 6145, "MPL_IDN_TIMER_SET_1" }, + { 6146, "MPL_IDN_TIMER_SET_2" }, + { 6147, "MPL_IDN_TIMER_SET_3" }, + { 6148, "MPL_IDN_TIMER" }, + { 6149, "IDN_DEADLOCK_COUNT" }, + { 6150, "IDN_DEADLOCK_TIMEOUT" }, + { 6400, "MPL_UDN_TIMER_SET_0" }, + { 6401, "MPL_UDN_TIMER_SET_1" }, + { 6402, "MPL_UDN_TIMER_SET_2" }, + { 6403, "MPL_UDN_TIMER_SET_3" }, + { 6404, "MPL_UDN_TIMER" }, + { 6405, "UDN_DEADLOCK_COUNT" }, + { 6406, "UDN_DEADLOCK_TIMEOUT" }, + { 6656, "MPL_IDN_AVAIL_SET_0" }, + { 6657, "MPL_IDN_AVAIL_SET_1" }, + { 6658, "MPL_IDN_AVAIL_SET_2" }, + { 6659, "MPL_IDN_AVAIL_SET_3" }, + { 6660, "MPL_IDN_AVAIL" }, + { 6661, "IDN_AVAIL_EN" }, + { 6912, "MPL_UDN_AVAIL_SET_0" }, + { 6913, "MPL_UDN_AVAIL_SET_1" }, + { 6914, "MPL_UDN_AVAIL_SET_2" }, + { 6915, "MPL_UDN_AVAIL_SET_3" }, + { 6916, "MPL_UDN_AVAIL" }, + { 6917, "UDN_AVAIL_EN" }, + { 7168, "MPL_IPI_3_SET_0" }, + { 7169, "MPL_IPI_3_SET_1" }, + { 7170, "MPL_IPI_3_SET_2" }, + { 7171, "MPL_IPI_3_SET_3" }, + { 7172, "MPL_IPI_3" }, + { 7173, "IPI_EVENT_3" }, + { 7174, "IPI_EVENT_RESET_3" }, + { 7175, "IPI_EVENT_SET_3" }, + { 7176, "IPI_MASK_3" }, + { 7177, "IPI_MASK_RESET_3" }, + { 7178, "IPI_MASK_SET_3" }, + { 7424, "MPL_IPI_2_SET_0" }, + { 7425, "MPL_IPI_2_SET_1" }, + { 7426, "MPL_IPI_2_SET_2" }, + { 7427, "MPL_IPI_2_SET_3" }, + { 7428, "MPL_IPI_2" }, + { 7429, "IPI_EVENT_2" }, + { 7430, "IPI_EVENT_RESET_2" }, + { 7431, "IPI_EVENT_SET_2" }, + { 7432, "IPI_MASK_2" }, + { 7433, "IPI_MASK_RESET_2" }, + { 7434, "IPI_MASK_SET_2" }, + { 7680, "MPL_IPI_1_SET_0" }, + { 7681, "MPL_IPI_1_SET_1" }, + { 7682, "MPL_IPI_1_SET_2" }, + { 7683, "MPL_IPI_1_SET_3" }, + { 7684, "MPL_IPI_1" }, + { 7685, "IPI_EVENT_1" }, + { 7686, "IPI_EVENT_RESET_1" }, + { 7687, "IPI_EVENT_SET_1" }, + { 7688, "IPI_MASK_1" }, + { 7689, "IPI_MASK_RESET_1" }, + { 7690, "IPI_MASK_SET_1" }, + { 7936, "MPL_IPI_0_SET_0" }, + { 7937, "MPL_IPI_0_SET_1" }, + { 7938, "MPL_IPI_0_SET_2" }, + { 7939, "MPL_IPI_0_SET_3" }, + { 7940, "MPL_IPI_0" }, + { 7941, "IPI_EVENT_0" }, + { 7942, "IPI_EVENT_RESET_0" }, + { 7943, "IPI_EVENT_SET_0" }, + { 7944, "IPI_MASK_0" }, + { 7945, "IPI_MASK_RESET_0" }, + { 7946, "IPI_MASK_SET_0" }, + { 8192, "MPL_PERF_COUNT_SET_0" }, + { 8193, "MPL_PERF_COUNT_SET_1" }, + { 8194, "MPL_PERF_COUNT_SET_2" }, + { 8195, "MPL_PERF_COUNT_SET_3" }, + { 8196, "MPL_PERF_COUNT" }, + { 8197, "PERF_COUNT_0" }, + { 8198, "PERF_COUNT_1" }, + { 8199, "PERF_COUNT_CTL" }, + { 8200, "PERF_COUNT_DN_CTL" }, + { 8201, "PERF_COUNT_STS" }, + { 8202, "WATCH_MASK" }, + { 8203, "WATCH_VAL" }, + { 8448, "MPL_AUX_PERF_COUNT_SET_0" }, + { 8449, "MPL_AUX_PERF_COUNT_SET_1" }, + { 8450, "MPL_AUX_PERF_COUNT_SET_2" }, + { 8451, "MPL_AUX_PERF_COUNT_SET_3" }, + { 8452, "MPL_AUX_PERF_COUNT" }, + { 8453, "AUX_PERF_COUNT_0" }, + { 8454, "AUX_PERF_COUNT_1" }, + { 8455, "AUX_PERF_COUNT_CTL" }, + { 8456, "AUX_PERF_COUNT_STS" }, + { 8704, "MPL_INTCTRL_3_SET_0" }, + { 8705, "MPL_INTCTRL_3_SET_1" }, + { 8706, "MPL_INTCTRL_3_SET_2" }, + { 8707, "MPL_INTCTRL_3_SET_3" }, + { 8708, "MPL_INTCTRL_3" }, + { 8709, "INTCTRL_3_STATUS" }, + { 8710, "INTERRUPT_MASK_3" }, + { 8711, "INTERRUPT_MASK_RESET_3" }, + { 8712, "INTERRUPT_MASK_SET_3" }, + { 8713, "INTERRUPT_VECTOR_BASE_3" }, + { 8714, "SINGLE_STEP_EN_0_3" }, + { 8715, "SINGLE_STEP_EN_1_3" }, + { 8716, "SINGLE_STEP_EN_2_3" }, + { 8717, "SINGLE_STEP_EN_3_3" }, + { 8832, "EX_CONTEXT_3_0" }, + { 8833, "EX_CONTEXT_3_1" }, + { 8834, "SYSTEM_SAVE_3_0" }, + { 8835, "SYSTEM_SAVE_3_1" }, + { 8836, "SYSTEM_SAVE_3_2" }, + { 8837, "SYSTEM_SAVE_3_3" }, + { 8960, "MPL_INTCTRL_2_SET_0" }, + { 8961, "MPL_INTCTRL_2_SET_1" }, + { 8962, "MPL_INTCTRL_2_SET_2" }, + { 8963, "MPL_INTCTRL_2_SET_3" }, + { 8964, "MPL_INTCTRL_2" }, + { 8965, "INTCTRL_2_STATUS" }, + { 8966, "INTERRUPT_MASK_2" }, + { 8967, "INTERRUPT_MASK_RESET_2" }, + { 8968, "INTERRUPT_MASK_SET_2" }, + { 8969, "INTERRUPT_VECTOR_BASE_2" }, + { 8970, "SINGLE_STEP_EN_0_2" }, + { 8971, "SINGLE_STEP_EN_1_2" }, + { 8972, "SINGLE_STEP_EN_2_2" }, + { 8973, "SINGLE_STEP_EN_3_2" }, + { 9088, "EX_CONTEXT_2_0" }, + { 9089, "EX_CONTEXT_2_1" }, + { 9090, "SYSTEM_SAVE_2_0" }, + { 9091, "SYSTEM_SAVE_2_1" }, + { 9092, "SYSTEM_SAVE_2_2" }, + { 9093, "SYSTEM_SAVE_2_3" }, + { 9216, "MPL_INTCTRL_1_SET_0" }, + { 9217, "MPL_INTCTRL_1_SET_1" }, + { 9218, "MPL_INTCTRL_1_SET_2" }, + { 9219, "MPL_INTCTRL_1_SET_3" }, + { 9220, "MPL_INTCTRL_1" }, + { 9221, "INTCTRL_1_STATUS" }, + { 9222, "INTERRUPT_MASK_1" }, + { 9223, "INTERRUPT_MASK_RESET_1" }, + { 9224, "INTERRUPT_MASK_SET_1" }, + { 9225, "INTERRUPT_VECTOR_BASE_1" }, + { 9226, "SINGLE_STEP_EN_0_1" }, + { 9227, "SINGLE_STEP_EN_1_1" }, + { 9228, "SINGLE_STEP_EN_2_1" }, + { 9229, "SINGLE_STEP_EN_3_1" }, + { 9344, "EX_CONTEXT_1_0" }, + { 9345, "EX_CONTEXT_1_1" }, + { 9346, "SYSTEM_SAVE_1_0" }, + { 9347, "SYSTEM_SAVE_1_1" }, + { 9348, "SYSTEM_SAVE_1_2" }, + { 9349, "SYSTEM_SAVE_1_3" }, + { 9472, "MPL_INTCTRL_0_SET_0" }, + { 9473, "MPL_INTCTRL_0_SET_1" }, + { 9474, "MPL_INTCTRL_0_SET_2" }, + { 9475, "MPL_INTCTRL_0_SET_3" }, + { 9476, "MPL_INTCTRL_0" }, + { 9477, "INTCTRL_0_STATUS" }, + { 9478, "INTERRUPT_MASK_0" }, + { 9479, "INTERRUPT_MASK_RESET_0" }, + { 9480, "INTERRUPT_MASK_SET_0" }, + { 9481, "INTERRUPT_VECTOR_BASE_0" }, + { 9482, "SINGLE_STEP_EN_0_0" }, + { 9483, "SINGLE_STEP_EN_1_0" }, + { 9484, "SINGLE_STEP_EN_2_0" }, + { 9485, "SINGLE_STEP_EN_3_0" }, + { 9600, "EX_CONTEXT_0_0" }, + { 9601, "EX_CONTEXT_0_1" }, + { 9602, "SYSTEM_SAVE_0_0" }, + { 9603, "SYSTEM_SAVE_0_1" }, + { 9604, "SYSTEM_SAVE_0_2" }, + { 9605, "SYSTEM_SAVE_0_3" }, + { 9728, "MPL_BOOT_ACCESS_SET_0" }, + { 9729, "MPL_BOOT_ACCESS_SET_1" }, + { 9730, "MPL_BOOT_ACCESS_SET_2" }, + { 9731, "MPL_BOOT_ACCESS_SET_3" }, + { 9732, "MPL_BOOT_ACCESS" }, + { 9733, "BIG_ENDIAN_CONFIG" }, + { 9734, "CACHE_INVALIDATION_COMPRESSION_MODE" }, + { 9735, "CACHE_INVALIDATION_MASK_0" }, + { 9736, "CACHE_INVALIDATION_MASK_1" }, + { 9737, "CACHE_INVALIDATION_MASK_2" }, + { 9738, "CBOX_CACHEASRAM_CONFIG" }, + { 9739, "CBOX_CACHE_CONFIG" }, + { 9740, "CBOX_HOME_MAP_ADDR" }, + { 9741, "CBOX_HOME_MAP_DATA" }, + { 9742, "CBOX_MMAP_0" }, + { 9743, "CBOX_MMAP_1" }, + { 9744, "CBOX_MMAP_2" }, + { 9745, "CBOX_MMAP_3" }, + { 9746, "CBOX_MSR" }, + { 9747, "DIAG_BCST_CTL" }, + { 9748, "DIAG_BCST_MASK" }, + { 9749, "DIAG_BCST_TRIGGER" }, + { 9750, "DIAG_MUX_CTL" }, + { 9751, "DIAG_TRACE_CTL" }, + { 9752, "DIAG_TRACE_DATA" }, + { 9753, "DIAG_TRACE_STS" }, + { 9754, "IDN_DEMUX_BUF_THRESH" }, + { 9755, "L1_I_PIN_WAY_0" }, + { 9756, "MEM_ROUTE_ORDER" }, + { 9757, "MEM_STRIPE_CONFIG" }, + { 9758, "PERF_COUNT_PLS" }, + { 9759, "PSEUDO_RANDOM_NUMBER_MODIFY" }, + { 9760, "QUIESCE_CTL" }, + { 9761, "RSHIM_COORD" }, + { 9762, "SBOX_CONFIG" }, + { 9763, "UDN_DEMUX_BUF_THRESH" }, + { 9764, "XDN_CORE_STARVATION_COUNT" }, + { 9765, "XDN_ROUND_ROBIN_ARB_CTL" }, + { 9856, "CYCLE_MODIFY" }, + { 9857, "I_AAR" }, + { 9984, "MPL_WORLD_ACCESS_SET_0" }, + { 9985, "MPL_WORLD_ACCESS_SET_1" }, + { 9986, "MPL_WORLD_ACCESS_SET_2" }, + { 9987, "MPL_WORLD_ACCESS_SET_3" }, + { 9988, "MPL_WORLD_ACCESS" }, + { 9989, "DONE" }, + { 9990, "DSTREAM_PF" }, + { 9991, "FAIL" }, + { 9992, "INTERRUPT_CRITICAL_SECTION" }, + { 9993, "PASS" }, + { 9994, "PSEUDO_RANDOM_NUMBER" }, + { 9995, "TILE_COORD" }, + { 9996, "TILE_RTF_HWM" }, + { 10112, "CMPEXCH_VALUE" }, + { 10113, "CYCLE" }, + { 10114, "EVENT_BEGIN" }, + { 10115, "EVENT_END" }, + { 10116, "PROC_STATUS" }, + { 10117, "SIM_CONTROL" }, + { 10118, "SIM_SOCKET" }, + { 10119, "STATUS_SATURATE" }, + { 10240, "MPL_I_ASID_SET_0" }, + { 10241, "MPL_I_ASID_SET_1" }, + { 10242, "MPL_I_ASID_SET_2" }, + { 10243, "MPL_I_ASID_SET_3" }, + { 10244, "MPL_I_ASID" }, + { 10245, "I_ASID" }, + { 10496, "MPL_D_ASID_SET_0" }, + { 10497, "MPL_D_ASID_SET_1" }, + { 10498, "MPL_D_ASID_SET_2" }, + { 10499, "MPL_D_ASID_SET_3" }, + { 10500, "MPL_D_ASID" }, + { 10501, "D_ASID" }, + { 10752, "MPL_DOUBLE_FAULT_SET_0" }, + { 10753, "MPL_DOUBLE_FAULT_SET_1" }, + { 10754, "MPL_DOUBLE_FAULT_SET_2" }, + { 10755, "MPL_DOUBLE_FAULT_SET_3" }, + { 10756, "MPL_DOUBLE_FAULT" }, + { 10757, "LAST_INTERRUPT_REASON" }, +}; + +const int tilegx_num_sprs = 441; + +const char * +get_tilegx_spr_name (int num) +{ + void *result; + struct tilegx_spr key; + + key.number = num; + result = bsearch((const void *) &key, (const void *) tilegx_sprs, + tilegx_num_sprs, sizeof (struct tilegx_spr), + tilegx_spr_compare); + + if (result == NULL) + { + return (NULL); + } + else + { + struct tilegx_spr *result_ptr = (struct tilegx_spr *) result; + return (result_ptr->name); + } +} + +int +print_insn_tilegx (unsigned char * memaddr) +{ + struct tilegx_decoded_instruction + decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; + unsigned char opbuf[TILEGX_BUNDLE_SIZE_IN_BYTES]; + int i, num_instructions, num_printed; + tilegx_mnemonic padding_mnemonic; + + memcpy((void *)opbuf, (void *)memaddr, TILEGX_BUNDLE_SIZE_IN_BYTES); + + /* Parse the instructions in the bundle. */ + num_instructions = + parse_insn_tilegx (*(unsigned long long *)opbuf, (unsigned long long)memaddr, decoded); + + /* Print the instructions in the bundle. */ + printf("{ "); + num_printed = 0; + + /* Determine which nop opcode is used for padding and should be skipped. */ + padding_mnemonic = TILEGX_OPC_FNOP; + for (i = 0; i < num_instructions; i++) + { + if (!decoded[i].opcode->can_bundle) + { + /* Instructions that cannot be bundled are padded out with nops, + rather than fnops. Displaying them is always clutter. */ + padding_mnemonic = TILEGX_OPC_NOP; + break; + } + } + + for (i = 0; i < num_instructions; i++) + { + const struct tilegx_opcode *opcode = decoded[i].opcode; + const char *name; + int j; + + /* Do not print out fnops, unless everything is an fnop, in + which case we will print out just the last one. */ + if (opcode->mnemonic == padding_mnemonic + && (num_printed > 0 || i + 1 < num_instructions)) + continue; + + if (num_printed > 0) + printf(" ; "); + ++num_printed; + + name = opcode->name; + if (name == NULL) + name = ""; + printf("%s", name); + + for (j = 0; j < opcode->num_operands; j++) + { + unsigned long long num; + const struct tilegx_operand *op; + const char *spr_name; + + if (j > 0) + printf (","); + printf (" "); + + num = decoded[i].operand_values[j]; + + op = decoded[i].operands[j]; + switch (op->type) + { + case TILEGX_OP_TYPE_REGISTER: + printf ("%s", tilegx_register_names[(int)num]); + break; + case TILEGX_OP_TYPE_SPR: + spr_name = get_tilegx_spr_name(num); + if (spr_name != NULL) + printf ("%s", spr_name); + else + printf ("%d", (int)num); + break; + case TILEGX_OP_TYPE_IMMEDIATE: + printf ("%d", (int)num); + break; + case TILEGX_OP_TYPE_ADDRESS: + printf ("0x%016llx", num); + break; + default: + abort (); + } + } + } + printf (" }\n"); + + return TILEGX_BUNDLE_SIZE_IN_BYTES; +} diff --git a/tools/pcre/sljit/sljitNativeTILEGX_64.c b/tools/pcre/sljit/sljitNativeTILEGX_64.c new file mode 100644 index 00000000..d0b392e7 --- /dev/null +++ b/tools/pcre/sljit/sljitNativeTILEGX_64.c @@ -0,0 +1,2580 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved. + * 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. + */ + +/* TileGX architecture. */ +/* Contributed by Tilera Corporation. */ +#include "sljitNativeTILEGX-encoder.c" + +#define SIMM_8BIT_MAX (0x7f) +#define SIMM_8BIT_MIN (-0x80) +#define SIMM_16BIT_MAX (0x7fff) +#define SIMM_16BIT_MIN (-0x8000) +#define SIMM_17BIT_MAX (0xffff) +#define SIMM_17BIT_MIN (-0x10000) +#define SIMM_32BIT_MIN (-0x80000000) +#define SIMM_32BIT_MAX (0x7fffffff) +#define SIMM_48BIT_MIN (0x800000000000L) +#define SIMM_48BIT_MAX (0x7fffffff0000L) +#define IMM16(imm) ((imm) & 0xffff) + +#define UIMM_16BIT_MAX (0xffff) + +#define TMP_REG1 (SLJIT_NO_REGISTERS + 1) +#define TMP_REG2 (SLJIT_NO_REGISTERS + 2) +#define TMP_REG3 (SLJIT_NO_REGISTERS + 3) +#define ADDR_TMP (SLJIT_NO_REGISTERS + 4) +#define PIC_ADDR_REG TMP_REG2 + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { + 63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7 +}; + +#define SLJIT_LOCALS_REG_mapped 54 +#define TMP_REG1_mapped 5 +#define TMP_REG2_mapped 16 +#define TMP_REG3_mapped 6 +#define ADDR_TMP_mapped 7 +#define SLJIT_SAVED_REG1_mapped 30 +#define SLJIT_SAVED_REG2_mapped 31 +#define SLJIT_SAVED_REG3_mapped 32 +#define SLJIT_SAVED_EREG1_mapped 33 +#define SLJIT_SAVED_EREG2_mapped 34 + +/* Flags are keept in volatile registers. */ +#define EQUAL_FLAG 8 +/* And carry flag as well. */ +#define ULESS_FLAG 9 +#define UGREATER_FLAG 10 +#define LESS_FLAG 11 +#define GREATER_FLAG 12 +#define OVERFLOW_FLAG 13 + +#define ZERO 63 +#define RA 55 +#define TMP_EREG1 14 +#define TMP_EREG2 15 + +#define LOAD_DATA 0x01 +#define WORD_DATA 0x00 +#define BYTE_DATA 0x02 +#define HALF_DATA 0x04 +#define INT_DATA 0x06 +#define SIGNED_DATA 0x08 +#define DOUBLE_DATA 0x10 + +/* Separates integer and floating point registers */ +#define GPR_REG 0xf + +#define MEM_MASK 0x1f + +#define WRITE_BACK 0x00020 +#define ARG_TEST 0x00040 +#define ALT_KEEP_CACHE 0x00080 +#define CUMULATIVE_OP 0x00100 +#define LOGICAL_OP 0x00200 +#define IMM_OP 0x00400 +#define SRC2_IMM 0x00800 + +#define UNUSED_DEST 0x01000 +#define REG_DEST 0x02000 +#define REG1_SOURCE 0x04000 +#define REG2_SOURCE 0x08000 +#define SLOW_SRC1 0x10000 +#define SLOW_SRC2 0x20000 +#define SLOW_DEST 0x40000 + +/* 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)))) + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char *sljit_get_platform_name(void) +{ + return "TileGX" SLJIT_CPUINFO; +} + +/* Length of an instruction word */ +typedef sljit_uw sljit_ins; + +struct jit_instr { + const struct tilegx_opcode* opcode; + tilegx_pipeline pipe; + unsigned long input_registers; + unsigned long output_registers; + int operand_value[4]; + int line; +}; + +/* Opcode Helper Macros */ +#define TILEGX_X_MODE 0 + +#define X_MODE create_Mode(TILEGX_X_MODE) + +#define FNOP_X0 \ + create_Opcode_X0(RRR_0_OPCODE_X0) | \ + create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ + create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0) + +#define FNOP_X1 \ + create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ + create_UnaryOpcodeExtension_X1(FNOP_UNARY_OPCODE_X1) + +#define NOP \ + create_Mode(TILEGX_X_MODE) | FNOP_X0 | FNOP_X1 + +#define ANOP_X0 \ + create_Opcode_X0(RRR_0_OPCODE_X0) | \ + create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ + create_UnaryOpcodeExtension_X0(NOP_UNARY_OPCODE_X0) + +#define BPT create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ + create_UnaryOpcodeExtension_X1(ILL_UNARY_OPCODE_X1) | \ + create_Dest_X1(0x1C) | create_SrcA_X1(0x25) | ANOP_X0 + +#define ADD_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(ADD_RRR_0_OPCODE_X1) | FNOP_X0 + +#define ADDI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ + create_Imm8OpcodeExtension_X1(ADDI_IMM8_OPCODE_X1) | FNOP_X0 + +#define SUB_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(SUB_RRR_0_OPCODE_X1) | FNOP_X0 + +#define NOR_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(NOR_RRR_0_OPCODE_X1) | FNOP_X0 + +#define OR_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(OR_RRR_0_OPCODE_X1) | FNOP_X0 + +#define AND_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(AND_RRR_0_OPCODE_X1) | FNOP_X0 + +#define XOR_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(XOR_RRR_0_OPCODE_X1) | FNOP_X0 + +#define CMOVNEZ_X0 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ + create_RRROpcodeExtension_X0(CMOVNEZ_RRR_0_OPCODE_X0) | FNOP_X1 + +#define CMOVEQZ_X0 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ + create_RRROpcodeExtension_X0(CMOVEQZ_RRR_0_OPCODE_X0) | FNOP_X1 + +#define ADDLI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(ADDLI_OPCODE_X1) | FNOP_X0 + +#define V4INT_L_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(V4INT_L_RRR_0_OPCODE_X1) | FNOP_X0 + +#define BFEXTU_X0 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \ + create_BFOpcodeExtension_X0(BFEXTU_BF_OPCODE_X0) | FNOP_X1 + +#define BFEXTS_X0 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \ + create_BFOpcodeExtension_X0(BFEXTS_BF_OPCODE_X0) | FNOP_X1 + +#define SHL16INSLI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHL16INSLI_OPCODE_X1) | FNOP_X0 + +#define ST_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(ST_RRR_0_OPCODE_X1) | create_Dest_X1(0x0) | FNOP_X0 + +#define LD_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ + create_UnaryOpcodeExtension_X1(LD_UNARY_OPCODE_X1) | FNOP_X0 + +#define JR_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ + create_UnaryOpcodeExtension_X1(JR_UNARY_OPCODE_X1) | FNOP_X0 + +#define JALR_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \ + create_UnaryOpcodeExtension_X1(JALR_UNARY_OPCODE_X1) | FNOP_X0 + +#define CLZ_X0 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \ + create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \ + create_UnaryOpcodeExtension_X0(CNTLZ_UNARY_OPCODE_X0) | FNOP_X1 + +#define CMPLTUI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ + create_Imm8OpcodeExtension_X1(CMPLTUI_IMM8_OPCODE_X1) | FNOP_X0 + +#define CMPLTU_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(CMPLTU_RRR_0_OPCODE_X1) | FNOP_X0 + +#define CMPLTS_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(CMPLTS_RRR_0_OPCODE_X1) | FNOP_X0 + +#define XORI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ + create_Imm8OpcodeExtension_X1(XORI_IMM8_OPCODE_X1) | FNOP_X0 + +#define ORI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ + create_Imm8OpcodeExtension_X1(ORI_IMM8_OPCODE_X1) | FNOP_X0 + +#define ANDI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \ + create_Imm8OpcodeExtension_X1(ANDI_IMM8_OPCODE_X1) | FNOP_X0 + +#define SHLI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ + create_ShiftOpcodeExtension_X1(SHLI_SHIFT_OPCODE_X1) | FNOP_X0 + +#define SHL_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(SHL_RRR_0_OPCODE_X1) | FNOP_X0 + +#define SHRSI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ + create_ShiftOpcodeExtension_X1(SHRSI_SHIFT_OPCODE_X1) | FNOP_X0 + +#define SHRS_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(SHRS_RRR_0_OPCODE_X1) | FNOP_X0 + +#define SHRUI_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \ + create_ShiftOpcodeExtension_X1(SHRUI_SHIFT_OPCODE_X1) | FNOP_X0 + +#define SHRU_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \ + create_RRROpcodeExtension_X1(SHRU_RRR_0_OPCODE_X1) | FNOP_X0 + +#define BEQZ_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \ + create_BrType_X1(BEQZ_BRANCH_OPCODE_X1) | FNOP_X0 + +#define BNEZ_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \ + create_BrType_X1(BNEZ_BRANCH_OPCODE_X1) | FNOP_X0 + +#define J_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \ + create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) | FNOP_X0 + +#define JAL_X1 \ + create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \ + create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) | FNOP_X0 + +#define DEST_X0(x) create_Dest_X0(x) +#define SRCA_X0(x) create_SrcA_X0(x) +#define SRCB_X0(x) create_SrcB_X0(x) +#define DEST_X1(x) create_Dest_X1(x) +#define SRCA_X1(x) create_SrcA_X1(x) +#define SRCB_X1(x) create_SrcB_X1(x) +#define IMM16_X1(x) create_Imm16_X1(x) +#define IMM8_X1(x) create_Imm8_X1(x) +#define BFSTART_X0(x) create_BFStart_X0(x) +#define BFEND_X0(x) create_BFEnd_X0(x) +#define SHIFTIMM_X1(x) create_ShAmt_X1(x) +#define JOFF_X1(x) create_JumpOff_X1(x) +#define BOFF_X1(x) create_BrOff_X1(x) + +static SLJIT_CONST tilegx_mnemonic data_transfer_insts[16] = { + /* u w s */ TILEGX_OPC_ST /* st */, + /* u w l */ TILEGX_OPC_LD /* ld */, + /* u b s */ TILEGX_OPC_ST1 /* st1 */, + /* u b l */ TILEGX_OPC_LD1U /* ld1u */, + /* u h s */ TILEGX_OPC_ST2 /* st2 */, + /* u h l */ TILEGX_OPC_LD2U /* ld2u */, + /* u i s */ TILEGX_OPC_ST4 /* st4 */, + /* u i l */ TILEGX_OPC_LD4U /* ld4u */, + /* s w s */ TILEGX_OPC_ST /* st */, + /* s w l */ TILEGX_OPC_LD /* ld */, + /* s b s */ TILEGX_OPC_ST1 /* st1 */, + /* s b l */ TILEGX_OPC_LD1S /* ld1s */, + /* s h s */ TILEGX_OPC_ST2 /* st2 */, + /* s h l */ TILEGX_OPC_LD2S /* ld2s */, + /* s i s */ TILEGX_OPC_ST4 /* st4 */, + /* s i l */ TILEGX_OPC_LD4S /* ld4s */, +}; + +#ifdef TILEGX_JIT_DEBUG +static sljit_si push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line) +{ + sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr = ins; + compiler->size++; + printf("|%04d|S0|:\t\t", line); + print_insn_tilegx(ptr); + return SLJIT_SUCCESS; +} + +static sljit_si push_inst_nodebug(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; +} + +#define push_inst(a, b) push_inst_debug(a, b, __LINE__) +#else +static sljit_si 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; +} +#endif + +#define BUNDLE_FORMAT_MASK(p0, p1, p2) \ + ((p0) | ((p1) << 8) | ((p2) << 16)) + +#define BUNDLE_FORMAT(p0, p1, p2) \ + { \ + { \ + (tilegx_pipeline)(p0), \ + (tilegx_pipeline)(p1), \ + (tilegx_pipeline)(p2) \ + }, \ + BUNDLE_FORMAT_MASK(1 << (p0), 1 << (p1), (1 << (p2))) \ + } + +#define NO_PIPELINE TILEGX_NUM_PIPELINE_ENCODINGS + +#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1) + +#define PI(encoding) \ + push_inst(compiler, encoding) + +#define PB3(opcode, dst, srca, srcb) \ + push_3_buffer(compiler, opcode, dst, srca, srcb, __LINE__) + +#define PB2(opcode, dst, src) \ + push_2_buffer(compiler, opcode, dst, src, __LINE__) + +#define JR(reg) \ + push_jr_buffer(compiler, TILEGX_OPC_JR, reg, __LINE__) + +#define ADD(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_ADD, dst, srca, srcb, __LINE__) + +#define SUB(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__) + +#define NOR(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__) + +#define OR(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_OR, dst, srca, srcb, __LINE__) + +#define XOR(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_XOR, dst, srca, srcb, __LINE__) + +#define AND(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_AND, dst, srca, srcb, __LINE__) + +#define CLZ(dst, src) \ + push_2_buffer(compiler, TILEGX_OPC_CLZ, dst, src, __LINE__) + +#define SHLI(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_SHLI, dst, srca, srcb, __LINE__) + +#define SHRUI(dst, srca, imm) \ + push_3_buffer(compiler, TILEGX_OPC_SHRUI, dst, srca, imm, __LINE__) + +#define XORI(dst, srca, imm) \ + push_3_buffer(compiler, TILEGX_OPC_XORI, dst, srca, imm, __LINE__) + +#define ORI(dst, srca, imm) \ + push_3_buffer(compiler, TILEGX_OPC_ORI, dst, srca, imm, __LINE__) + +#define CMPLTU(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_CMPLTU, dst, srca, srcb, __LINE__) + +#define CMPLTS(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_CMPLTS, dst, srca, srcb, __LINE__) + +#define CMPLTUI(dst, srca, imm) \ + push_3_buffer(compiler, TILEGX_OPC_CMPLTUI, dst, srca, imm, __LINE__) + +#define CMOVNEZ(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_CMOVNEZ, dst, srca, srcb, __LINE__) + +#define CMOVEQZ(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_CMOVEQZ, dst, srca, srcb, __LINE__) + +#define ADDLI(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_ADDLI, dst, srca, srcb, __LINE__) + +#define SHL16INSLI(dst, srca, srcb) \ + push_3_buffer(compiler, TILEGX_OPC_SHL16INSLI, dst, srca, srcb, __LINE__) + +#define LD_ADD(dst, addr, adjust) \ + push_3_buffer(compiler, TILEGX_OPC_LD_ADD, dst, addr, adjust, __LINE__) + +#define ST_ADD(src, addr, adjust) \ + push_3_buffer(compiler, TILEGX_OPC_ST_ADD, src, addr, adjust, __LINE__) + +#define LD(dst, addr) \ + push_2_buffer(compiler, TILEGX_OPC_LD, dst, addr, __LINE__) + +#define BFEXTU(dst, src, start, end) \ + push_4_buffer(compiler, TILEGX_OPC_BFEXTU, dst, src, start, end, __LINE__) + +#define BFEXTS(dst, src, start, end) \ + push_4_buffer(compiler, TILEGX_OPC_BFEXTS, dst, src, start, end, __LINE__) + +#define ADD_SOLO(dest, srca, srcb) \ + push_inst(compiler, ADD_X1 | DEST_X1(dest) | SRCA_X1(srca) | SRCB_X1(srcb)) + +#define ADDI_SOLO(dest, srca, imm) \ + push_inst(compiler, ADDI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM8_X1(imm)) + +#define ADDLI_SOLO(dest, srca, imm) \ + push_inst(compiler, ADDLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm)) + +#define SHL16INSLI_SOLO(dest, srca, imm) \ + push_inst(compiler, SHL16INSLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm)) + +#define JALR_SOLO(reg) \ + push_inst(compiler, JALR_X1 | SRCA_X1(reg)) + +#define JR_SOLO(reg) \ + push_inst(compiler, JR_X1 | SRCA_X1(reg)) + +struct Format { + /* Mapping of bundle issue slot to assigned pipe. */ + tilegx_pipeline pipe[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; + + /* Mask of pipes used by this bundle. */ + unsigned int pipe_mask; +}; + +const struct Format formats[] = +{ + /* In Y format we must always have something in Y2, since it has + * no fnop, so this conveys that Y2 must always be used. */ + BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, NO_PIPELINE), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, NO_PIPELINE), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, NO_PIPELINE), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, NO_PIPELINE), + + /* Y format has three instructions. */ + BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1), + BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0), + + /* X format has only two instructions. */ + BUNDLE_FORMAT(TILEGX_PIPELINE_X0, TILEGX_PIPELINE_X1, NO_PIPELINE), + BUNDLE_FORMAT(TILEGX_PIPELINE_X1, TILEGX_PIPELINE_X0, NO_PIPELINE) +}; + + +struct jit_instr inst_buf[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; +unsigned long inst_buf_index; + +tilegx_pipeline get_any_valid_pipe(const struct tilegx_opcode* opcode) +{ + /* FIXME: tile: we could pregenerate this. */ + int pipe; + for (pipe = 0; ((opcode->pipes & (1 << pipe)) == 0 && pipe < TILEGX_NUM_PIPELINE_ENCODINGS); pipe++) + ; + return (tilegx_pipeline)(pipe); +} + +void insert_nop(tilegx_mnemonic opc, int line) +{ + const struct tilegx_opcode* opcode = NULL; + + memmove(&inst_buf[1], &inst_buf[0], inst_buf_index * sizeof inst_buf[0]); + + opcode = &tilegx_opcodes[opc]; + inst_buf[0].opcode = opcode; + inst_buf[0].pipe = get_any_valid_pipe(opcode); + inst_buf[0].input_registers = 0; + inst_buf[0].output_registers = 0; + inst_buf[0].line = line; + ++inst_buf_index; +} + +const struct Format* compute_format() +{ + unsigned int compatible_pipes = BUNDLE_FORMAT_MASK( + inst_buf[0].opcode->pipes, + inst_buf[1].opcode->pipes, + (inst_buf_index == 3 ? inst_buf[2].opcode->pipes : (1 << NO_PIPELINE))); + + const struct Format* match = NULL; + const struct Format *b = NULL; + unsigned int i = 0; + for (i; i < sizeof formats / sizeof formats[0]; i++) { + b = &formats[i]; + if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) { + match = b; + break; + } + } + + return match; +} + +sljit_si assign_pipes() +{ + unsigned long output_registers = 0; + unsigned int i = 0; + + if (inst_buf_index == 1) { + tilegx_mnemonic opc = inst_buf[0].opcode->can_bundle + ? TILEGX_OPC_FNOP : TILEGX_OPC_NOP; + insert_nop(opc, __LINE__); + } + + const struct Format* match = compute_format(); + + if (match == NULL) + return -1; + + for (i = 0; i < inst_buf_index; i++) { + + if ((i > 0) && ((inst_buf[i].input_registers & output_registers) != 0)) + return -1; + + if ((i > 0) && ((inst_buf[i].output_registers & output_registers) != 0)) + return -1; + + /* Don't include Rzero in the match set, to avoid triggering + needlessly on 'prefetch' instrs. */ + + output_registers |= inst_buf[i].output_registers & 0xFFFFFFFFFFFFFFL; + + inst_buf[i].pipe = match->pipe[i]; + } + + /* If only 2 instrs, and in Y-mode, insert a nop. */ + if (inst_buf_index == 2 && !tilegx_is_x_pipeline(match->pipe[0])) { + insert_nop(TILEGX_OPC_FNOP, __LINE__); + + /* Select the yet unassigned pipe. */ + tilegx_pipeline pipe = (tilegx_pipeline)(((TILEGX_PIPELINE_Y0 + + TILEGX_PIPELINE_Y1 + TILEGX_PIPELINE_Y2) + - (inst_buf[1].pipe + inst_buf[2].pipe))); + + inst_buf[0].pipe = pipe; + } + + return 0; +} + +tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst) +{ + int i, val; + const struct tilegx_opcode* opcode = inst->opcode; + tilegx_bundle_bits bits = opcode->fixed_bit_values[inst->pipe]; + + const struct tilegx_operand* operand = NULL; + for (i = 0; i < opcode->num_operands; i++) { + operand = &tilegx_operands[opcode->operands[inst->pipe][i]]; + val = inst->operand_value[i]; + + bits |= operand->insert(val); + } + + return bits; +} + +static sljit_si update_buffer(struct sljit_compiler *compiler) +{ + int count; + int i; + int orig_index = inst_buf_index; + struct jit_instr inst0 = inst_buf[0]; + struct jit_instr inst1 = inst_buf[1]; + struct jit_instr inst2 = inst_buf[2]; + tilegx_bundle_bits bits = 0; + + /* If the bundle is valid as is, perform the encoding and return 1. */ + if (assign_pipes() == 0) { + for (i = 0; i < inst_buf_index; i++) { + bits |= get_bundle_bit(inst_buf + i); +#ifdef TILEGX_JIT_DEBUG + printf("|%04d", inst_buf[i].line); +#endif + } +#ifdef TILEGX_JIT_DEBUG + if (inst_buf_index == 3) + printf("|M0|:\t"); + else + printf("|M0|:\t\t"); + print_insn_tilegx(&bits); +#endif + + inst_buf_index = 0; + +#ifdef TILEGX_JIT_DEBUG + return push_inst_nodebug(compiler, bits); +#else + return push_inst(compiler, bits); +#endif + } + + /* If the bundle is invalid, split it in two. First encode the first two + (or possibly 1) instructions, and then the last, separately. Note that + assign_pipes may have re-ordered the instrs (by inserting no-ops in + lower slots) so we need to reset them. */ + + inst_buf_index = orig_index - 1; + inst_buf[0] = inst0; + inst_buf[1] = inst1; + inst_buf[2] = inst2; + if (assign_pipes() == 0) { + for (i = 0; i < inst_buf_index; i++) { + bits |= get_bundle_bit(inst_buf + i); +#ifdef TILEGX_JIT_DEBUG + printf("|%04d", inst_buf[i].line); +#endif + } + +#ifdef TILEGX_JIT_DEBUG + if (inst_buf_index == 3) + printf("|M1|:\t"); + else + printf("|M1|:\t\t"); + print_insn_tilegx(&bits); +#endif + + if ((orig_index - 1) == 2) { + inst_buf[0] = inst2; + inst_buf_index = 1; + } else if ((orig_index - 1) == 1) { + inst_buf[0] = inst1; + inst_buf_index = 1; + } else + SLJIT_ASSERT_STOP(); + +#ifdef TILEGX_JIT_DEBUG + return push_inst_nodebug(compiler, bits); +#else + return push_inst(compiler, bits); +#endif + } else { + /* We had 3 instrs of which the first 2 can't live in the same bundle. + Split those two. Note that we don't try to then combine the second + and third instr into a single bundle. First instruction: */ + inst_buf_index = 1; + inst_buf[0] = inst0; + inst_buf[1] = inst1; + inst_buf[2] = inst2; + if (assign_pipes() == 0) { + for (i = 0; i < inst_buf_index; i++) { + bits |= get_bundle_bit(inst_buf + i); +#ifdef TILEGX_JIT_DEBUG + printf("|%04d", inst_buf[i].line); +#endif + } + +#ifdef TILEGX_JIT_DEBUG + if (inst_buf_index == 3) + printf("|M2|:\t"); + else + printf("|M2|:\t\t"); + print_insn_tilegx(&bits); +#endif + + inst_buf[0] = inst1; + inst_buf[1] = inst2; + inst_buf_index = orig_index - 1; +#ifdef TILEGX_JIT_DEBUG + return push_inst_nodebug(compiler, bits); +#else + return push_inst(compiler, bits); +#endif + } else + SLJIT_ASSERT_STOP(); + } + + SLJIT_ASSERT_STOP(); +} + +static sljit_si flush_buffer(struct sljit_compiler *compiler) +{ + while (inst_buf_index != 0) + update_buffer(compiler); +} + +static sljit_si push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line) +{ + if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) + FAIL_IF(update_buffer(compiler)); + + const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; + inst_buf[inst_buf_index].opcode = opcode; + inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); + inst_buf[inst_buf_index].operand_value[0] = op0; + inst_buf[inst_buf_index].operand_value[1] = op1; + inst_buf[inst_buf_index].operand_value[2] = op2; + inst_buf[inst_buf_index].operand_value[3] = op3; + inst_buf[inst_buf_index].input_registers = 1L << op1; + inst_buf[inst_buf_index].output_registers = 1L << op0; + inst_buf[inst_buf_index].line = line; + inst_buf_index++; + + return SLJIT_SUCCESS; +} + +static sljit_si push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line) +{ + if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) + FAIL_IF(update_buffer(compiler)); + + const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; + inst_buf[inst_buf_index].opcode = opcode; + inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); + inst_buf[inst_buf_index].operand_value[0] = op0; + inst_buf[inst_buf_index].operand_value[1] = op1; + inst_buf[inst_buf_index].operand_value[2] = op2; + inst_buf[inst_buf_index].line = line; + + switch (opc) { + case TILEGX_OPC_ST_ADD: + inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1); + inst_buf[inst_buf_index].output_registers = 1L << op0; + break; + case TILEGX_OPC_LD_ADD: + inst_buf[inst_buf_index].input_registers = 1L << op1; + inst_buf[inst_buf_index].output_registers = (1L << op0) | (1L << op1); + break; + case TILEGX_OPC_ADD: + case TILEGX_OPC_AND: + case TILEGX_OPC_SUB: + case TILEGX_OPC_OR: + case TILEGX_OPC_XOR: + case TILEGX_OPC_NOR: + case TILEGX_OPC_SHL: + case TILEGX_OPC_SHRU: + case TILEGX_OPC_SHRS: + case TILEGX_OPC_CMPLTU: + case TILEGX_OPC_CMPLTS: + case TILEGX_OPC_CMOVEQZ: + case TILEGX_OPC_CMOVNEZ: + inst_buf[inst_buf_index].input_registers = (1L << op1) | (1L << op2); + inst_buf[inst_buf_index].output_registers = 1L << op0; + break; + case TILEGX_OPC_ADDLI: + case TILEGX_OPC_XORI: + case TILEGX_OPC_ORI: + case TILEGX_OPC_SHLI: + case TILEGX_OPC_SHRUI: + case TILEGX_OPC_SHRSI: + case TILEGX_OPC_SHL16INSLI: + case TILEGX_OPC_CMPLTUI: + case TILEGX_OPC_CMPLTSI: + inst_buf[inst_buf_index].input_registers = 1L << op1; + inst_buf[inst_buf_index].output_registers = 1L << op0; + break; + default: + printf("unrecoginzed opc: %s\n", opcode->name); + SLJIT_ASSERT_STOP(); + } + + inst_buf_index++; + + return SLJIT_SUCCESS; +} + +static sljit_si push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line) +{ + if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) + FAIL_IF(update_buffer(compiler)); + + const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; + inst_buf[inst_buf_index].opcode = opcode; + inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); + inst_buf[inst_buf_index].operand_value[0] = op0; + inst_buf[inst_buf_index].operand_value[1] = op1; + inst_buf[inst_buf_index].line = line; + + switch (opc) { + case TILEGX_OPC_BEQZ: + case TILEGX_OPC_BNEZ: + inst_buf[inst_buf_index].input_registers = 1L << op0; + break; + case TILEGX_OPC_ST: + case TILEGX_OPC_ST1: + case TILEGX_OPC_ST2: + case TILEGX_OPC_ST4: + inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1); + inst_buf[inst_buf_index].output_registers = 0; + break; + case TILEGX_OPC_CLZ: + case TILEGX_OPC_LD: + case TILEGX_OPC_LD1U: + case TILEGX_OPC_LD1S: + case TILEGX_OPC_LD2U: + case TILEGX_OPC_LD2S: + case TILEGX_OPC_LD4U: + case TILEGX_OPC_LD4S: + inst_buf[inst_buf_index].input_registers = 1L << op1; + inst_buf[inst_buf_index].output_registers = 1L << op0; + break; + default: + printf("unrecoginzed opc: %s\n", opcode->name); + SLJIT_ASSERT_STOP(); + } + + inst_buf_index++; + + return SLJIT_SUCCESS; +} + +static sljit_si push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line) +{ + if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) + FAIL_IF(update_buffer(compiler)); + + const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; + inst_buf[inst_buf_index].opcode = opcode; + inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); + inst_buf[inst_buf_index].input_registers = 0; + inst_buf[inst_buf_index].output_registers = 0; + inst_buf[inst_buf_index].line = line; + inst_buf_index++; + + return SLJIT_SUCCESS; +} + +static sljit_si push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line) +{ + if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) + FAIL_IF(update_buffer(compiler)); + + const struct tilegx_opcode* opcode = &tilegx_opcodes[opc]; + inst_buf[inst_buf_index].opcode = opcode; + inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode); + inst_buf[inst_buf_index].operand_value[0] = op0; + inst_buf[inst_buf_index].input_registers = 1L << op0; + inst_buf[inst_buf_index].output_registers = 0; + inst_buf[inst_buf_index].line = line; + inst_buf_index++; + + return flush_buffer(compiler); +} + +static SLJIT_INLINE sljit_ins * detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_sw 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--; + + diff = ((sljit_sw) target_addr - (sljit_sw) inst) >> 3; + if (diff <= SIMM_17BIT_MAX && diff >= SIMM_17BIT_MIN) { + jump->flags |= PATCH_B; + + if (!(jump->flags & IS_COND)) { + if (jump->flags & IS_JAL) { + jump->flags &= ~(PATCH_B); + jump->flags |= PATCH_J; + inst[0] = JAL_X1; + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(inst); +#endif + } else { + inst[0] = BEQZ_X1 | SRCA_X1(ZERO); + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(inst); +#endif + } + + return inst; + } + + inst[0] = inst[0] ^ (0x7L << 55); + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(inst); +#endif + jump->addr -= sizeof(sljit_ins); + return inst; + } + + if (jump->flags & IS_COND) { + if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) { + jump->flags |= PATCH_J; + inst[0] = (inst[0] & ~(BOFF_X1(-1))) | BOFF_X1(2); + inst[1] = J_X1; + return inst + 1; + } + + return code_ptr; + } + + if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) { + jump->flags |= PATCH_J; + + if (jump->flags & IS_JAL) { + inst[0] = JAL_X1; + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(inst); +#endif + + } else { + inst[0] = J_X1; + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(inst); +#endif + } + + return inst; + } + + return code_ptr; +} + +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 >> 3); + 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 (jump->flags & IS_JAL) + jump->addr = (sljit_uw)(code_ptr - 4); + else + jump->addr = (sljit_uw)(code_ptr - 3); + + code_ptr = detect_jump_type(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 <= (sljit_sw)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_sw)(addr - (jump->addr)) >> 3; + SLJIT_ASSERT((sljit_sw) addr <= SIMM_17BIT_MAX && (sljit_sw) addr >= SIMM_17BIT_MIN); + buf_ptr[0] = (buf_ptr[0] & ~(BOFF_X1(-1))) | BOFF_X1(addr); + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(buf_ptr); +#endif + break; + } + + if (jump->flags & PATCH_J) { + SLJIT_ASSERT((addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)); + addr = (sljit_sw)(addr - (jump->addr)) >> 3; + buf_ptr[0] = (buf_ptr[0] & ~(JOFF_X1(-1))) | JOFF_X1(addr); + +#ifdef TILEGX_JIT_DEBUG + printf("[runtime relocate]%04d:\t", __LINE__); + print_insn_tilegx(buf_ptr); +#endif + break; + } + + SLJIT_ASSERT(!(jump->flags & IS_JAL)); + + /* Set the fields of immediate loads. */ + buf_ptr[0] = (buf_ptr[0] & ~(0xFFFFL << 43)) | (((addr >> 32) & 0xFFFFL) << 43); + buf_ptr[1] = (buf_ptr[1] & ~(0xFFFFL << 43)) | (((addr >> 16) & 0xFFFFL) << 43); + buf_ptr[2] = (buf_ptr[2] & ~(0xFFFFL << 43)) | ((addr & 0xFFFFL) << 43); + } while (0); + + jump = jump->next; + } + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); + SLJIT_CACHE_FLUSH(code, code_ptr); + return code; +} + +static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +{ + + if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN) + return ADDLI(dst_ar, ZERO, imm); + + if (imm <= SIMM_32BIT_MAX && imm >= SIMM_32BIT_MIN) { + FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 16)); + return SHL16INSLI(dst_ar, dst_ar, imm); + } + + if (imm <= SIMM_48BIT_MAX && imm >= SIMM_48BIT_MIN) { + FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32)); + FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); + return SHL16INSLI(dst_ar, dst_ar, imm); + } + + FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 48)); + FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 32)); + FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); + return SHL16INSLI(dst_ar, dst_ar, imm); +} + +static sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush) +{ + /* Should *not* be optimized as load_immediate, as pcre relocation + mechanism will match this fixed 4-instruction pattern. */ + if (flush) { + FAIL_IF(ADDLI_SOLO(dst_ar, ZERO, imm >> 32)); + FAIL_IF(SHL16INSLI_SOLO(dst_ar, dst_ar, imm >> 16)); + return SHL16INSLI_SOLO(dst_ar, dst_ar, imm); + } + + FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32)); + FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16)); + return SHL16INSLI(dst_ar, dst_ar, imm); +} + +static sljit_si emit_const_64(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush) +{ + /* Should *not* be optimized as load_immediate, as pcre relocation + mechanism will match this fixed 4-instruction pattern. */ + if (flush) { + FAIL_IF(ADDLI_SOLO(reg_map[dst_ar], ZERO, imm >> 48)); + FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 32)); + FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 16)); + return SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm); + } + + FAIL_IF(ADDLI(reg_map[dst_ar], ZERO, imm >> 48)); + FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 32)); + FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 16)); + return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + sljit_ins base; + sljit_ins bundle = 0; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + local_size += (saveds + 1) * sizeof(sljit_sw); + local_size = (local_size + 7) & ~7; + compiler->local_size = local_size; + + if (local_size <= SIMM_16BIT_MAX) { + /* Frequent case. */ + FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, -local_size)); + base = SLJIT_LOCALS_REG_mapped; + } else { + FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size)); + FAIL_IF(ADD(TMP_REG2_mapped, SLJIT_LOCALS_REG_mapped, ZERO)); + FAIL_IF(SUB(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped)); + base = TMP_REG2_mapped; + local_size = 0; + } + + FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8)); + FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8)); + + if (saveds >= 1) + FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG1_mapped, -8)); + + if (saveds >= 2) + FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG2_mapped, -8)); + + if (saveds >= 3) + FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG3_mapped, -8)); + + if (saveds >= 4) + FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_EREG1_mapped, -8)); + + if (saveds >= 5) + FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_EREG2_mapped, -8)); + + if (args >= 1) + FAIL_IF(ADD(SLJIT_SAVED_REG1_mapped, 0, ZERO)); + + if (args >= 2) + FAIL_IF(ADD(SLJIT_SAVED_REG2_mapped, 1, ZERO)); + + if (args >= 3) + FAIL_IF(ADD(SLJIT_SAVED_REG3_mapped, 2, ZERO)); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +{ + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); + + compiler->scratches = scratches; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + local_size += (saveds + 1) * sizeof(sljit_sw); + compiler->local_size = (local_size + 7) & ~7; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +{ + sljit_si local_size; + sljit_ins base; + int addr_initialized = 0; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + local_size = compiler->local_size; + if (local_size <= SIMM_16BIT_MAX) + base = SLJIT_LOCALS_REG_mapped; + else { + FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size)); + FAIL_IF(ADD(TMP_REG1_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped)); + base = TMP_REG1_mapped; + local_size = 0; + } + + FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8)); + FAIL_IF(LD(RA, ADDR_TMP_mapped)); + + if (compiler->saveds >= 5) { + FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 48)); + addr_initialized = 1; + + FAIL_IF(LD_ADD(SLJIT_SAVED_EREG2_mapped, ADDR_TMP_mapped, 8)); + } + + if (compiler->saveds >= 4) { + if (addr_initialized == 0) { + FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 40)); + addr_initialized = 1; + } + + FAIL_IF(LD_ADD(SLJIT_SAVED_EREG1_mapped, ADDR_TMP_mapped, 8)); + } + + if (compiler->saveds >= 3) { + if (addr_initialized == 0) { + FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 32)); + addr_initialized = 1; + } + + FAIL_IF(LD_ADD(SLJIT_SAVED_REG3_mapped, ADDR_TMP_mapped, 8)); + } + + if (compiler->saveds >= 2) { + if (addr_initialized == 0) { + FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 24)); + addr_initialized = 1; + } + + FAIL_IF(LD_ADD(SLJIT_SAVED_REG2_mapped, ADDR_TMP_mapped, 8)); + } + + if (compiler->saveds >= 1) { + if (addr_initialized == 0) { + FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 16)); + /* addr_initialized = 1; no need to initialize as it's the last one. */ + } + + FAIL_IF(LD_ADD(SLJIT_SAVED_REG1_mapped, ADDR_TMP_mapped, 8)); + } + + if (compiler->local_size <= SIMM_16BIT_MAX) + FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, compiler->local_size)); + else + FAIL_IF(ADD(SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped, ZERO)); + + return JR(RA); +} + +/* reg_ar is an absoulute register! */ + +/* Can perform an operation using at most 1 instruction. */ +static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +{ + SLJIT_ASSERT(arg & SLJIT_MEM); + + if ((!(flags & WRITE_BACK) || !(arg & REG_MASK)) + && !(arg & OFFS_REG_MASK) && argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { + /* Works for both absoulte and relative addresses. */ + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[arg & REG_MASK], argw)); + + if (flags & LOAD_DATA) + FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped)); + else + FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar)); + + return -1; + } + + return 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); + + /* Simple operation except for updates. */ + if (arg & OFFS_REG_MASK) { + argw &= 0x3; + next_argw &= 0x3; + if (argw && argw == next_argw + && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK))) + return 1; + return 0; + } + + if (arg == next_arg) { + if (((next_argw - argw) <= SIMM_16BIT_MAX + && (next_argw - argw) >= SIMM_16BIT_MIN)) + return 1; + + return 0; + } + + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +{ + sljit_si tmp_ar, base; + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(next_arg & SLJIT_MEM)) { + next_arg = 0; + next_argw = 0; + } + + if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) + tmp_ar = reg_ar; + else + tmp_ar = TMP_REG1_mapped; + + base = arg & REG_MASK; + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + argw &= 0x3; + + if ((flags & WRITE_BACK) && reg_ar == reg_map[base]) { + SLJIT_ASSERT(!(flags & LOAD_DATA) && reg_map[TMP_REG1] != reg_ar); + FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO)); + reg_ar = TMP_REG1_mapped; + } + + /* Using the cache. */ + if (argw == compiler->cache_argw) { + if (!(flags & WRITE_BACK)) { + if (arg == compiler->cache_arg) { + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); + else + return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); + } + + if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { + if (arg == next_arg && argw == (next_argw & 0x3)) { + compiler->cache_arg = arg; + compiler->cache_argw = argw; + FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], TMP_REG3_mapped)); + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); + else + return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); + } + + FAIL_IF(ADD(tmp_ar, reg_map[base], TMP_REG3_mapped)); + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); + else + return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); + } + } else { + if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) { + FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); + else + return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); + } + } + } + + if (SLJIT_UNLIKELY(argw)) { + compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); + compiler->cache_argw = argw; + FAIL_IF(SHLI(TMP_REG3_mapped, reg_map[OFFS_REG(arg)], argw)); + } + + if (!(flags & WRITE_BACK)) { + if (arg == next_arg && argw == (next_argw & 0x3)) { + compiler->cache_arg = arg; + compiler->cache_argw = argw; + FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); + tmp_ar = TMP_REG3_mapped; + } else + FAIL_IF(ADD(tmp_ar, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); + + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); + else + return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); + } + + FAIL_IF(ADD(reg_map[base], reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3])); + + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); + else + return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); + } + + if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) { + /* Update only applies if a base register exists. */ + if (reg_ar == reg_map[base]) { + SLJIT_ASSERT(!(flags & LOAD_DATA) && TMP_REG1_mapped != reg_ar); + if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { + FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[base], argw)); + if (flags & LOAD_DATA) + FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped)); + else + FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar)); + + if (argw) + return ADDLI(reg_map[base], reg_map[base], argw); + + return SLJIT_SUCCESS; + } + + FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO)); + reg_ar = TMP_REG1_mapped; + } + + if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) { + if (argw) + FAIL_IF(ADDLI(reg_map[base], reg_map[base], argw)); + } else { + if (compiler->cache_arg == SLJIT_MEM + && argw - compiler->cache_argw <= SIMM_16BIT_MAX + && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { + if (argw != compiler->cache_argw) { + FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); + compiler->cache_argw = argw; + } + + FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); + } else { + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw)); + FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped)); + } + } + + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]); + else + return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar); + } + + if (compiler->cache_arg == arg + && argw - compiler->cache_argw <= SIMM_16BIT_MAX + && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { + if (argw != compiler->cache_argw) { + FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); + compiler->cache_argw = argw; + } + + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); + else + return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); + } + + if (compiler->cache_arg == SLJIT_MEM + && argw - compiler->cache_argw <= SIMM_16BIT_MAX + && argw - compiler->cache_argw >= SIMM_16BIT_MIN) { + if (argw != compiler->cache_argw) + FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw)); + } else { + compiler->cache_arg = SLJIT_MEM; + FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw)); + } + + compiler->cache_argw = argw; + + if (!base) { + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); + else + return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); + } + + if (arg == next_arg + && next_argw - argw <= SIMM_16BIT_MAX + && next_argw - argw >= SIMM_16BIT_MIN) { + compiler->cache_arg = arg; + FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, reg_map[base])); + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped); + else + return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar); + } + + FAIL_IF(ADD(tmp_ar, TMP_REG3_mapped, reg_map[base])); + + if (flags & LOAD_DATA) + return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar); + else + return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); +} + +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw 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 SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +{ + 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) + return SLJIT_SUCCESS; + + if (FAST_IS_REG(dst)) + return ADD(reg_map[dst], RA, ZERO); + + /* Memory. */ + return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) + FAIL_IF(ADD(RA, reg_map[src], ZERO)); + + else if (src & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RA, src, srcw)); + + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, RA, srcw)); + + return JR(RA); +} + +static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_si src1, sljit_sw src2) +{ + sljit_si overflow_ra = 0; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (dst != src2) + return ADD(reg_map[dst], reg_map[src2], ZERO); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SI) + return BFEXTS(reg_map[dst], reg_map[src2], 0, 31); + + return BFEXTU(reg_map[dst], reg_map[src2], 0, 31); + } else if (dst != src2) + SLJIT_ASSERT_STOP(); + + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) + return BFEXTS(reg_map[dst], reg_map[src2], 0, 7); + + return BFEXTU(reg_map[dst], reg_map[src2], 0, 7); + } else if (dst != src2) + SLJIT_ASSERT_STOP(); + + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) + return BFEXTS(reg_map[dst], reg_map[src2], 0, 15); + + return BFEXTU(reg_map[dst], reg_map[src2], 0, 15); + } 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(NOR(EQUAL_FLAG, reg_map[src2], reg_map[src2])); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(NOR(reg_map[dst], reg_map[src2], reg_map[src2])); + + return SLJIT_SUCCESS; + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (op & SLJIT_SET_E) + FAIL_IF(CLZ(EQUAL_FLAG, reg_map[src2])); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(CLZ(reg_map[dst], reg_map[src2])); + + return SLJIT_SUCCESS; + + case SLJIT_ADD: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + FAIL_IF(SHRUI(TMP_EREG1, reg_map[src1], 63)); + if (src2 < 0) + FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1)); + } + + if (op & SLJIT_SET_E) + FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], src2)); + + if (op & SLJIT_SET_C) { + if (src2 >= 0) + FAIL_IF(ORI(ULESS_FLAG ,reg_map[src1], src2)); + else { + FAIL_IF(ADDLI(ULESS_FLAG ,ZERO, src2)); + FAIL_IF(OR(ULESS_FLAG,reg_map[src1],ULESS_FLAG)); + } + } + + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2)); + + if (op & SLJIT_SET_O) { + FAIL_IF(SHRUI(OVERFLOW_FLAG, reg_map[dst], 63)); + + if (src2 < 0) + FAIL_IF(XORI(OVERFLOW_FLAG, OVERFLOW_FLAG, 1)); + } + } else { + if (op & SLJIT_SET_O) { + FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2])); + FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63)); + + if (src1 != dst) + overflow_ra = reg_map[src1]; + else if (src2 != dst) + overflow_ra = reg_map[src2]; + else { + /* Rare ocasion. */ + FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); + overflow_ra = TMP_EREG2; + } + } + + if (op & SLJIT_SET_E) + FAIL_IF(ADD(EQUAL_FLAG ,reg_map[src1], reg_map[src2])); + + if (op & SLJIT_SET_C) + FAIL_IF(OR(ULESS_FLAG,reg_map[src1], reg_map[src2])); + + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(ADD(reg_map[dst],reg_map[src1], reg_map[src2])); + + if (op & SLJIT_SET_O) { + FAIL_IF(XOR(OVERFLOW_FLAG,reg_map[dst], overflow_ra)); + FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63)); + } + } + + /* a + b >= a | b (otherwise, the carry should be set to 1). */ + if (op & SLJIT_SET_C) + FAIL_IF(CMPLTU(ULESS_FLAG ,reg_map[dst] ,ULESS_FLAG)); + + if (op & SLJIT_SET_O) + return CMOVNEZ(OVERFLOW_FLAG, TMP_EREG1, ZERO); + + return SLJIT_SUCCESS; + + case SLJIT_ADDC: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_C) { + if (src2 >= 0) + FAIL_IF(ORI(TMP_EREG1, reg_map[src1], src2)); + else { + FAIL_IF(ADDLI(TMP_EREG1, ZERO, src2)); + FAIL_IF(OR(TMP_EREG1, reg_map[src1], TMP_EREG1)); + } + } + + FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2)); + + } else { + if (op & SLJIT_SET_C) + FAIL_IF(OR(TMP_EREG1, reg_map[src1], reg_map[src2])); + + /* dst may be the same as src1 or src2. */ + FAIL_IF(ADD(reg_map[dst], reg_map[src1], reg_map[src2])); + } + + if (op & SLJIT_SET_C) + FAIL_IF(CMPLTU(TMP_EREG1, reg_map[dst], TMP_EREG1)); + + FAIL_IF(ADD(reg_map[dst], reg_map[dst], ULESS_FLAG)); + + if (!(op & SLJIT_SET_C)) + return SLJIT_SUCCESS; + + /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */ + FAIL_IF(CMPLTUI(TMP_EREG2, reg_map[dst], 1)); + FAIL_IF(AND(TMP_EREG2, TMP_EREG2, ULESS_FLAG)); + /* Set carry flag. */ + return OR(ULESS_FLAG, TMP_EREG2, TMP_EREG1); + + case SLJIT_SUB: + if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_16BIT_MIN)) { + FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2)); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + FAIL_IF(SHRUI(TMP_EREG1,reg_map[src1], 63)); + + if (src2 < 0) + FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1)); + + if (src1 != dst) + overflow_ra = reg_map[src1]; + else { + /* Rare ocasion. */ + FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); + + overflow_ra = TMP_EREG2; + } + } + + if (op & SLJIT_SET_E) + FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], -src2)); + + if (op & SLJIT_SET_C) { + FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); + FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], ADDR_TMP_mapped)); + } + + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2)); + + } else { + + if (op & SLJIT_SET_O) { + FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2])); + FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63)); + + if (src1 != dst) + overflow_ra = reg_map[src1]; + else { + /* Rare ocasion. */ + FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO)); + overflow_ra = TMP_EREG2; + } + } + + if (op & SLJIT_SET_E) + FAIL_IF(SUB(EQUAL_FLAG, reg_map[src1], reg_map[src2])); + + if (op & (SLJIT_SET_U | SLJIT_SET_C)) + FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], reg_map[src2])); + + if (op & SLJIT_SET_U) + FAIL_IF(CMPLTU(UGREATER_FLAG, reg_map[src2], reg_map[src1])); + + if (op & SLJIT_SET_S) { + FAIL_IF(CMPLTS(LESS_FLAG ,reg_map[src1] ,reg_map[src2])); + FAIL_IF(CMPLTS(GREATER_FLAG ,reg_map[src2] ,reg_map[src1])); + } + + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C)) + FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2])); + } + + if (op & SLJIT_SET_O) { + FAIL_IF(XOR(OVERFLOW_FLAG, reg_map[dst], overflow_ra)); + FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63)); + return CMOVEQZ(OVERFLOW_FLAG, TMP_EREG1, ZERO); + } + + return SLJIT_SUCCESS; + + case SLJIT_SUBC: + if ((flags & SRC2_IMM) && src2 == SIMM_16BIT_MIN) { + FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2)); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_C) { + FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, -src2)); + FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], ADDR_TMP_mapped)); + } + + /* dst may be the same as src1 or src2. */ + FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2)); + + } else { + if (op & SLJIT_SET_C) + FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], reg_map[src2])); + /* dst may be the same as src1 or src2. */ + FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2])); + } + + if (op & SLJIT_SET_C) + FAIL_IF(CMOVEQZ(TMP_EREG1, reg_map[dst], ULESS_FLAG)); + + FAIL_IF(SUB(reg_map[dst], reg_map[dst], ULESS_FLAG)); + + if (op & SLJIT_SET_C) + FAIL_IF(ADD(ULESS_FLAG, TMP_EREG1, ZERO)); + + return SLJIT_SUCCESS; + +#define EMIT_LOGICAL(op_imm, op_norm) \ + if (flags & SRC2_IMM) { \ + FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ + ADDR_TMP_mapped, __LINE__)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, reg_map[dst], reg_map[src1], \ + ADDR_TMP_mapped, __LINE__)); \ + } else { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, EQUAL_FLAG, reg_map[src1], \ + reg_map[src2], __LINE__)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, reg_map[dst], reg_map[src1], \ + reg_map[src2], __LINE__)); \ + } + + case SLJIT_AND: + EMIT_LOGICAL(TILEGX_OPC_ANDI, TILEGX_OPC_AND); + return SLJIT_SUCCESS; + + case SLJIT_OR: + EMIT_LOGICAL(TILEGX_OPC_ORI, TILEGX_OPC_OR); + return SLJIT_SUCCESS; + + case SLJIT_XOR: + EMIT_LOGICAL(TILEGX_OPC_XORI, TILEGX_OPC_XOR); + return SLJIT_SUCCESS; + +#define EMIT_SHIFT(op_imm, op_norm) \ + if (flags & SRC2_IMM) { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_3_buffer( \ + compiler, op_imm, EQUAL_FLAG, reg_map[src1], \ + src2 & 0x3F, __LINE__)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_3_buffer( \ + compiler, op_imm, reg_map[dst], reg_map[src1], \ + src2 & 0x3F, __LINE__)); \ + } else { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_3_buffer( \ + compiler, op_imm, reg_map[dst], reg_map[src1], \ + src2 & 0x3F, __LINE__)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_3_buffer( \ + compiler, op_norm, reg_map[dst], reg_map[src1], \ + reg_map[src2], __LINE__)); \ + } + + case SLJIT_SHL: + EMIT_SHIFT(TILEGX_OPC_SHLI, TILEGX_OPC_SHL); + return SLJIT_SUCCESS; + + case SLJIT_LSHR: + EMIT_SHIFT(TILEGX_OPC_SHRUI, TILEGX_OPC_SHRU); + return SLJIT_SUCCESS; + + case SLJIT_ASHR: + EMIT_SHIFT(TILEGX_OPC_SHRSI, TILEGX_OPC_SHRS); + return SLJIT_SUCCESS; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw 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. */ + sljit_si dst_r = TMP_REG2; + sljit_si src1_r; + sljit_sw src2_r = 0; + sljit_si sugg_src2_r = TMP_REG2; + + if (!(flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } + + if (SLJIT_UNLIKELY(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 (FAST_IS_REG(dst)) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw)) + flags |= SLOW_DEST; + + if (flags & IMM_OP) { + if ((src2 & SLJIT_IMM) && src2w) { + if ((!(flags & LOGICAL_OP) + && (src2w <= SIMM_16BIT_MAX && src2w >= SIMM_16BIT_MIN)) + || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_16BIT_MAX))) { + flags |= SRC2_IMM; + src2_r = src2w; + } + } + + if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { + if ((!(flags & LOGICAL_OP) + && (src1w <= SIMM_16BIT_MAX && src1w >= SIMM_16BIT_MIN)) + || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_16BIT_MAX))) { + flags |= SRC2_IMM; + src2_r = src1w; + + /* And swap arguments. */ + src1 = src2; + src1w = src2w; + src2 = SLJIT_IMM; + /* src2w = src2_r unneeded. */ + } + } + } + + /* Source 1. */ + if (FAST_IS_REG(src1)) { + src1_r = src1; + flags |= REG1_SOURCE; + } else if (src1 & SLJIT_IMM) { + if (src1w) { + FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, src1w)); + src1_r = TMP_REG1; + } else + src1_r = 0; + } else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC1; + src1_r = TMP_REG1; + } + + /* Source 2. */ + if (FAST_IS_REG(src2)) { + 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 (!(flags & SRC2_IMM)) { + if (src2w) { + FAIL_IF(load_immediate(compiler, reg_map[sugg_src2_r], src2w)); + src2_r = sugg_src2_r; + } else { + src2_r = 0; + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + dst_r = 0; + } + } + } else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, reg_map[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, TMP_REG2_mapped, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw)); + } else { + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, dst, dstw)); + } + } else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, reg_map[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, reg_map[dst_r], dst, dstw); + return compiler->error; + } + + return getput_arg(compiler, flags, reg_map[dst_r], dst, dstw, 0, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw, sljit_si type) +{ + sljit_si sugg_dst_ar, dst_ar; + sljit_si flags = GET_ALL_FLAGS(op); + + CHECK_ERROR(); + check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + op = GET_OPCODE(op); + sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2]; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } + + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_NOT_EQUAL: + FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1)); + 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(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1)); + 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; + + default: + SLJIT_ASSERT_STOP(); + dst_ar = sugg_dst_ar; + break; + } + + if (type & 0x1) { + FAIL_IF(XORI(sugg_dst_ar, dst_ar, 1)); + dst_ar = sugg_dst_ar; + } + + if (op >= SLJIT_ADD) { + if (TMP_REG2_mapped != dst_ar) + FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO)); + return emit_op(compiler, op | flags, CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, 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 ADD(sugg_dst_ar, dst_ar, ZERO); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) { + CHECK_ERROR(); + check_sljit_emit_op0(compiler, op); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_NOP: + return push_0_buffer(compiler, TILEGX_OPC_FNOP, __LINE__); + + case SLJIT_BREAKPOINT: + return PI(BPT); + + case SLJIT_UMUL: + case SLJIT_SMUL: + case SLJIT_UDIV: + case SLJIT_SDIV: + SLJIT_ASSERT_STOP(); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw 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_P: + return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UI: + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_SI: + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UB: + return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw); + + case SLJIT_MOV_SB: + return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw); + + case SLJIT_MOV_UH: + return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw); + + case SLJIT_MOV_SH: + return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw); + + case SLJIT_MOVU: + case SLJIT_MOVU_P: + return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UI: + return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_SI: + return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UB: + return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw); + + case SLJIT_MOVU_SB: + return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw); + + case SLJIT_MOVU_UH: + return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw); + + case SLJIT_MOVU_SH: + return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw); + + case SLJIT_NOT: + return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: + return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_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 sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw 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: + return emit_op(compiler, op, CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUB: + case SLJIT_SUBC: + return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_MUL: + return emit_op(compiler, op, CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SHL: + case SLJIT_LSHR: + case SLJIT_ASHR: + if (src2 & SLJIT_IMM) + src2w &= 0x3f; + if (op & SLJIT_INT_OP) + src2w &= 0x1f; + + return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + flush_buffer(compiler); + + 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 sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +{ + sljit_si src_r = TMP_REG2; + struct sljit_jump *jump = NULL; + + flush_buffer(compiler); + + CHECK_ERROR(); + check_sljit_emit_ijump(compiler, type, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (FAST_IS_REG(src)) { + if (reg_map[src] != 0) + src_r = src; + else + FAIL_IF(ADD_SOLO(TMP_REG2_mapped, reg_map[src], ZERO)); + } + + if (type >= SLJIT_CALL0) { + SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2); + if (src & (SLJIT_IMM | SLJIT_MEM)) { + if (src & SLJIT_IMM) + FAIL_IF(emit_const(compiler, reg_map[PIC_ADDR_REG], srcw, 1)); + 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(ADD_SOLO(0, reg_map[SLJIT_SCRATCH_REG1], ZERO)); + + FAIL_IF(ADDI_SOLO(54, 54, -16)); + + FAIL_IF(JALR_SOLO(reg_map[PIC_ADDR_REG])); + + return ADDI_SOLO(54, 54, 16); + } + + /* Register input. */ + if (type >= SLJIT_CALL1) + FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_SCRATCH_REG1], ZERO)); + + FAIL_IF(ADD_SOLO(reg_map[PIC_ADDR_REG], reg_map[src_r], ZERO)); + + FAIL_IF(ADDI_SOLO(54, 54, -16)); + + FAIL_IF(JALR_SOLO(reg_map[src_r])); + + return ADDI_SOLO(54, 54, 16); + } + + 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; + FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1)); + + if (type >= SLJIT_FAST_CALL) { + FAIL_IF(ADD_SOLO(ZERO, ZERO, ZERO)); + jump->addr = compiler->size; + FAIL_IF(JR_SOLO(reg_map[src_r])); + } else { + jump->addr = compiler->size; + FAIL_IF(JR_SOLO(reg_map[src_r])); + } + + return SLJIT_SUCCESS; + + } else if (src & SLJIT_MEM) + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + + FAIL_IF(JR_SOLO(reg_map[src_r])); + + if (jump) + jump->addr = compiler->size; + + return SLJIT_SUCCESS; +} + +#define BR_Z(src) \ + inst = BEQZ_X1 | SRCA_X1(src); \ + flags = IS_COND; + +#define BR_NZ(src) \ + inst = BNEZ_X1 | SRCA_X1(src); \ + flags = IS_COND; + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +{ + struct sljit_jump *jump; + sljit_ins inst; + sljit_si flags = 0; + + flush_buffer(compiler); + + 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; + default: + /* Not conditional branch. */ + inst = 0; + break; + } + + jump->flags |= flags; + + if (inst) { + inst = inst | ((type <= SLJIT_JUMP) ? BOFF_X1(5) : BOFF_X1(6)); + PTR_FAIL_IF(PI(inst)); + } + + PTR_FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1)); + if (type <= SLJIT_JUMP) { + jump->addr = compiler->size; + PTR_FAIL_IF(JR_SOLO(TMP_REG2_mapped)); + } else { + SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && 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(ADD_SOLO(0, reg_map[SLJIT_SCRATCH_REG1], ZERO)); + jump->addr = compiler->size; + PTR_FAIL_IF(JALR_SOLO(TMP_REG2_mapped)); + } + + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +{ + return 0; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw) +{ + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) +{ + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +{ + struct sljit_const *const_; + sljit_si reg; + + flush_buffer(compiler); + + 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 = FAST_IS_REG(dst) ? dst : TMP_REG2; + + PTR_FAIL_IF(emit_const_64(compiler, reg, init_value, 1)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + return const_; +} + +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] & ~(0xFFFFL << 43)) | (((new_addr >> 32) & 0xffff) << 43); + inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_addr >> 16) & 0xffff) << 43); + inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_addr & 0xffff) << 43); + SLJIT_CACHE_FLUSH(inst, inst + 3); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +{ + sljit_ins *inst = (sljit_ins *)addr; + + inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_constant >> 48) & 0xFFFFL) << 43); + inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_constant >> 32) & 0xFFFFL) << 43); + inst[2] = (inst[2] & ~(0xFFFFL << 43)) | (((new_constant >> 16) & 0xFFFFL) << 43); + inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43); + SLJIT_CACHE_FLUSH(inst, inst + 4); +} diff --git a/tools/pcre/sljit/sljitNativeX86_32.c b/tools/pcre/sljit/sljitNativeX86_32.c index 03a595bd..dd03f266 100644 --- a/tools/pcre/sljit/sljitNativeX86_32.c +++ b/tools/pcre/sljit/sljitNativeX86_32.c @@ -89,11 +89,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil FAIL_IF(!inst); INC_SIZE(size); - PUSH_REG(reg_map[TMP_REGISTER]); + PUSH_REG(reg_map[TMP_REG1]); #if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (args > 0) { *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[TMP_REGISTER] << 3) | 0x4 /* esp */; + *inst++ = MOD_REG | (reg_map[TMP_REG1] << 3) | 0x4 /* esp */; } #endif if (saveds > 2) @@ -121,17 +121,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #else if (args > 0) { *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER]; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REG1]; *inst++ = sizeof(sljit_sw) * 2; } if (args > 1) { *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER]; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REG1]; *inst++ = sizeof(sljit_sw) * 3; } if (args > 2) { *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER]; + *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REG1]; *inst++ = sizeof(sljit_sw) * 4; } #endif @@ -149,7 +149,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil if (saveds > 3) locals_offset += (saveds - 3) * sizeof(sljit_uw); compiler->locals_offset = locals_offset; +#if defined(__APPLE__) + saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw); + local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds; +#else local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1)); +#endif compiler->local_size = local_size; #ifdef _WIN32 @@ -197,7 +202,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, if (saveds > 3) locals_offset += (saveds - 3) * sizeof(sljit_uw); compiler->locals_offset = locals_offset; +#if defined(__APPLE__) + saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw); + compiler->local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds; +#else compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1)); +#endif } SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) @@ -235,7 +245,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi POP_REG(reg_map[SLJIT_SAVED_REG2]); if (compiler->saveds > 2) POP_REG(reg_map[SLJIT_SAVED_REG3]); - POP_REG(reg_map[TMP_REGISTER]); + POP_REG(reg_map[TMP_REG1]); #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (compiler->args > 2) RET_I16(sizeof(sljit_sw)); @@ -291,9 +301,9 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si /* Calculate size of b. */ inst_size += 1; /* mod r/m byte. */ if (b & SLJIT_MEM) { - if ((b & 0x0f) == SLJIT_UNUSED) + if ((b & REG_MASK) == SLJIT_UNUSED) inst_size += sizeof(sljit_sw); - else if (immb != 0 && !(b & 0xf0)) { + else if (immb != 0 && !(b & OFFS_REG_MASK)) { /* Immediate operand. */ if (immb <= 127 && immb >= -128) inst_size += sizeof(sljit_sb); @@ -301,10 +311,10 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si inst_size += sizeof(sljit_sw); } - if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0)) - b |= SLJIT_LOCALS_REG << 4; + if ((b & REG_MASK) == SLJIT_LOCALS_REG && !(b & OFFS_REG_MASK)) + b |= TO_OFFS_REG(SLJIT_LOCALS_REG); - if ((b & 0xf0) != SLJIT_UNUSED) + if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) inst_size += 1; /* SIB byte. */ } @@ -383,8 +393,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si #else *buf_ptr++ |= MOD_REG + reg_map[b]; #endif - else if ((b & 0x0f) != SLJIT_UNUSED) { - if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) { + else if ((b & REG_MASK) != SLJIT_UNUSED) { + if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_LOCALS_REG)) { if (immb != 0) { if (immb <= 127 && immb >= -128) *buf_ptr |= 0x40; @@ -392,11 +402,11 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si *buf_ptr |= 0x80; } - if ((b & 0xf0) == SLJIT_UNUSED) - *buf_ptr++ |= reg_map[b & 0x0f]; + if ((b & OFFS_REG_MASK) == SLJIT_UNUSED) + *buf_ptr++ |= reg_map[b & REG_MASK]; else { *buf_ptr++ |= 0x04; - *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3); + *buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3); } if (immb != 0) { @@ -410,7 +420,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si } else { *buf_ptr++ |= 0x04; - *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3) | (immb << 6); + *buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3) | (immb << 6); } } else { @@ -485,9 +495,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c /* For UNUSED dst. Uncommon, but possible. */ if (dst == SLJIT_UNUSED) - dst = TMP_REGISTER; + dst = TMP_REG1; - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { /* Unused dest is possible here. */ inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); @@ -514,7 +524,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * CHECK_EXTRA_REGS(src, srcw, (void)0); - if (src <= TMP_REGISTER) { + if (FAST_IS_REG(src)) { inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); FAIL_IF(!inst); diff --git a/tools/pcre/sljit/sljitNativeX86_64.c b/tools/pcre/sljit/sljitNativeX86_64.c index 28f04fdd..967f3c34 100644 --- a/tools/pcre/sljit/sljitNativeX86_64.c +++ b/tools/pcre/sljit/sljitNativeX86_64.c @@ -69,7 +69,7 @@ static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si { sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si)); - if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) { + if (delta <= HALFWORD_MAX && delta >= HALFWORD_MIN) { *code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32; *(sljit_sw*)code_ptr = delta; } @@ -420,12 +420,12 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size &= 0xf; inst_size = size; - if ((b & SLJIT_MEM) && !(b & 0xf0) && NOT_HALFWORD(immb)) { + if ((b & SLJIT_MEM) && !(b & OFFS_REG_MASK) && NOT_HALFWORD(immb)) { if (emit_load_imm64(compiler, TMP_REG3, immb)) return NULL; immb = 0; - if (b & 0xf) - b |= TMP_REG3 << 4; + if (b & REG_MASK) + b |= TO_OFFS_REG(TMP_REG3); else b |= TMP_REG3; } @@ -445,12 +445,12 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si /* Calculate size of b. */ inst_size += 1; /* mod r/m byte. */ if (b & SLJIT_MEM) { - if ((b & 0x0f) == SLJIT_UNUSED) + if ((b & REG_MASK) == SLJIT_UNUSED) inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */ else { - if (reg_map[b & 0x0f] >= 8) + if (reg_map[b & REG_MASK] >= 8) rex |= REX_B; - if (immb != 0 && !(b & 0xf0)) { + if (immb != 0 && !(b & OFFS_REG_MASK)) { /* Immediate operand. */ if (immb <= 127 && immb >= -128) inst_size += sizeof(sljit_sb); @@ -459,12 +459,12 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si } } - if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0)) - b |= SLJIT_LOCALS_REG << 4; + if ((b & REG_MASK) == SLJIT_LOCALS_REG && !(b & OFFS_REG_MASK)) + b |= TO_OFFS_REG(SLJIT_LOCALS_REG); - if ((b & 0xf0) != SLJIT_UNUSED) { + if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) { inst_size += 1; /* SIB byte. */ - if (reg_map[(b >> 4) & 0x0f] >= 8) + if (reg_map[OFFS_REG(b)] >= 8) rex |= REX_X; } } @@ -563,8 +563,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si #else *buf_ptr++ |= MOD_REG + reg_lmap[b]; #endif - else if ((b & 0x0f) != SLJIT_UNUSED) { - if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) { + else if ((b & REG_MASK) != SLJIT_UNUSED) { + if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_LOCALS_REG)) { if (immb != 0) { if (immb <= 127 && immb >= -128) *buf_ptr |= 0x40; @@ -572,11 +572,11 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si *buf_ptr |= 0x80; } - if ((b & 0xf0) == SLJIT_UNUSED) - *buf_ptr++ |= reg_lmap[b & 0x0f]; + if ((b & OFFS_REG_MASK) == SLJIT_UNUSED) + *buf_ptr++ |= reg_lmap[b & REG_MASK]; else { *buf_ptr++ |= 0x04; - *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3); + *buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3); } if (immb != 0) { @@ -590,7 +590,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si } else { *buf_ptr++ |= 0x04; - *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3) | (immb << 6); + *buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6); } } else { @@ -662,9 +662,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c /* For UNUSED dst. Uncommon, but possible. */ if (dst == SLJIT_UNUSED) - dst = TMP_REGISTER; + dst = TMP_REG1; - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { if (reg_map[dst] < 8) { inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); @@ -698,11 +698,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * ADJUST_LOCAL_OFFSET(src, srcw); if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) { - FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, srcw)); - src = TMP_REGISTER; + FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw)); + src = TMP_REG1; } - if (src <= TMP_REGISTER) { + if (FAST_IS_REG(src)) { if (reg_map[src] < 8) { inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); FAIL_IF(!inst); @@ -765,7 +765,7 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); FAIL_IF(!inst); @@ -782,9 +782,9 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; } - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - if ((dst & SLJIT_MEM) && (src <= TMP_REGISTER)) + if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) dst_r = src; else { if (sign) { diff --git a/tools/pcre/sljit/sljitNativeX86_common.c b/tools/pcre/sljit/sljitNativeX86_common.c index ab98a03d..653705f6 100644 --- a/tools/pcre/sljit/sljitNativeX86_common.c +++ b/tools/pcre/sljit/sljitNativeX86_common.c @@ -64,7 +64,7 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) /* Last register + 1. */ -#define TMP_REGISTER (SLJIT_NO_REGISTERS + 1) +#define TMP_REG1 (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 @@ -85,7 +85,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = { #else /* SLJIT_CONFIG_X86_32 */ /* Last register + 1. */ -#define TMP_REGISTER (SLJIT_NO_REGISTERS + 1) +#define TMP_REG1 (SLJIT_NO_REGISTERS + 1) #define TMP_REG2 (SLJIT_NO_REGISTERS + 2) #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) @@ -118,8 +118,16 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { #define REX_B 0x41 #define REX 0x40 -#define IS_HALFWORD(x) ((x) <= 0x7fffffffll && (x) >= -0x80000000ll) -#define NOT_HALFWORD(x) ((x) > 0x7fffffffll || (x) < -0x80000000ll) +#ifndef _WIN64 +#define HALFWORD_MAX 0x7fffffffl +#define HALFWORD_MIN -0x80000000l +#else +#define HALFWORD_MAX 0x7fffffffll +#define HALFWORD_MIN -0x80000000ll +#endif + +#define IS_HALFWORD(x) ((x) <= HALFWORD_MAX && (x) >= HALFWORD_MIN) +#define NOT_HALFWORD(x) ((x) > HALFWORD_MAX || (x) < HALFWORD_MIN) #define CHECK_EXTRA_REGS(p, w, do) @@ -206,6 +214,7 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { #define OR_r_rm 0x0b #define OR_EAX_i32 0x0d #define OR_rm_r 0x09 +#define OR_rm8_r8 0x08 #define POP_r 0x58 #define POP_rm 0x8f #define POPF 0x9d @@ -267,75 +276,54 @@ static sljit_si cpu_has_sse2 = -1; #endif static sljit_si cpu_has_cmov = -1; -#if defined(_MSC_VER) && (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -#if _MSC_VER >= 1400 +#if defined(_MSC_VER) && _MSC_VER >= 1400 #include -#else -#error "MSVC does not support inline assembly in 64 bit mode" #endif -#endif /* _MSC_VER && SLJIT_CONFIG_X86_64 */ static void get_cpu_features(void) { sljit_ui features; -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + int CPUInfo[4]; + __cpuid(CPUInfo, 1); + features = (sljit_ui)CPUInfo[3]; + +#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) -#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) /* AT&T syntax. */ __asm__ ( - "pushl %%ebx\n" "movl $0x1, %%eax\n" +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + /* On x86-32, there is no red zone, so this + should work (no need for a local variable). */ + "push %%ebx\n" +#endif "cpuid\n" - "popl %%ebx\n" +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + "pop %%ebx\n" +#endif "movl %%edx, %0\n" : "=g" (features) : +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) : "%eax", "%ecx", "%edx" +#else + : "%rax", "%rbx", "%rcx", "%rdx" +#endif ); -#elif defined(_MSC_VER) || defined(__BORLANDC__) + +#else /* _MSC_VER && _MSC_VER >= 1400 */ + /* 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 -#else /* SLJIT_CONFIG_X86_32 */ - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) - /* AT&T syntax. */ - __asm__ ( - "pushq %%rbx\n" - "movl $0x1, %%eax\n" - "cpuid\n" - "popq %%rbx\n" - "movl %%edx, %0\n" - : "=g" (features) - : - : "%rax", "%rcx", "%rdx" - ); -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - int CPUInfo[4]; - - __cpuid(CPUInfo, 1); - features = (sljit_ui)CPUInfo[3]; -#else - __asm { - mov eax, 1 - push rbx - cpuid - pop rbx - mov features, edx - } -#endif - -#endif /* SLJIT_CONFIG_X86_32 */ +#endif /* _MSC_VER && _MSC_VER >= 1400 */ #if (defined SLJIT_SSE2 && SLJIT_SSE2) && (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) cpu_has_sse2 = (features >> 26) & 0x1; @@ -417,7 +405,7 @@ static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code short_jump = (sljit_sw)(label_addr - (jump->addr + 2)) >= -128 && (sljit_sw)(label_addr - (jump->addr + 2)) <= 127; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((sljit_sw)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_sw)(label_addr - (jump->addr + 1)) < -0x80000000ll) + if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN) return generate_far_jump_code(jump, code_ptr, type); #endif @@ -546,7 +534,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sw))); #else - SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) >= -0x80000000ll && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) <= 0x7fffffffll); + SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) >= HALFWORD_MIN && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) <= HALFWORD_MAX); *(sljit_si*)jump->addr = (sljit_si)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))); #endif } @@ -554,7 +542,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_sw))); #else - SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) >= -0x80000000ll && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) <= 0x7fffffffll); + SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) >= HALFWORD_MIN && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) <= HALFWORD_MAX); *(sljit_si*)jump->addr = (sljit_si)(jump->u.target - (jump->addr + sizeof(sljit_si))); #endif } @@ -570,7 +558,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* 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; + compiler->executable_size = code_ptr - code; return (void*)code; } @@ -650,9 +638,10 @@ static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size) 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); + CPU cycles if the stack is large enough. However, you don't know it in + advance, so it must always be called. I think this is a bad design in + general even if it has some reasons. */ + *(volatile sljit_si*)alloca(local_size) = 0; } #endif @@ -672,20 +661,20 @@ static sljit_si emit_mov(struct sljit_compiler *compiler, if (dst == SLJIT_UNUSED) { /* No destination, doesn't need to setup flags. */ if (src & SLJIT_MEM) { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw); FAIL_IF(!inst); *inst = MOV_r_rm; } return SLJIT_SUCCESS; } - if (src <= TMP_REGISTER) { + if (FAST_IS_REG(src)) { inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw); FAIL_IF(!inst); *inst = MOV_rm_r; return SLJIT_SUCCESS; } if (src & SLJIT_IMM) { - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); #else @@ -711,7 +700,7 @@ static sljit_si emit_mov(struct sljit_compiler *compiler, *inst = MOV_rm_i32; return SLJIT_SUCCESS; } - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { inst = emit_x86_instruction(compiler, 1, dst, 0, src, srcw); FAIL_IF(!inst); *inst = MOV_r_rm; @@ -719,10 +708,10 @@ static sljit_si emit_mov(struct sljit_compiler *compiler, } /* Memory to memory move. Requires two instruction. */ - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw); FAIL_IF(!inst); *inst = MOV_r_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); FAIL_IF(!inst); *inst = MOV_rm_r; return SLJIT_SUCCESS; @@ -764,13 +753,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler SLJIT_COMPILE_ASSERT( reg_map[SLJIT_SCRATCH_REG1] == 0 && reg_map[SLJIT_SCRATCH_REG2] == 2 - && reg_map[TMP_REGISTER] > 7, + && reg_map[TMP_REG1] > 7, invalid_register_assignment_for_div_mul); #else SLJIT_COMPILE_ASSERT( reg_map[SLJIT_SCRATCH_REG1] == 0 && reg_map[SLJIT_SCRATCH_REG2] < 7 - && reg_map[TMP_REGISTER] == 2, + && reg_map[TMP_REG1] == 2, invalid_register_assignment_for_div_mul); #endif compiler->mode32 = op & SLJIT_INT_OP; @@ -779,10 +768,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler 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_SCRATCH_REG2, 0); + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_SCRATCH_REG2, 0); inst = emit_x86_instruction(compiler, 1, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0); #else - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); #endif FAIL_IF(!inst); *inst = XOR_r_rm; @@ -790,7 +779,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler if (op == SLJIT_SDIV) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) - EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_SCRATCH_REG2, 0); + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_SCRATCH_REG2, 0); #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -819,7 +808,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler FAIL_IF(!inst); INC_SIZE(2); *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_SCRATCH_REG2]); + *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_map[TMP_REG1] : reg_map[SLJIT_SCRATCH_REG2]); #else #ifdef _WIN64 size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2; @@ -835,7 +824,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler else if (op >= SLJIT_UDIV) *inst++ = REX_B; *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_SCRATCH_REG2]); + *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_SCRATCH_REG2]); #else if (!compiler->mode32) *inst++ = REX_W; @@ -858,7 +847,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler break; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) - EMIT_MOV(compiler, SLJIT_SCRATCH_REG2, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, SLJIT_SCRATCH_REG2, 0, TMP_REG1, 0); #endif break; } @@ -892,7 +881,7 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); #else @@ -908,13 +897,13 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; } - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - if ((dst & SLJIT_MEM) && src <= TMP_REGISTER) { + if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) { #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); + SLJIT_ASSERT(dst_r == TMP_REG1); + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); } else dst_r = src; #else @@ -922,9 +911,9 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, #endif } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - else if (src <= TMP_REGISTER && reg_map[src] >= 4) { + else if (FAST_IS_REG(src) && reg_map[src] >= 4) { /* src, dst are registers. */ - SLJIT_ASSERT(dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REGISTER); + SLJIT_ASSERT(SLOW_IS_REG(dst)); if (reg_map[dst] < 4) { if (dst != src) EMIT_MOV(compiler, dst, 0, src, 0); @@ -965,25 +954,25 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, if (dst & SLJIT_MEM) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (dst_r == TMP_REGISTER) { + if (dst_r == TMP_REG1) { /* Find a non-used register, whose reg_map[src] < 4. */ - if ((dst & 0xf) == SLJIT_SCRATCH_REG1) { - if ((dst & 0xf0) == (SLJIT_SCRATCH_REG2 << 4)) + if ((dst & REG_MASK) == SLJIT_SCRATCH_REG1) { + if ((dst & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SCRATCH_REG2)) work_r = SLJIT_SCRATCH_REG3; else work_r = SLJIT_SCRATCH_REG2; } else { - if ((dst & 0xf0) != (SLJIT_SCRATCH_REG1 << 4)) + if ((dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SCRATCH_REG1)) work_r = SLJIT_SCRATCH_REG1; - else if ((dst & 0xf) == SLJIT_SCRATCH_REG2) + else if ((dst & REG_MASK) == SLJIT_SCRATCH_REG2) work_r = SLJIT_SCRATCH_REG3; else work_r = SLJIT_SCRATCH_REG2; } if (work_r == SLJIT_SCRATCH_REG1) { - ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REGISTER]); + ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]); } else { inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); @@ -996,7 +985,7 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, *inst = MOV_rm8_r8; if (work_r == SLJIT_SCRATCH_REG1) { - ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REGISTER]); + ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]); } else { inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); @@ -1034,7 +1023,7 @@ static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); #else @@ -1050,9 +1039,9 @@ static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; } - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - if ((dst & SLJIT_MEM) && src <= TMP_REGISTER) + if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) dst_r = src; else { inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); @@ -1077,8 +1066,8 @@ static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, sljit_ub* inst; if (dst == SLJIT_UNUSED) { - EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst++ = GROUP_F7; *inst |= opcode; @@ -1092,7 +1081,7 @@ static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, *inst |= opcode; return SLJIT_SUCCESS; } - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { EMIT_MOV(compiler, dst, 0, src, srcw); inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); @@ -1100,12 +1089,12 @@ static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, *inst |= opcode; return SLJIT_SUCCESS; } - EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst++ = GROUP_F7; *inst |= opcode; - EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } @@ -1116,17 +1105,17 @@ static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, sljit_ub* inst; if (dst == SLJIT_UNUSED) { - EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst++ = GROUP_F7; *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst = OR_r_rm; return SLJIT_SUCCESS; } - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { EMIT_MOV(compiler, dst, 0, src, srcw); inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); @@ -1137,15 +1126,15 @@ static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, *inst = OR_r_rm; return SLJIT_SUCCESS; } - EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst++ = GROUP_F7; *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst = OR_r_rm; - EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } @@ -1159,15 +1148,15 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, SLJIT_UNUSED_ARG(op_flags); if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { /* Just set the zero flag. */ - EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst++ = GROUP_F7; *inst |= NOT_rm; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REG1, 0); #else - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, TMP_REG1, 0); #endif FAIL_IF(!inst); *inst |= SHR; @@ -1175,24 +1164,24 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, } if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { - EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_IMM, srcw); - src = TMP_REGISTER; + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); + src = TMP_REG1; srcw = 0; } - inst = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw); + inst = emit_x86_instruction(compiler, 2, TMP_REG1, 0, src, srcw); FAIL_IF(!inst); *inst++ = GROUP_0F; *inst = BSR_r_rm; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (dst <= TMP_REGISTER) + if (FAST_IS_REG(dst)) dst_r = dst; else { /* Find an unused temporary register. */ - if ((dst & 0xf) != SLJIT_SCRATCH_REG1 && (dst & 0xf0) != (SLJIT_SCRATCH_REG1 << 4)) + if ((dst & REG_MASK) != SLJIT_SCRATCH_REG1 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SCRATCH_REG1)) dst_r = SLJIT_SCRATCH_REG1; - else if ((dst & 0xf) != SLJIT_SCRATCH_REG2 && (dst & 0xf0) != (SLJIT_SCRATCH_REG2 << 4)) + else if ((dst & REG_MASK) != SLJIT_SCRATCH_REG2 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SCRATCH_REG2)) dst_r = SLJIT_SCRATCH_REG2; else dst_r = SLJIT_SCRATCH_REG3; @@ -1200,7 +1189,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, } EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31); #else - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REG2; + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; compiler->mode32 = 0; EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); compiler->mode32 = op_flags & SLJIT_INT_OP; @@ -1210,7 +1199,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, get_cpu_features(); if (cpu_has_cmov) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst++ = GROUP_0F; *inst = CMOVNE_r_rm; @@ -1223,7 +1212,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, *inst++ = JE_i8; *inst++ = 2; *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[dst_r] << 3) | reg_map[TMP_REGISTER]; + *inst++ = MOD_REG | (reg_map[dst_r] << 3) | reg_map[TMP_REG1]; #else inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); @@ -1231,9 +1220,9 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, *inst++ = JE_i8; *inst++ = 3; - *inst++ = REX_W | (reg_map[dst_r] >= 8 ? REX_R : 0) | (reg_map[TMP_REGISTER] >= 8 ? REX_B : 0); + *inst++ = REX_W | (reg_map[dst_r] >= 8 ? REX_R : 0) | (reg_map[TMP_REG1] >= 8 ? REX_B : 0); *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_lmap[dst_r] << 3) | reg_lmap[TMP_REGISTER]; + *inst++ = MOD_REG | (reg_lmap[dst_r] << 3) | reg_lmap[TMP_REG1]; #endif } @@ -1290,7 +1279,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #endif if (op_flags & SLJIT_INT_OP) { - if (src <= TMP_REGISTER && src == dst) { + if (FAST_IS_REG(src) && src == dst) { if (!TYPE_CAST_NEEDED(op)) return SLJIT_SUCCESS; } @@ -1341,8 +1330,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #endif } - if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & 0xf) && (srcw != 0 || (src & 0xf0) != 0)) { - inst = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw); + if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & REG_MASK) && (srcw != 0 || (src & OFFS_REG_MASK) != 0)) { + inst = emit_x86_instruction(compiler, 1, src & REG_MASK, 0, src, srcw); FAIL_IF(!inst); *inst = LEA_r_m; src &= SLJIT_MEM | 0xf; @@ -1352,7 +1341,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #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 || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) { SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG)); - dst = TMP_REGISTER; + dst = TMP_REG1; } #endif @@ -1388,12 +1377,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler } #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); + if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1) + return emit_mov(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), dstw, TMP_REG1, 0); #endif - if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & 0xf) && (dstw != 0 || (dst & 0xf0) != 0)) { - inst = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw); + if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & REG_MASK) && (dstw != 0 || (dst & OFFS_REG_MASK) != 0)) { + inst = emit_x86_instruction(compiler, 1, dst & REG_MASK, 0, dst, dstw); FAIL_IF(!inst); *inst = LEA_r_m; } @@ -1466,12 +1455,12 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, sljit_ub* inst; if (dst == SLJIT_UNUSED) { - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); if (src2 & SLJIT_IMM) { - BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); + BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); } else { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); FAIL_IF(!inst); *inst = op_rm; } @@ -1491,20 +1480,20 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); } } - else if (dst <= TMP_REGISTER) { + else if (FAST_IS_REG(dst)) { inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); FAIL_IF(!inst); *inst = op_rm; } - else if (src2 <= TMP_REGISTER) { + else if (FAST_IS_REG(src2)) { /* Special exception for sljit_emit_op_flags. */ inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); FAIL_IF(!inst); *inst = op_mr; } else { - EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); FAIL_IF(!inst); *inst = op_mr; } @@ -1525,19 +1514,19 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src1w, dst, dstw); } } - else if (dst <= TMP_REGISTER) { + else if (FAST_IS_REG(dst)) { inst = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w); FAIL_IF(!inst); *inst = op_rm; } - else if (src1 <= TMP_REGISTER) { + else if (FAST_IS_REG(src1)) { inst = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw); FAIL_IF(!inst); *inst = op_mr; } else { - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); FAIL_IF(!inst); *inst = op_mr; } @@ -1545,7 +1534,7 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, } /* General version. */ - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { EMIT_MOV(compiler, dst, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); @@ -1558,16 +1547,16 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, } else { /* This version requires less memory writing. */ - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); if (src2 & SLJIT_IMM) { - BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); + BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); } else { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); FAIL_IF(!inst); *inst = op_rm; } - EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); } return SLJIT_SUCCESS; @@ -1582,12 +1571,12 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, sljit_ub* inst; if (dst == SLJIT_UNUSED) { - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); if (src2 & SLJIT_IMM) { - BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); + BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); } else { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); FAIL_IF(!inst); *inst = op_rm; } @@ -1607,19 +1596,19 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); } } - else if (dst <= TMP_REGISTER) { + else if (FAST_IS_REG(dst)) { inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); FAIL_IF(!inst); *inst = op_rm; } - else if (src2 <= TMP_REGISTER) { + else if (FAST_IS_REG(src2)) { inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); FAIL_IF(!inst); *inst = op_mr; } else { - EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw); FAIL_IF(!inst); *inst = op_mr; } @@ -1627,7 +1616,7 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, } /* General version. */ - if (dst <= TMP_REGISTER && dst != src2) { + if (FAST_IS_REG(dst) && dst != src2) { EMIT_MOV(compiler, dst, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); @@ -1640,16 +1629,16 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, } else { /* This version requires less memory writing. */ - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); if (src2 & SLJIT_IMM) { - BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); + BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); } else { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); FAIL_IF(!inst); *inst = op_rm; } - EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); } return SLJIT_SUCCESS; @@ -1663,7 +1652,7 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, sljit_ub* inst; sljit_si dst_r; - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; /* Register destination. */ if (dst_r == src1 && !(src2 & SLJIT_IMM)) { @@ -1771,7 +1760,7 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, else { /* Neither argument is immediate. */ if (ADDRESSING_DEPENDS_ON(src2, dst_r)) - dst_r = TMP_REGISTER; + dst_r = TMP_REG1; EMIT_MOV(compiler, dst_r, 0, src1, src1w); inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); FAIL_IF(!inst); @@ -1779,13 +1768,13 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, *inst = IMUL_r_rm; } - if (dst_r == TMP_REGISTER) - EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + if (dst_r == TMP_REG1) + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } -static sljit_si emit_lea_binary(struct sljit_compiler *compiler, +static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_flags, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) @@ -1794,15 +1783,17 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si 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; + if (!keep_flags) { + if (dst == src1 && dstw == src1w) + return SLJIT_ERR_UNSUPPORTED; + if (dst == src2 && dstw == src2w) + return SLJIT_ERR_UNSUPPORTED; + } - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - if (src1 <= TMP_REGISTER) { - if (src2 <= TMP_REGISTER || src2 == TMP_REGISTER) { + if (FAST_IS_REG(src1)) { + if (FAST_IS_REG(src2)) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0); FAIL_IF(!inst); *inst = LEA_r_m; @@ -1820,7 +1811,7 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, done = 1; } } - else if (src2 <= TMP_REGISTER) { + else if (FAST_IS_REG(src2)) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_si)src1w); @@ -1835,8 +1826,8 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, } if (done) { - if (dst_r == TMP_REGISTER) - return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0); + if (dst_r == TMP_REG1) + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } return SLJIT_ERR_UNSUPPORTED; @@ -1857,7 +1848,7 @@ static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } - if (src1 <= TMP_REGISTER) { + if (FAST_IS_REG(src1)) { if (src2 & SLJIT_IMM) { BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0); } @@ -1869,7 +1860,7 @@ static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } - if (src2 <= TMP_REGISTER && !(src1 & SLJIT_IMM)) { + if (FAST_IS_REG(src2) && !(src1 & SLJIT_IMM)) { inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); FAIL_IF(!inst); *inst = CMP_rm_r; @@ -1878,15 +1869,15 @@ static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, if (src2 & SLJIT_IMM) { if (src1 & SLJIT_IMM) { - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - src1 = TMP_REGISTER; + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + src1 = TMP_REG1; src1w = 0; } BINARY_IMM(CMP, CMP_rm_r, src2w, src1, src1w); } else { - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); FAIL_IF(!inst); *inst = CMP_r_rm; } @@ -1917,7 +1908,7 @@ static sljit_si emit_test_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } - if (src1 <= TMP_REGISTER) { + if (FAST_IS_REG(src1)) { if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { @@ -1945,7 +1936,7 @@ static sljit_si emit_test_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } - if (src2 <= TMP_REGISTER) { + if (FAST_IS_REG(src2)) { if (src1 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src1w) || compiler->mode32) { @@ -1973,28 +1964,28 @@ static sljit_si emit_test_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0); FAIL_IF(!inst); *inst = GROUP_F7; } else { FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst = TEST_rm_r; } #else - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0); FAIL_IF(!inst); *inst = GROUP_F7; #endif } else { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w); FAIL_IF(!inst); *inst = TEST_rm_r; } @@ -2017,21 +2008,21 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } if (dst == SLJIT_UNUSED) { - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0); FAIL_IF(!inst); *inst |= mode; return SLJIT_SUCCESS; } if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) { - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst |= mode; - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); return SLJIT_SUCCESS; } - if (dst <= TMP_REGISTER) { + if (FAST_IS_REG(dst)) { EMIT_MOV(compiler, dst, 0, src1, src1w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); FAIL_IF(!inst); @@ -2039,36 +2030,36 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0); FAIL_IF(!inst); *inst |= mode; - EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } if (dst == SLJIT_PREF_SHIFT_REG) { - EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst |= mode; - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); } - else if (dst <= TMP_REGISTER && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) { + else if (FAST_IS_REG(dst) && 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, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0); FAIL_IF(!inst); *inst |= mode; - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 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); + EMIT_MOV(compiler, TMP_REG1, 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 @@ -2076,7 +2067,7 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_sw), SLJIT_PREF_SHIFT_REG, 0); #endif EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); FAIL_IF(!inst); *inst |= mode; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -2084,7 +2075,7 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, #else EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_sw)); #endif - EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); } return SLJIT_SUCCESS; @@ -2115,12 +2106,12 @@ static sljit_si emit_shift_with_flags(struct sljit_compiler *compiler, if (!set_flags) return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); - if (!(dst <= TMP_REGISTER)) + if (!FAST_IS_REG(dst)) 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 <= TMP_REGISTER) + if (FAST_IS_REG(dst)) return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0); return SLJIT_SUCCESS; } @@ -2153,7 +2144,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *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) + if (emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED) return compiler->error; } else @@ -2173,7 +2164,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler 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) + if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED) return compiler->error; } else @@ -2231,6 +2222,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) return reg_map[reg]; } +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +{ + check_sljit_get_float_register_index(reg); + return reg; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_si size) { @@ -2274,7 +2271,9 @@ static void init_compiler(void) SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) { -#if (defined SLJIT_SSE2 && SLJIT_SSE2) +#ifdef SLJIT_IS_FPU_AVAILABLE + return SLJIT_IS_FPU_AVAILABLE; +#elif (defined SLJIT_SSE2 && SLJIT_SSE2) #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) if (cpu_has_sse2 == -1) get_cpu_features(); @@ -2340,7 +2339,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile if (GET_OPCODE(op) == SLJIT_CMPD) { compiler->flags_saved = 0; - if (dst <= SLJIT_FLOAT_REG6) + if (FAST_IS_REG(dst)) dst_r = dst; else { dst_r = TMP_FREG; @@ -2350,15 +2349,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile } if (op == SLJIT_MOVD) { - if (dst <= SLJIT_FLOAT_REG6) + if (FAST_IS_REG(dst)) return emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst, src, srcw); - if (src <= SLJIT_FLOAT_REG6) + if (FAST_IS_REG(src)) return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, src); FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src, srcw)); return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); } - if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG6) { + if (SLOW_IS_REG(dst)) { dst_r = dst; if (dst != src) FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); @@ -2397,7 +2396,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->mode32 = 1; #endif - if (dst <= SLJIT_FLOAT_REG6) { + if (FAST_IS_REG(dst)) { dst_r = dst; if (dst == src1) ; /* Do nothing here. */ @@ -2559,8 +2558,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (src == SLJIT_SCRATCH_REG3) { - EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); - src = TMP_REGISTER; + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + src = TMP_REG1; } if (src == SLJIT_MEM1(SLJIT_LOCALS_REG) && type >= SLJIT_CALL3) srcw += sizeof(sljit_sw); @@ -2568,8 +2567,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64) if (src == SLJIT_SCRATCH_REG3) { - EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); - src = TMP_REGISTER; + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + src = TMP_REG1; } #endif FAIL_IF(call_with_args(compiler, type)); @@ -2637,7 +2636,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com cond_set = get_jump_code(type) + 0x10; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - reg = (op == SLJIT_MOV && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 3); + FAIL_IF(!inst); + INC_SIZE(4 + 3); + /* Set low register to conditional flag. */ + *inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | reg_lmap[TMP_REG1]; + *inst++ = REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B); + *inst++ = OR_rm8_r8; + *inst++ = MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]; + return SLJIT_SUCCESS; + } + + reg = (op == SLJIT_MOV && FAST_IS_REG(dst)) ? dst : TMP_REG1; inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); FAIL_IF(!inst); @@ -2652,19 +2666,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com *inst++ = MOVZX_r_rm8; *inst = MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]; - if (reg != TMP_REGISTER) + if (reg != TMP_REG1) return SLJIT_SUCCESS; if (GET_OPCODE(op) < SLJIT_ADD) { compiler->mode32 = GET_OPCODE(op) != SLJIT_MOV; - return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0); + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); } #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_REGISTER, 0); + return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG1, 0); #else /* SLJIT_CONFIG_X86_64 */ - if (GET_OPCODE(op) < SLJIT_ADD && dst <= TMP_REGISTER) { + if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) { if (reg_map[dst] <= 4) { /* Low byte is accessible. */ inst = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); @@ -2686,7 +2700,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com get_cpu_features(); if (cpu_has_cmov) { - EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_IMM, 1); + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1); /* a xor reg, reg operation would overwrite the flags. */ EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0); @@ -2697,14 +2711,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com *inst++ = GROUP_0F; /* cmovcc = setcc - 0x50. */ *inst++ = cond_set - 0x50; - *inst++ = MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REGISTER]; + *inst++ = MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REG1]; return SLJIT_SUCCESS; } inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); FAIL_IF(!inst); INC_SIZE(1 + 3 + 3 + 1); - *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; /* Set al to conditional flag. */ *inst++ = GROUP_0F; *inst++ = cond_set; @@ -2713,15 +2727,48 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com *inst++ = GROUP_0F; *inst++ = MOVZX_r_rm8; *inst++ = MOD_REG | (reg_map[dst] << 3) | 0 /* eax */; - *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; return SLJIT_SUCCESS; } - /* Set TMP_REGISTER to the bit. */ + if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src && reg_map[dst] <= 4) { + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG1] == 0, scratch_reg1_must_be_eax); + if (dst != SLJIT_SCRATCH_REG1) { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1); + FAIL_IF(!inst); + INC_SIZE(1 + 3 + 2 + 1); + /* Set low register to conditional flag. */ + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | 0 /* eax */; + *inst++ = OR_rm8_r8; + *inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst]; + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; + } + else { + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2); + FAIL_IF(!inst); + INC_SIZE(2 + 3 + 2 + 2); + /* Set low register to conditional flag. */ + *inst++ = XCHG_r_rm; + *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]; + *inst++ = GROUP_0F; + *inst++ = cond_set; + *inst++ = MOD_REG | 1 /* ecx */; + *inst++ = OR_rm8_r8; + *inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */; + *inst++ = XCHG_r_rm; + *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]; + } + return SLJIT_SUCCESS; + } + + /* Set TMP_REG1 to the bit. */ inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); FAIL_IF(!inst); INC_SIZE(1 + 3 + 3 + 1); - *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; /* Set al to conditional flag. */ *inst++ = GROUP_0F; *inst++ = cond_set; @@ -2731,15 +2778,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com *inst++ = MOVZX_r_rm8; *inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */; - *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; + *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; if (GET_OPCODE(op) < SLJIT_ADD) - return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0); + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); #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); + return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0); #endif /* SLJIT_CONFIG_X86_64 */ } @@ -2759,18 +2806,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (NOT_HALFWORD(offset)) { - FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, offset)); + FAIL_IF(emit_load_imm64(compiler, TMP_REG1, 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); + SLJIT_ASSERT(emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED); return compiler->error; #else - return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0); + return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REG1, 0); #endif } #endif if (offset != 0) - return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset); + return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset); return emit_mov(compiler, dst, dstw, SLJIT_LOCALS_REG, 0); } @@ -2794,13 +2841,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; - reg = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + reg = SLOW_IS_REG(dst) ? dst : TMP_REG1; if (emit_load_imm64(compiler, reg, init_value)) return NULL; #else if (dst == SLJIT_UNUSED) - dst = TMP_REGISTER; + dst = TMP_REG1; if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value)) return NULL; @@ -2813,8 +2860,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi *inst++ = 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)) + if (dst & SLJIT_MEM) + if (emit_mov(compiler, dst, dstw, TMP_REG1, 0)) return NULL; #endif diff --git a/tools/pcre/sljit/sljitUtils.c b/tools/pcre/sljit/sljitUtils.c index 1f023fa6..b29b4036 100644 --- a/tools/pcre/sljit/sljitUtils.c +++ b/tools/pcre/sljit/sljitUtils.c @@ -315,12 +315,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_sta aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; /* If madvise is available, we release the unnecessary space. */ -#if defined(POSIX_MADV_DONTNEED) - if (aligned_new_limit < aligned_old_limit) - posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED); -#elif defined(MADV_DONTNEED) +#if defined(MADV_DONTNEED) if (aligned_new_limit < aligned_old_limit) madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED); +#elif defined(POSIX_MADV_DONTNEED) + if (aligned_new_limit < aligned_old_limit) + posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED); #endif stack->limit = new_limit; return 0; diff --git a/tools/pcre/test-driver b/tools/pcre/test-driver new file mode 100644 index 00000000..d3060566 --- /dev/null +++ b/tools/pcre/test-driver @@ -0,0 +1,139 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2013-07-13.22; # UTC + +# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? +if test $enable_hard_errors = no && test $estatus -eq 99; then + estatus=1 +fi + +case $estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/tools/pcre/testdata/grepoutput b/tools/pcre/testdata/grepoutput index 733b9d6a..9bf9d9d6 100644 --- a/tools/pcre/testdata/grepoutput +++ b/tools/pcre/testdata/grepoutput @@ -705,3 +705,41 @@ RC=0 ./testdata/grepinput:zero|a ./testdata/grepinput:.|zero|the|. RC=0 +---------------------------- Test 102 ----------------------------- +2: +5: +7: +9: +12: +14: +RC=0 +---------------------------- Test 103 ----------------------------- +RC=0 +---------------------------- Test 104 ----------------------------- +2: +5: +7: +9: +12: +14: +RC=0 +---------------------------- Test 105 ----------------------------- +triple: t1_txt s1_tag s_txt p_tag p_txt o_tag o_txt + +triple: t2_txt s1_tag s_txt p_tag p_txt o_tag +Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + +triple: t3_txt s2_tag s_txt p_tag p_txt o_tag o_txt + +triple: t4_txt s1_tag s_txt p_tag p_txt o_tag o_txt + +triple: t5_txt s1_tag s_txt p_tag p_txt o_tag +o_txt + +triple: t6_txt s2_tag s_txt p_tag p_txt o_tag o_txt + +triple: t7_txt s1_tag s_txt p_tag p_txt o_tag o_txt +RC=0 +---------------------------- Test 106 ----------------------------- +a +RC=0 diff --git a/tools/pcre/testdata/saved16 b/tools/pcre/testdata/saved16 index ff5b11dff9bed96ba61ff959d8d45c2b57e9662f..f86326c9f876add7c53d1f5afd72953688b1ee63 100644 GIT binary patch literal 86 zcmZQzVDMuA0@ont05Ai{4g%u;P>{%w43Y){83=_&)-!N0$TB1XaS{+GGn4@N3=9Ci C^KNzN7l-orsc!uk1|BEn+(i&F3p5JcaM_yYrj4HOSxuzLV=F<(4@AS#GoTr?DoJfoR6QLAThWf2Ri>8`2n zX&T%FNYdeWM4q?tQjCTU^&-!eJUVtv*|G?wXU~zPs!a8n8(mg~z5N|mXqH@vadJmr zuQ#vwgSjS0tY3ylh)+dh3C!e+xzf_s8=9KqUFuU@#YP_JN$nB}6Fh@J%S&(#J>Ge| kq@L)jtD`Ol(*MI%b;Pj#QtqmL%XAAvB7SZfgg>G726CS?bN~PV diff --git a/tools/pcre/testdata/saved16BE-2 b/tools/pcre/testdata/saved16BE-2 index dade400e96556e635a2a21998fb03f09c88a650a..c91ce37bd4f972235cb295be6b9a5326524f5707 100644 GIT binary patch delta 135 zcmcb>bc4x&fq_wlfq_9Mz&Xej!sg%r@|pfa0gw#>Oh7Edz|O!lQA3xznIV;-l|h$* zk)dE>f~j%=10PV9@uM;W;|+#8mJCcc9PTjOaJgp!6is6&XOIIb+hNXK!Qc(lB?2@m Rf8sAi)(RlAVzL6G0RTj&AM^kK delta 133 zcmcb?bb(2Yfq_wmfq_9Mz&Xej!scLLU;>JOFbGI6urn}Cc4QQu=qSTo%aF=Y&!Ee| z$dEHJ!;~>+;yhW_LIyb??|`{s5ra2SQUs_o`#%!+`~UxMBrcfAPy|$0G+Beu000G~ BFoysD diff --git a/tools/pcre/testdata/saved16LE-1 b/tools/pcre/testdata/saved16LE-1 index deb44919bbbc263c227c51454f2dd25d582c7a6b..822ccd7012aa61c85670ca8664d70cb187d22f5d 100644 GIT binary patch literal 418 zcmZXQJqp4=5QX2a#2>J*uuyF5Ec6y)AH0F6kj5m4pkOI_HLqZoV_0eYcGaNCgV~)o z`)23uN+y;xna!tRY@{B<68Q(Dz*UB7_}v#Oi&3nFHd^}=t3*3Rur2(giw2w*=)7+% z_$N7QEQ7lHqqR;;l(EtQUGnysd9zPe7k^ly8#BL+_f##eu?kISd1_7C<11C4^xO2v uuepmd&^P&oTb@Zrjp*vRF6Q0K(jQJ&K;S<@9Wd#D7rxv3D8H%7>y%!X_It1Z literal 402 zcmZvYOA5k35JcaM#1FV|;lkhnT<8I^7x%#f2%m1lI9n;5Hu-)KS4boJEK z^fb5;&>IZ<@yJ0##6LnCEh;&;{1c8fV^+-aqG!XNL~JL1hbvaYli%V*9@x(6n`dSILv{el)eZUh*5k2W^m%gf= nuUQHQI=a=eTULH)eiI!B3iY2z9q6^4W})#a{!O6hP*&j%f@(B$ diff --git a/tools/pcre/testdata/saved16LE-2 b/tools/pcre/testdata/saved16LE-2 index c8be985756cf3442483356e21337ae5f72c76318..656c058d2603f646877d69cd34c453ba8f94cf44 100644 GIT binary patch delta 133 zcmcb>bc0Eofq_wlfq_BCHOM(Yg^_`QgM)#A2`KO%3V=)?0Ex&P%tsxRJnkG4=BmVp!^Z2`-bHmCI*Ka40l{^nA~GvNMk5xkOL~)Zq8l7;0@Fz U0yHUq;!j1^3Lvv$vOJ?909}0`sQ>@~ delta 102 zcmcb?bb(2kfq_wmfq_BCHOM(Yh7ri(U|?VZQXmWh5)AB<^%+GcI>>O>GNdxpGw3of uGUQB5H)YJ3I9HankU={@Cj&7A@WB{xx*o{l0Ag7n2B`(nNl+T3uLOue H@*n^J-RTXH literal 100 zcmZQzV2EJ=0@ont05Ai{4gm=OK_U<*12GSXg9d7Wd=4O%1!9mo5S;|2L3)aS7$gq@ E06=R6g8%>k diff --git a/tools/pcre/testdata/saved32BE-1 b/tools/pcre/testdata/saved32BE-1 index 42af7b42b026869ac20fae8a78430470c298a8e3..609d97cdeba0099867aa8a4cc700c0d6c4f02da7 100644 GIT binary patch literal 560 zcmaiwOAY~15JjuCZ(`75LJVx6cOm8-3y=sB6Iw(AXc=j59IMRbb*-#T38EVQ~Q?n8OrusV0Oq%s_i9koGWy4yZnr zXTJ_QV31emskRQ!x`OK9izcjXLH;m#UX+Y?M)4**bc O`V0NL@o=c*3AXpT=kmA_7|&`jEe_AZ5> I+5V~V0$e6E<^TWy diff --git a/tools/pcre/testdata/saved32BE-2 b/tools/pcre/testdata/saved32BE-2 index 68a896d45b06c4208c0f52f803409d020d47b376..79bb5e8805564e92323778586754862667d682f7 100644 GIT binary patch delta 144 zcmX@We1h48fq`)f0|SFjfOC*5gw4SLQaL?#O`I*S$oStdXXQp*FxAS1IUXD}*rf@DAZe|wt2fgT)Gi$LaK;p&HD`2i$*))F(t1VyzbC|+Qax7s3Gtk`{qyr401MEGq$*xI1K O(7#I|sF!~#5%2`q4tyQ} literal 544 zcmZ{gNeaS15Jf9-hAb3U;=&8$0Pe+o@Bo6SAdV=y6g{T9Tp(vq-|r-nh<Uq+1F<3y zgLLFf>~&|%nRr#7vk=G=28m4OWpoxT0{%w43Y){3kZcq)-!O*CdwwsCYLa9G5`QgwGDg# literal 61 ucmZQzU@&C>0@ont05Ai{4g?7RK_Wvkg9d~NCu= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and - 16-bit PCRE libraries. --/ + Perl >= 5.10, in non-UTF-8 mode. It should run clean for the 8-bit, 16-bit, + and 32-bit PCRE libraries. --/ + +< forbid 89?=ABCDEFfGILMNPTUWXZ< /the quick brown fox/ the quick brown fox @@ -1483,14 +1485,19 @@ abc\100\x30 abc\100\060 abc\100\60 + +/^A\8B\9C$/ + A8B9C + *** Failers + A\08B\09C + +/^(A)(B)(C)(D)(E)(F)(G)(H)(I)\8\9$/ + ABCDEFGHIHI -/abc\81/ - abc\081 - abc\0\x38\x31 - -/abc\91/ - abc\091 - abc\0\x39\x31 +/^[A\8B\9C]+$/ + A8B9C + *** Failers + A8B9C\x00 /(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\12\123/ abcdefghijkllS @@ -3654,13 +3661,6 @@ /a*/g abbab -/^[a-\d]/ - abcde - -things - 0digit - *** Failers - bcdef - /^[\d-a]/ abcde -things @@ -3773,9 +3773,9 @@ abc123abc abc123bc -/-- This tests for an IPv6 address in the form where it can have up to --/ -/-- eight components, one and only one of which is empty. This must be --/ -/-- an internal component. --/ +/-- This tests for an IPv6 address in the form where it can have up to + eight components, one and only one of which is empty. This must be + an internal component. --/ /^(?!:) # colon disallowed at start (?: # start of item @@ -4221,9 +4221,6 @@ ab bc -/^(?=(a)){0}b(?1)/ - backgammon - /^(?=(?1))?[az]([abc])d/ abd zcdxx @@ -4656,16 +4653,10 @@ /(? \( ( [^()]++ | (?&pn) )* \) )/x (ab(cd)ef) -/^(?!a(*SKIP)b)/ - ac - /^(?=a(*SKIP)b|ac)/ ** Failers ac -/^(?=a(*THEN)b|ac)/ - ac - /^(?=a(*PRUNE)b)/ ab ** Failers @@ -4674,9 +4665,6 @@ /^(?=a(*ACCEPT)b)/ ac -/^(?(?!a(*SKIP)b))/ - ac - /(?>a\Kb)/ ab @@ -4899,33 +4887,15 @@ however, we need the complication for Perl. ---/ /(A (A|B(*ACCEPT)|C) D)(E)/x AB -/\A.*?(?:a|b(*THEN)c)/ - ba - -/\A.*?(?:a|bc)/ - ba - -/\A.*?(a|b(*THEN)c)/ - ba - /\A.*?(a|bc)/ ba -/\A.*?(?:a|b(*THEN)c)++/ - ba - /\A.*?(?:a|bc)++/ ba -/\A.*?(a|b(*THEN)c)++/ - ba - /\A.*?(a|bc)++/ ba -/\A.*?(?:a|b(*THEN)c|d)/ - ba - /\A.*?(?:a|bc|d)/ ba @@ -5253,9 +5223,6 @@ name were given. ---/ /(a(*COMMIT)b){0}a(?1)|aac/ aac -/(?!a(*COMMIT)b)ac|cd/ - ac - /((?:a?)*)*c/ aac @@ -5303,4 +5270,400 @@ name were given. ---/ "(?>.*?)foo" abcdfooxyz +/(?:(a(*PRUNE)b)){0}(?:(?1)|ac)/ + ac + +/(?:(a(*SKIP)b)){0}(?:(?1)|ac)/ + ac + +/(?<=(*SKIP)ac)a/ + aa + +/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK + AAAC + +/a(*SKIP:m)x|ac(*:n)(*SKIP:n)d|ac/K + acacd + +/A(*SKIP:m)x|A(*SKIP:n)x|AB/K + AB + +/((*SKIP:r)d){0}a(*SKIP:m)x|ac(*:n)|ac/K + acacd + +/-- Tests that try to figure out how Perl works. My hypothesis is that the + first verb that is backtracked onto is the one that acts. This seems to be + the case almost all the time, but there is one exception that is perhaps a + bug. --/ + +/-- This matches "aaaac"; each PRUNE advances one character until the subject + no longer starts with 5 'a's. --/ + +/aaaaa(*PRUNE)b|a+c/ + aaaaaac + +/-- Putting SKIP in front of PRUNE makes no difference, as it is never +backtracked onto, whether or not it has a label. --/ + +/aaaaa(*SKIP)(*PRUNE)b|a+c/ + aaaaaac + +/aaaaa(*SKIP:N)(*PRUNE)b|a+c/ + aaaaaac + +/aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c/ + aaaaaac + +/-- Putting THEN in front makes no difference. */ + +/aaaaa(*THEN)(*PRUNE)b|a+c/ + aaaaaac + +/-- However, putting COMMIT in front of the prune changes it to "no match". I + think this is inconsistent and possibly a bug. For the moment, running this + test is moved out of the Perl-compatible file. --/ + +/aaaaa(*COMMIT)(*PRUNE)b|a+c/ + + +/---- OK, lets play the same game again using SKIP instead of PRUNE. ----/ + +/-- This matches "ac" because SKIP forces the next match to start on the + sixth "a". --/ + +/aaaaa(*SKIP)b|a+c/ + aaaaaac + +/-- Putting PRUNE in front makes no difference. --/ + +/aaaaa(*PRUNE)(*SKIP)b|a+c/ + aaaaaac + +/-- Putting THEN in front makes no difference. --/ + +/aaaaa(*THEN)(*SKIP)b|a+c/ + aaaaaac + +/-- In this case, neither does COMMIT. This still matches "ac". --/ + +/aaaaa(*COMMIT)(*SKIP)b|a+c/ + aaaaaac + +/-- This gives "no match", as expected. --/ + +/aaaaa(*COMMIT)b|a+c/ + aaaaaac + + +/------ Tests using THEN ------/ + +/-- This matches "aaaaaac", as expected. --/ + +/aaaaa(*THEN)b|a+c/ + aaaaaac + +/-- Putting SKIP in front makes no difference. --/ + +/aaaaa(*SKIP)(*THEN)b|a+c/ + aaaaaac + +/-- Putting PRUNE in front makes no difference. --/ + +/aaaaa(*PRUNE)(*THEN)b|a+c/ + aaaaaac + +/-- Putting COMMIT in front makes no difference. --/ + +/aaaaa(*COMMIT)(*THEN)b|a+c/ + aaaaaac + +/-- End of "priority" tests --/ + +/aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+/ + aaaaaa + +/aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+/ + aaaaaa + +/aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+/ + aaaaaa + +/aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+/ + aaaaaa + +/a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c/ + aaaac + +/a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c/ + aaaac + +/aaa(*PRUNE:A)a(*SKIP:A)b|a+c/ + aaaac + +/aaa(*MARK:A)a(*SKIP:A)b|a+c/ + aaaac + +/a(*:m)a(*COMMIT)(*SKIP:m)b|a+c/K + aaaaaac + +/.?(a|b(*THEN)c)/ + ba + +/(a(*COMMIT)b)c|abd/ + abc + abd + +/(?=a(*COMMIT)b)abc|abd/ + abc + abd + +/(?>a(*COMMIT)b)c|abd/ + abc + abd + +/a(?=b(*COMMIT)c)[^d]|abd/ + abd + abc + +/a(?=bc).|abd/ + abd + abc + +/a(?>b(*COMMIT)c)d|abd/ + abceabd + +/a(?>bc)d|abd/ + abceabd + +/(?>a(*COMMIT)b)c|abd/ + abd + +/(?>a(*COMMIT)c)d|abd/ + abd + +/((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/ + ac + +/-- These tests were formerly in test 2, but changes in PCRE and Perl have + made them compatible. --/ + +/^(a)?(?(1)a|b)+$/ + *** Failers + a + +/(?=a\Kb)ab/ + ab + +/(?!a\Kb)ac/ + ac + +/^abc(?<=b\Kc)d/ + abcd + +/^abc(?b))/K + abc + +/(*PRUNE:m(m)(?&y)(?(DEFINE)(?b))/K + abc + +/(*SKIP:m(m)(?&y)(?(DEFINE)(?b))/K + abc + +/(*THEN:m(m)(?&y)(?(DEFINE)(?b))/K + abc + +/^\d*\w{4}/ + 1234 + 123 + +/^[^b]*\w{4}/ + aaaa + aaa + +/^[^b]*\w{4}/i + aaaa + aaa + +/^a*\w{4}/ + aaaa + aaa + +/^a*\w{4}/i + aaaa + aaa + +/(?(?=ab)ab)/+ + ca + cd + +/(?:(?foo)|(?bar))\k/J + foofoo + barbar + +/(?A)(?:(?foo)|(?bar))\k/J + AfooA + AbarA + ** Failers + Afoofoo + Abarbar + +/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ + 1 IN SOA non-sp1 non-sp2( + +/^ (?:(?A)|(?'B'B)(?A)) (?('A')x) (?()y)$/xJ + Ax + BAxy + +/^A\xZ/ + A\0Z + +/^A\o{123}B/ + A\123B + +/ ^ a + + b $ /x + aaaab + +/ ^ a + #comment + + b $ /x + aaaab + +/ ^ a + #comment + #comment + + b $ /x + aaaab + +/ ^ (?> a + ) b $ /x + aaaab + +/ ^ ( a + ) + + \w $ /x + aaaab + +/(?:a\Kb)*+/+ + ababc + +/(?>a\Kb)*/+ + ababc + +/(?:a\Kb)*/+ + ababc + +/(a\Kb)*+/+ + ababc + +/(a\Kb)*/+ + ababc + /-- End of testinput1 --/ diff --git a/tools/pcre/testdata/testinput10 b/tools/pcre/testdata/testinput10 index f20dcb3d..93ddb3a7 100644 --- a/tools/pcre/testdata/testinput10 +++ b/tools/pcre/testdata/testinput10 @@ -139,6 +139,12 @@ /^\p{Cf}/8 \x{601} + \x{180e} + \x{061c} + \x{2066} + \x{2067} + \x{2068} + \x{2069} ** Failers \x{09f} @@ -199,11 +205,12 @@ /^\p{Mn}/8 \x{300} + \x{1a1b} ** Failers X \x{903} -/^\p{Nd}+/8 +/^\p{Nd}+/8O 0123456789\x{660}\x{661}\x{662}\x{663}\x{664}\x{665}\x{666}\x{667}\x{668}\x{669}\x{66a} \x{6f0}\x{6f1}\x{6f2}\x{6f3}\x{6f4}\x{6f5}\x{6f6}\x{6f7}\x{6f8}\x{6f9}\x{6fa} \x{966}\x{967}\x{968}\x{969}\x{96a}\x{96b}\x{96c}\x{96d}\x{96e}\x{96f}\x{970} @@ -243,6 +250,8 @@ ] } \x{f3b} + \x{2309} + \x{230b} ** Failers X \x{203f} @@ -250,7 +259,7 @@ [ { \x{f3c} - + /^\p{Pf}/8 \x{bb} \x{2019} @@ -277,6 +286,8 @@ [ { \x{f3c} + \x{2308} + \x{230a} ** Failers X ) @@ -326,7 +337,6 @@ \ \ \x{a0} \x{1680} - \x{180e} \x{2000} \x{2001} ** Failers @@ -423,23 +433,23 @@ ** Failers 1234 -/\D+/8 +/\D+/8O 11111111111111111111111111111111111111111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/\P{Nd}+/8 +/\P{Nd}+/8O 11111111111111111111111111111111111111111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/[\D]+/8 +/[\D]+/8O 11111111111111111111111111111111111111111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/[\P{Nd}]+/8 +/[\P{Nd}]+/8O 11111111111111111111111111111111111111111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/[\D\P{Nd}]+/8 +/[\D\P{Nd}]+/8O 11111111111111111111111111111111111111111111111111111111111111111111111 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -886,19 +896,19 @@ ** Failers \x{0b} -/^>\p{Xsp}+/8 +/^>\p{Xsp}+/8O > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/^>\p{Xsp}*/8 +/^>\p{Xsp}*/8O > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/^>\p{Xsp}{2,9}/8 +/^>\p{Xsp}{2,9}/8O > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/^>[\p{Xsp}]/8 +/^>[\p{Xsp}]/8O >\x{2028}\x{0b} -/^>[\p{Xsp}]+/8 +/^>[\p{Xsp}]+/8O > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}/8 @@ -1334,4 +1344,76 @@ /is{2}t/8i iskt +/^\p{Xuc}/8 + $abc + @abc + `abc + \x{1234}abc + ** Failers + abc + +/^\p{Xuc}+/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\p{Xuc}+?/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\p{Xuc}+?\*/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\p{Xuc}++/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\p{Xuc}{3,5}/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\p{Xuc}{3,5}?/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^[\p{Xuc}]/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^[\p{Xuc}]+/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\P{Xuc}/8 + abc + ** Failers + $abc + @abc + `abc + \x{1234}abc + +/^[\P{Xuc}]/8 + abc + ** Failers + $abc + @abc + `abc + \x{1234}abc + +/^A\s+Z/8W + A\x{2005}Z + A\x{85}\x{180e}\x{2005}Z + +/^A[\s]+Z/8W + A\x{2005}Z + A\x{85}\x{180e}\x{2005}Z + /-- End of testinput10 --/ diff --git a/tools/pcre/testdata/testinput12 b/tools/pcre/testdata/testinput12 index 7deba3c4..5d727af2 100644 --- a/tools/pcre/testdata/testinput12 +++ b/tools/pcre/testdata/testinput12 @@ -4,7 +4,9 @@ and a couple of things that are different with JIT. --/ /abc/S+I -/ab(*THEN)/S+I +/(?(?C1)(?=a)a)/S+I + +/(?(?C1)(?=a)a)/S!+I /abc/S+I>testsavedregex @@ -82,8 +84,7 @@ and a couple of things that are different with JIT. --/ /(*NO_START_OPT)a(*:m)b/KS++ a -/.?(*THEN)/S+I - -/.?(*THEN)/S!+I +/^12345678abcd/mS++ + 12345678abcd /-- End of testinput12 --/ diff --git a/tools/pcre/testdata/testinput14 b/tools/pcre/testdata/testinput14 index e5e85207..325ed9e3 100644 --- a/tools/pcre/testdata/testinput14 +++ b/tools/pcre/testdata/testinput14 @@ -1,6 +1,9 @@ -/-- 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. --/ +/-- This set of tests is run only with the 8-bit library. They do not require + UTF-8 or Unicode property support. The file starts with all the tests of + the POSIX interface, because that is supported only with the 8-bit library. + --/ + +< forbid 8W /abc/P abc @@ -85,9 +88,12 @@ a\nb ** Failers (too big char) A\x{123}B + A\o{443}B /\x{100}/I +/\o{400}/I + / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment @@ -294,8 +300,12 @@ not matter. --/ /\h/SI +/\H/SI + /\v/SI +/\V/SI + /\R/SI /[\h]/BZ @@ -326,4 +336,8 @@ not matter. --/ /[\u0100-\u0200]/ +/[^\x00-a]{12,}[^b-\xff]*/BZ + +/[^\s]*\s* [^\W]+\W+ [^\d]*?\d0 [^\d\w]{4,6}?\w*A/BZ + /-- End of testinput14 --/ diff --git a/tools/pcre/testdata/testinput15 b/tools/pcre/testdata/testinput15 index 6445d435..83e26773 100644 --- a/tools/pcre/testdata/testinput15 +++ b/tools/pcre/testdata/testinput15 @@ -1,5 +1,7 @@ -/-- This set of tests is for UTF-8 support, and is relevant only to the 8-bit - library. --/ +/-- This set of tests is for UTF-8 support but not Unicode property support, + and is relevant only to the 8-bit library. --/ + +< forbid W /X(\C{3})/8 X\x{1234} @@ -47,7 +49,7 @@ /ÃÃÃxxx/8 -/ÃÃÃxxx/8?DZSS +/ÃÃÃxxx/8?DZSSO /badutf/8 \xdf @@ -89,7 +91,6 @@ \x80 \xfe \xff - \xef\xb7\x90 /badutf/8 \xfb\x80\x80\x80\x80 @@ -136,74 +137,6 @@ \?\xfc\x84\x80\x80\x80\x80 \?\xfd\x83\x80\x80\x80\x80 -/noncharacter/8 - \x{fffe} - \x{ffff} - \x{1fffe} - \x{1ffff} - \x{2fffe} - \x{2ffff} - \x{3fffe} - \x{3ffff} - \x{4fffe} - \x{4ffff} - \x{5fffe} - \x{5ffff} - \x{6fffe} - \x{6ffff} - \x{7fffe} - \x{7ffff} - \x{8fffe} - \x{8ffff} - \x{9fffe} - \x{9ffff} - \x{afffe} - \x{affff} - \x{bfffe} - \x{bffff} - \x{cfffe} - \x{cffff} - \x{dfffe} - \x{dffff} - \x{efffe} - \x{effff} - \x{ffffe} - \x{fffff} - \x{10fffe} - \x{10ffff} - \x{fdd0} - \x{fdd1} - \x{fdd2} - \x{fdd3} - \x{fdd4} - \x{fdd5} - \x{fdd6} - \x{fdd7} - \x{fdd8} - \x{fdd9} - \x{fdda} - \x{fddb} - \x{fddc} - \x{fddd} - \x{fdde} - \x{fddf} - \x{fde0} - \x{fde1} - \x{fde2} - \x{fde3} - \x{fde4} - \x{fde5} - \x{fde6} - \x{fde7} - \x{fde8} - \x{fde9} - \x{fdea} - \x{fdeb} - \x{fdec} - \x{fded} - \x{fdee} - \x{fdef} - /\x{100}/8DZ /\x{1000}/8DZ @@ -310,7 +243,6 @@ correctly, but that messes up comparisons). --/ /-- 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} @@ -427,4 +359,8 @@ correctly, but that messes up comparisons). --/ \x{ff000041} \x{7f000041} +/(*UTF8)abc/9 + +/abc/89 + /-- End of testinput15 --/ diff --git a/tools/pcre/testdata/testinput17 b/tools/pcre/testdata/testinput17 index ba803188..1d933c79 100644 --- a/tools/pcre/testdata/testinput17 +++ b/tools/pcre/testdata/testinput17 @@ -1,6 +1,8 @@ /-- This set of tests is for the 16- and 32-bit library's basic (non-UTF-16 or -32) features that are not compatible with the 8-bit library, or which give different output in 16- or 32-bit mode. --/ + +< forbid 8W /a\Cb/ aXb @@ -293,4 +295,13 @@ /^\x{ffff}{0,3}/i \x{ffff} +/[^\x00-a]{12,}[^b-\xff]*/BZ + +/[^\s]*\s* [^\W]+\W+ [^\d]*?\d0 [^\d\w]{4,6}?\w*A/BZ + +/a*[b-\x{200}]?a#a*[b-\x{200}]?b#[a-f]*[g-\x{200}]*#[g-\x{200}]*[a-c]*#[g-\x{200}]*[a-h]*/BZ + +/^[\x{1234}\x{4321}]{2,4}?/ + \x{1234}\x{1234}\x{1234} + /-- End of testinput17 --/ diff --git a/tools/pcre/testdata/testinput18 b/tools/pcre/testdata/testinput18 index 7f87ca2c..2dfb54cd 100644 --- a/tools/pcre/testdata/testinput18 +++ b/tools/pcre/testdata/testinput18 @@ -1,5 +1,7 @@ -/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to the - 16- and 32-bit library. --/ +/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to + the 16- and 32-bit libraries. --/ + +< forbid W /ÃÃÃxxx/8?DZSS @@ -156,7 +158,6 @@ correctly, but that messes up comparisons). --/ /^[\QÄ€\E-\QÅ\E/BZ8 /X/8 - \x{0}\x{d7ff}\x{e000}\x{10ffff} \x{d800} \x{d800}\? \x{da00} @@ -169,7 +170,6 @@ correctly, but that messes up comparisons). --/ \x{dfff}\? \x{110000} \x{d800}\x{1234} - \x{fffe} /(*UTF16)\x{11234}/ abcd\x{11234}pqr @@ -207,7 +207,7 @@ correctly, but that messes up comparisons). --/ CDBABC \x{2000}ABC -/\R*A/SI8 +/\R*A/SI8 CDBABC \x{2028}A @@ -293,4 +293,8 @@ correctly, but that messes up comparisons). --/ /\x{a0}+\s!/8BZT1 \x{a0}\x20! +/(*UTF)abc/9 + +/abc/89 + /-- End of testinput18 --/ diff --git a/tools/pcre/testdata/testinput2 b/tools/pcre/testdata/testinput2 index 9670104e..da6e6149 100644 --- a/tools/pcre/testdata/testinput2 +++ b/tools/pcre/testdata/testinput2 @@ -7,6 +7,8 @@ NOTE: This is a non-UTF set of tests. When UTF support is needed, use test 5, and if Unicode Property Support is needed, use test 7. --/ + +< forbid 8W /(a)b|/I @@ -313,12 +315,6 @@ *** Failers fooabar -/This one is here because Perl 5.005_02 doesn't fail it/I - -/^(a)?(?(1)a|b)+$/I - *** Failers - a - /This one is here because Perl behaves differently; see also the following/I /^(a\1?){4}$/I @@ -835,7 +831,13 @@ /x++/DZ -/x{1,3}+/DZ +/x{1,3}+/BZO + +/x{1,3}+/BZOi + +/[^x]{1,3}+/BZO + +/[^x]{1,3}+/BZOi /(x)*+/DZ @@ -905,6 +907,9 @@ /\U/I +/a{1,3}b/U + ab + /[/I /[a-/I @@ -1501,6 +1506,8 @@ a2b\CA ** Failers a1b\CZ\CA + +/(?|(?)(?)(?)|(?)(?)(?))/IJ /^(?Pa)(?Pb)/IJ ab\CA @@ -1941,10 +1948,7 @@ a random value. /Ix /(? (?'B' abc (?(R) (?(R&A)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x abcabc1Xabc2XabcXabcabc -/(? (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x - -/(?<1> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x - abcabc1Xabc2XabcXabcabc +/(? (?'B' abc (?(R) (?(R&C)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x /^(?(DEFINE) abc | xyz ) /x @@ -2061,7 +2065,7 @@ a random value. /Ix /^(a)\g{3/ -/^(a)\g{4a}/ +/^(a)\g{aa}/ /^a.b/ a\rb @@ -2516,7 +2520,10 @@ a random value. /Ix ** Failers ab -/a(?!)+b/ +/a(?!)b/BZ + +/(?!)?a/BZ + ab /a(*FAIL)+b/ @@ -2541,7 +2548,9 @@ a random value. /Ix abcxypqr\Y /(*NO_START_OPT)xyz/C - abcxyz + abcxyz + +/(*NO_AUTO_POSSESS)a+b/BZ /xyz/CY abcxyz @@ -2939,7 +2948,7 @@ a random value. /Ix xxxxabcde\P xxxxabcde\P\P -/-- This is not in the Perl >= 5.10 test because Perl seems currently to be +/-- This is not in the Perl-compatible test because Perl seems currently to be broken and not behaving as specified in that it *does* bumpalong after hitting (*COMMIT). --/ @@ -2985,28 +2994,12 @@ a random value. /Ix /^(?&t)*(?(DEFINE)(?.))$/BZ -/ -- The first four of these are not in the Perl >= 5.10 test because Perl - documents that the use of \K in assertions is "not well defined". The - last is here because Perl gives the match as "b" rather than "ab". I +/ -- This one is here because Perl gives the match as "b" rather than "ab". I believe this to be a Perl bug. --/ -/(?=a\Kb)ab/ - ab - -/(?!a\Kb)ac/ - ac - -/^abc(?<=b\Kc)d/ - abcd - -/^abc(?a\Kb)z|(ab)/ ab -/----------------------/ - /(?P(?P0|)|(?P>L2)(?P>L1))/ /abc(*MARK:)pqr/ @@ -3021,7 +3014,7 @@ a random value. /Ix /A(*COMMIT)B/+K ACABX -/--- These should be different, but in Perl 5.11 are not, which I think +/--- These should be different, but in Perl they are not, which I think is a bug in Perl. ---/ /A(*THEN)B|A(*THEN)C/K @@ -3030,12 +3023,6 @@ a random value. /Ix /A(*PRUNE)B|A(*PRUNE)C/K AC -/--- This should fail; the SKIP advances by one, but when we get to AC, the - PRUNE kills it. Perl behaves differently. ---/ - -/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK - AAAC - /--- Mark names can be duplicated. Perl doesn't give a mark for this one, though PCRE does. ---/ @@ -3061,7 +3048,7 @@ with \Y. ---/ /^(ab (c+(*FAIL)cd) | xyz)/x abcccd -/--- Perl 5.11 gets some of these wrong ---/ +/--- Perl gets some of these wrong ---/ /(?>.(*ACCEPT))*?5/ abcde @@ -3121,14 +3108,6 @@ with \Y. ---/ /X\H++\R/BZ X\x0d\x0a -/-- Perl treats this one differently, not failing the second string. I believe - that is a bug in Perl. --/ - -/^((abc|abcx)(*THEN)y|abcd)/ - abcd - *** Failers - abcxy - /(?<=abc)def/ abc\P\P @@ -3427,7 +3406,7 @@ with \Y. ---/ /\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|a+)(?>(z+))\w/BZ aaaazzzzb ** Failers @@ -3564,6 +3497,8 @@ AbcdCBefgBhiBqz /a[B-\Nc]/ +/a[B\Nc]/ + /(a)(?2){0,1999}?(b)/ /(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/ @@ -3751,24 +3686,9 @@ replaced by single letters. --/ \r\r\r\P \r\r\r\P\P -/-- These two are here because Perl does not match: it seems to allow the -COMMIT to escape from the assertion. --/ - -/(?=a(*COMMIT)b|ac)ac|ac/ - ac - -/(?=a(*COMMIT)b|(ac)) ac | (a)c/x - ac - "AB(C(D))(E(F))?(?(?=\2)(?=\4))" ABCDGHI\O03 -/-- This one is here because Perl does not confine the *COMMIT to the -assertion, and therefore fails the entire subroutine call. --/ - -/((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/ - ac - /-- These are all run as real matches in test 1; here we are just checking the settings of the anchored and startline bits. --/ @@ -3810,4 +3730,336 @@ settings of the anchored and startline bits. --/ /.?/S!I +/(?:(a)+(?C1)bb|aa(?C2)b)/ + aab\C+ + +/(?:(a)++(?C1)bb|aa(?C2)b)/ + aab\C+ + +/(?:(?>(a))(?C1)bb|aa(?C2)b)/ + aab\C+ + +/(?:(?1)(?C1)x|ab(?C2))((a)){0}/ + aab\C+ + +/(?1)(?C1)((a)(?C2)){0}/ + aab\C+ + +/(?:(a)+(?C1)bb|aa(?C2)b)++/ + aab\C+ + aab\C+\O2 + +/(ab)x|ab/ + ab\O3 + ab\O2 + +/(ab)/ + ab\O3 + ab\O2 + +/(?<=123)(*MARK:xx)abc/K + xxxx123a\P\P + xxxx123a\P + +/123\Kabc/ + xxxx123a\P\P + xxxx123a\P + +/^(?(?=a)aa|bb)/C + bb + +/(?C1)^(?C2)(?(?C99)(?=(?C3)a(?C4))(?C5)a(?C6)a(?C7)|(?C8)b(?C9)b(?C10))(?C11)/ + bb + +/-- Perl seems to have a bug with this one --/ + +/aaaaa(*COMMIT)(*PRUNE)b|a+c/ + aaaaaac + +/-- Here are some that Perl treats differently because of the way it handles +backtracking verbs. --/ + + /(?!a(*COMMIT)b)ac|ad/ + ac + ad + +/^(?!a(*THEN)b|ac)../ + ac + ad + +/^(?=a(*THEN)b|ac)/ + ac + +/\A.*?(?:a|b(*THEN)c)/ + ba + +/\A.*?(?:a|b(*THEN)c)++/ + ba + +/\A.*?(?:a|b(*THEN)c|d)/ + ba + +/(?:(a(*MARK:X)a+(*SKIP:X)b)){0}(?:(?1)|aac)/ + aac + +/\A.*?(a|b(*THEN)c)/ + ba + +/^(A(*THEN)B|A(*THEN)D)/ + AD + +/(?!b(*THEN)a)bn|bnn/ + bnn + +/(?(?=b(*SKIP)a)bn|bnn)/ + bnn + +/(?=b(*THEN)a|)bn|bnn/ + bnn + +/-------------------------/ + +/(*LIMIT_MATCH=12bc)abc/ + +/(*LIMIT_MATCH=4294967290)abc/ + +/(*LIMIT_RECURSION=4294967280)abc/I + +/(a+)*zz/ + aaaaaaaaaaaaaz + aaaaaaaaaaaaaz\q3000 + +/(a+)*zz/S- + aaaaaaaaaaaaaz\Q10 + +/(*LIMIT_MATCH=3000)(a+)*zz/I + aaaaaaaaaaaaaz + aaaaaaaaaaaaaz\q60000 + +/(*LIMIT_MATCH=60000)(*LIMIT_MATCH=3000)(a+)*zz/I + aaaaaaaaaaaaaz + +/(*LIMIT_MATCH=60000)(a+)*zz/I + aaaaaaaaaaaaaz + aaaaaaaaaaaaaz\q3000 + +/(*LIMIT_RECURSION=10)(a+)*zz/IS- + aaaaaaaaaaaaaz + aaaaaaaaaaaaaz\Q1000 + +/(*LIMIT_RECURSION=10)(*LIMIT_RECURSION=1000)(a+)*zz/IS- + aaaaaaaaaaaaaz + +/(*LIMIT_RECURSION=1000)(a+)*zz/IS- + aaaaaaaaaaaaaz + aaaaaaaaaaaaaz\Q10 + +/-- This test causes a segfault with Perl 5.18.0 --/ + +/^(?=(a)){0}b(?1)/ + backgammon + +/(?|(?f)|(?b))/JI + +/(?abc)(?z)\k()/JDZS + +/a*[bcd]/BZ + +/[bcd]*a/BZ + +/-- A complete set of tests for auto-possessification of character types --/ + +/\D+\D \D+\d \D+\S \D+\s \D+\W \D+\w \D+. \D+\C \D+\R \D+\H \D+\h \D+\V \D+\v \D+\Z \D+\z \D+$/BZx + +/\d+\D \d+\d \d+\S \d+\s \d+\W \d+\w \d+. \d+\C \d+\R \d+\H \d+\h \d+\V \d+\v \d+\Z \d+\z \d+$/BZx + +/\S+\D \S+\d \S+\S \S+\s \S+\W \S+\w \S+. \S+\C \S+\R \S+\H \S+\h \S+\V \S+\v \S+\Z \S+\z \S+$/BZx + +/\s+\D \s+\d \s+\S \s+\s \s+\W \s+\w \s+. \s+\C \s+\R \s+\H \s+\h \s+\V \s+\v \s+\Z \s+\z \s+$/BZx + +/\W+\D \W+\d \W+\S \W+\s \W+\W \W+\w \W+. \W+\C \W+\R \W+\H \W+\h \W+\V \W+\v \W+\Z \W+\z \W+$/BZx + +/\w+\D \w+\d \w+\S \w+\s \w+\W \w+\w \w+. \w+\C \w+\R \w+\H \w+\h \w+\V \w+\v \w+\Z \w+\z \w+$/BZx + +/\C+\D \C+\d \C+\S \C+\s \C+\W \C+\w \C+. \C+\C \C+\R \C+\H \C+\h \C+\V \C+\v \C+\Z \C+\z \C+$/BZx + +/\R+\D \R+\d \R+\S \R+\s \R+\W \R+\w \R+. \R+\C \R+\R \R+\H \R+\h \R+\V \R+\v \R+\Z \R+\z \R+$/BZx + +/\H+\D \H+\d \H+\S \H+\s \H+\W \H+\w \H+. \H+\C \H+\R \H+\H \H+\h \H+\V \H+\v \H+\Z \H+\z \H+$/BZx + +/\h+\D \h+\d \h+\S \h+\s \h+\W \h+\w \h+. \h+\C \h+\R \h+\H \h+\h \h+\V \h+\v \h+\Z \h+\z \h+$/BZx + +/\V+\D \V+\d \V+\S \V+\s \V+\W \V+\w \V+. \V+\C \V+\R \V+\H \V+\h \V+\V \V+\v \V+\Z \V+\z \V+$/BZx + +/\v+\D \v+\d \v+\S \v+\s \v+\W \v+\w \v+. \v+\C \v+\R \v+\H \v+\h \v+\V \v+\v \v+\Z \v+\z \v+$/BZx + +/ a+\D a+\d a+\S a+\s a+\W a+\w a+. a+\C a+\R a+\H a+\h a+\V a+\v a+\Z a+\z a+$/BZx + +/\n+\D \n+\d \n+\S \n+\s \n+\W \n+\w \n+. \n+\C \n+\R \n+\H \n+\h \n+\V \n+\v \n+\Z \n+\z \n+$/BZx + +/ .+\D .+\d .+\S .+\s .+\W .+\w .+. .+\C .+\R .+\H .+\h .+\V .+\v .+\Z .+\z .+$/BZx + +/ .+\D .+\d .+\S .+\s .+\W .+\w .+. .+\C .+\R .+\H .+\h .+\V .+\v .+\Z .+\z .+$/BZxs + +/\D+$ \d+$ \S+$ \s+$ \W+$ \w+$ \C+$ \R+$ \H+$ \h+$ \V+$ \v+$ a+$ \n+$ .+$ .+$/BZxm + +/(?=a+)a(a+)++a/BZ + +/a+(bb|cc)a+(?:bb|cc)a+(?>bb|cc)a+(?:bb|cc)+a+(aa)a+(?:bb|aa)/BZ + +/a+(bb|cc)?#a+(?:bb|cc)??#a+(?:bb|cc)?+#a+(?:bb|cc)*#a+(bb|cc)?a#a+(?:aa)?/BZ + +/a+(?:bb)?a#a+(?:|||)#a+(?:|b)a#a+(?:|||)?a/BZ + +/[ab]*/BZ + aaaa + +/[ab]*?/BZ + aaaa + +/[ab]?/BZ + aaaa + +/[ab]??/BZ + aaaa + +/[ab]+/BZ + aaaa + +/[ab]+?/BZ + aaaa + +/[ab]{2,3}/BZ + aaaa + +/[ab]{2,3}?/BZ + aaaa + +/[ab]{2,}/BZ + aaaa + +/[ab]{2,}?/BZ + aaaa + +/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/BZ + +/[a-d]{5,12}[e-z0-9]*#[^a-z]+[b-y]*a[2-7]?[^0-9a-z]+/BZ + +/[a-z]*\s#[ \t]?\S#[a-c]*\S#[C-G]+?\d#[4-8]*\D#[4-9,]*\D#[!$]{0,5}\w#[M-Xf-l]+\W#[a-c,]?\W/BZ + +/a+(aa|bb)*c#a*(bb|cc)*a#a?(bb|cc)*d#[a-f]*(g|hh)*f/BZ + +/[a-f]*(g|hh|i)*i#[a-x]{4,}(y{0,6})*y#[a-k]+(ll|mm)+n/BZ + +/[a-f]*(?>gg|hh)+#[a-f]*(?>gg|hh)?#[a-f]*(?>gg|hh)*a#[a-f]*(?>gg|hh)*h/BZ + +/[a-c]*d/DZS + +/[a-c]+d/DZS + +/[a-c]?d/DZS + +/[a-c]{4,6}d/DZS + +/[a-c]{0,6}d/DZS + +/-- End of special auto-possessive tests --/ + +/^A\o{1239}B/ + A\123B + +/^A\oB/ + +/^A\x{zz}B/ + +/^A\x{12Z/ + +/^A\x{/ + +/[ab]++/BZO + +/[^ab]*+/BZO + +/a{4}+/BZO + +/a{4}+/BZOi + +/[a-[:digit:]]+/ + +/[A-[:digit:]]+/ + +/[a-[.xxx.]]+/ + +/[a-[=xxx=]]+/ + +/[a-[!xxx!]]+/ + +/[A-[!xxx!]]+/ + A]]] + +/[a-\d]+/ + +/(?<0abc>xx)/ + +/(?&1abc)xx(?<1abc>y)/ + +/(?xx)/ + +/(?'0abc'xx)/ + +/(?P<0abc>xx)/ + +/\k<5ghj>/ + +/\k'5ghj'/ + +/\k{2fgh}/ + +/(?P=8yuki)/ + +/\g{4df}/ + +/(?&1abc)xx(?<1abc>y)/ + +/(?P>1abc)xx(?<1abc>y)/ + +/\g'3gh'/ + +/\g<5fg>/ + +/(?(<4gh>)abc)/ + +/(?('4gh')abc)/ + +/(?(4gh)abc)/ + +/(?(R&6yh)abc)/ + +/-- Test the ugly "start or end of word" compatibility syntax --/ + +/[[:<:]]red[[:>:]]/BZ + little red riding hood + a /red/ thing + red is a colour + put it all on red + ** Failers + no reduction + Alfred Winifred + +/[a[:<:]] should give error/ + +/(?=ab\K)/+ + abcd + +/abcd/f + xx\nxabcd + +/ -- Test stack check external calls --/ + +/(((((a)))))/Q0 + +/(((((a)))))/Q1 + +/(((((a)))))/Q + /-- End of testinput2 --/ diff --git a/tools/pcre/testdata/testinput21 b/tools/pcre/testdata/testinput21 index 0f201ada..30895eef 100644 --- a/tools/pcre/testdata/testinput21 +++ b/tools/pcre/testdata/testinput21 @@ -1,9 +1,19 @@ -/-- Tests for reloading pre-compile patterns. The first one gives an error -right away. The others require the linke size to be 2. */ +/-- Tests for reloading pre-compiled patterns. The first one gives an error +right away, and can be any old pattern compiled in 8-bit mode ("abc" is +typical). The others require the link size to be 2. */x (?:[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}$ --/ +%-- Generated from: + /^[aL](?P(?:[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}$ + /x + + In 16-bit mode with options: S>testdata/saved16LE-1 + FS>testdata/saved16BE-1 + In 32-bit mode with options: S>testdata/saved32LE-1 + FS>testdata/saved32BE-1 +--%x [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 +%-- Generated from: + /(?P[aZ\x{400}-\x{10ffff}]{4,} + [\x{f123}\x{10039}\x{20000}-\x{21234}]?| + [A-Cx-z\x{100000}-\x{1000a7}\x{101234}]) + (?[^az])/x + + In 16-bit mode with options: S8>testdata/saved16LE-2 + FS8>testdata/saved16BE-2 + In 32-bit mode with options: S8>testdata/saved32LE-2 + FS8>testdata/saved32BE-2 +--%8x = 5.10 and both the 8-bit and 16-bit PCRE libraries. --/ + +< forbid 9?=ABCDEFfGILMNPTUWXZ< /a.b/8 acb @@ -621,4 +623,103 @@ /a(*:a£b)/8K abc +/-- Noncharacters --/ + +/./8 + \x{fffe} + \x{ffff} + \x{1fffe} + \x{1ffff} + \x{2fffe} + \x{2ffff} + \x{3fffe} + \x{3ffff} + \x{4fffe} + \x{4ffff} + \x{5fffe} + \x{5ffff} + \x{6fffe} + \x{6ffff} + \x{7fffe} + \x{7ffff} + \x{8fffe} + \x{8ffff} + \x{9fffe} + \x{9ffff} + \x{afffe} + \x{affff} + \x{bfffe} + \x{bffff} + \x{cfffe} + \x{cffff} + \x{dfffe} + \x{dffff} + \x{efffe} + \x{effff} + \x{ffffe} + \x{fffff} + \x{10fffe} + \x{10ffff} + \x{fdd0} + \x{fdd1} + \x{fdd2} + \x{fdd3} + \x{fdd4} + \x{fdd5} + \x{fdd6} + \x{fdd7} + \x{fdd8} + \x{fdd9} + \x{fdda} + \x{fddb} + \x{fddc} + \x{fddd} + \x{fdde} + \x{fddf} + \x{fde0} + \x{fde1} + \x{fde2} + \x{fde3} + \x{fde4} + \x{fde5} + \x{fde6} + \x{fde7} + \x{fde8} + \x{fde9} + \x{fdea} + \x{fdeb} + \x{fdec} + \x{fded} + \x{fdee} + \x{fdef} + +/^\d*\w{4}/8 + 1234 + 123 + +/^[^b]*\w{4}/8 + aaaa + aaa + +/^[^b]*\w{4}/8i + aaaa + aaa + +/^\x{100}*.{4}/8 + \x{100}\x{100}\x{100}\x{100} + \x{100}\x{100}\x{100} + +/^\x{100}*.{4}/8i + \x{100}\x{100}\x{100}\x{100} + \x{100}\x{100}\x{100} + +/^a+[a\x{200}]/8 + aa + +/^.\B.\B./8 + \x{10123}\x{10124}\x{10125} + +/^#[^\x{ffff}]#[^\x{ffff}]#[^\x{ffff}]#/8 + #\x{10000}#\x{100}#\x{10ffff}# + /-- End of testinput4 --/ diff --git a/tools/pcre/testdata/testinput5 b/tools/pcre/testdata/testinput5 index 642749c3..e36b09d6 100644 --- a/tools/pcre/testdata/testinput5 +++ b/tools/pcre/testdata/testinput5 @@ -1,21 +1,37 @@ /-- This set of tests checks the API, internals, and non-Perl stuff for UTF support, excluding Unicode properties. However, tests that give different results in 8-bit and 16-bit modes are excluded (see tests 16 and 17). --/ + +< forbid W /\x{110000}/8DZ +/\o{4200000}/8DZ + /\x{ffffffff}/8 +/\o{37777777777}/8 + /\x{100000000}/8 +/\o{77777777777}/8 + /\x{d800}/8 +/\o{154000}/8 + /\x{dfff}/8 +/\o{157777}/8 + /\x{d7ff}/8 +/\o{153777}/8 + /\x{e000}/8 +/\o{170000}/8 + /^\x{100}a\x{1234}/8 \x{100}a\x{1234}bcd @@ -769,4 +785,9 @@ /\ud800/8 +/^a+[a\x{200}]/8BZ + aa + +/[b-d\x{200}-\x{250}]*[ae-h]?#[\x{200}-\x{250}]{0,8}[\x00-\xff]*#[\x{200}-\x{250}]+[a-z]/8BZ + /-- End of testinput5 --/ diff --git a/tools/pcre/testdata/testinput6 b/tools/pcre/testdata/testinput6 index a4bfb3c1..7a6a53f1 100644 --- a/tools/pcre/testdata/testinput6 +++ b/tools/pcre/testdata/testinput6 @@ -1,5 +1,7 @@ /-- This set of tests is for Unicode property support. It is compatible with Perl >= 5.15. --/ + +< forbid 9?=ABCDEFfGILMNPTUXZ< /^\pC\pL\pM\pN\pP\pS\pZ06\? + /-- --/ /\x{1e9e}+/8i @@ -1316,4 +1322,175 @@ /\x{017f}+/8i \x{0053}\x{0073}\x{017f} +/^\p{Any}*\d{4}/8 + 1234 + 123 + +/^\X*\w{4}/8 + 1234 + 123 + +/^A\s+Z/8W + A\x{2005}Z + A\x{85}\x{180e}\x{2005}Z + +/^A[\s]+Z/8W + A\x{2005}Z + A\x{85}\x{180e}\x{2005}Z + +/^[[:graph:]]+$/8W + Letter:ABC + Mark:\x{300}\x{1d172}\x{1d17b} + Number:9\x{660} + Punctuation:\x{66a},; + Symbol:\x{6de}<>\x{fffc} + Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f} + \x{200b}\x{200c}\x{200d}\x{200e}\x{200f} + \x{202a}\x{202b}\x{202c}\x{202d}\x{202e} + \x{2060}\x{2061}\x{2062}\x{2063}\x{2064} + \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f} + \x{feff} + \x{fff9}\x{fffa}\x{fffb} + \x{110bd} + \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a} + \x{e0001} + \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f} + ** Failers + \x{09} + \x{0a} + \x{1D} + \x{20} + \x{85} + \x{a0} + \x{61c} + \x{1680} + \x{180e} + \x{2028} + \x{2029} + \x{202f} + \x{2065} + \x{2066} + \x{2067} + \x{2068} + \x{2069} + \x{3000} + \x{e0002} + \x{e001f} + \x{e0080} + +/^[[:print:]]+$/8W + Space: \x{a0} + \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005} + \x{2006}\x{2007}\x{2008}\x{2009}\x{200a} + \x{202f}\x{205f} + \x{3000} + Letter:ABC + Mark:\x{300}\x{1d172}\x{1d17b} + Number:9\x{660} + Punctuation:\x{66a},; + Symbol:\x{6de}<>\x{fffc} + Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f} + \x{180e} + \x{200b}\x{200c}\x{200d}\x{200e}\x{200f} + \x{202a}\x{202b}\x{202c}\x{202d}\x{202e} + \x{202f} + \x{2060}\x{2061}\x{2062}\x{2063}\x{2064} + \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f} + \x{feff} + \x{fff9}\x{fffa}\x{fffb} + \x{110bd} + \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a} + \x{e0001} + \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f} + ** Failers + \x{09} + \x{1D} + \x{85} + \x{61c} + \x{2028} + \x{2029} + \x{2065} + \x{2066} + \x{2067} + \x{2068} + \x{2069} + \x{e0002} + \x{e001f} + \x{e0080} + +/^[[:punct:]]+$/8W + \$+<=>^`|~ + !\"#%&'()*,-./:;?@[\\]_{} + \x{a1}\x{a7} + \x{37e} + ** Failers + abcde + +/^[[:^graph:]]+$/8W + \x{09}\x{0a}\x{1D}\x{20}\x{85}\x{a0}\x{61c}\x{1680}\x{180e} + \x{2028}\x{2029}\x{202f}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069} + \x{3000}\x{e0002}\x{e001f}\x{e0080} + ** Failers + Letter:ABC + Mark:\x{300}\x{1d172}\x{1d17b} + Number:9\x{660} + Punctuation:\x{66a},; + Symbol:\x{6de}<>\x{fffc} + Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f} + \x{200b}\x{200c}\x{200d}\x{200e}\x{200f} + \x{202a}\x{202b}\x{202c}\x{202d}\x{202e} + \x{2060}\x{2061}\x{2062}\x{2063}\x{2064} + \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f} + \x{feff} + \x{fff9}\x{fffa}\x{fffb} + \x{110bd} + \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a} + \x{e0001} + \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f} + +/^[[:^print:]]+$/8W + \x{09}\x{1D}\x{85}\x{61c}\x{2028}\x{2029}\x{2065}\x{2066}\x{2067} + \x{2068}\x{2069}\x{e0002}\x{e001f}\x{e0080} + ** Failers + Space: \x{a0} + \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005} + \x{2006}\x{2007}\x{2008}\x{2009}\x{200a} + \x{202f}\x{205f} + \x{3000} + Letter:ABC + Mark:\x{300}\x{1d172}\x{1d17b} + Number:9\x{660} + Punctuation:\x{66a},; + Symbol:\x{6de}<>\x{fffc} + Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f} + \x{180e} + \x{200b}\x{200c}\x{200d}\x{200e}\x{200f} + \x{202a}\x{202b}\x{202c}\x{202d}\x{202e} + \x{202f} + \x{2060}\x{2061}\x{2062}\x{2063}\x{2064} + \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f} + \x{feff} + \x{fff9}\x{fffa}\x{fffb} + \x{110bd} + \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a} + \x{e0001} + \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f} + +/^[[:^punct:]]+$/8W + abcde + ** Failers + \$+<=>^`|~ + !\"#%&'()*,-./:;?@[\\]_{} + \x{a1}\x{a7} + \x{37e} + +/[RST]+/8iW + Ss\x{17f} + +/[R-T]+/8iW + Ss\x{17f} + +/[q-u]+/8iW + Ss\x{17f} + /-- End of testinput6 --/ diff --git a/tools/pcre/testdata/testinput7 b/tools/pcre/testdata/testinput7 index b265f1f9..6bd05864 100644 --- a/tools/pcre/testdata/testinput7 +++ b/tools/pcre/testdata/testinput7 @@ -100,11 +100,30 @@ /\p{Cc}{2}+/8BZ +/^\p{Cf}/8 + \x{180e} + \x{061c} + \x{2066} + \x{2067} + \x{2068} + \x{2069} + /^\p{Cs}/8 \?\x{dfff} ** Failers \x{09f} +/^\p{Mn}/8 + \x{1a1b} + +/^\p{Pe}/8 + \x{2309} + \x{230b} + +/^\p{Ps}/8 + \x{2308} + \x{230a} + /^\p{Sc}+/8 $\x{a2}\x{a3}\x{a4}\x{a5}\x{a6} \x{9f2} @@ -116,15 +135,15 @@ \ \ \x{a0} \x{1680} - \x{180e} \x{2000} \x{2001} ** Failers \x{2028} \x{200d} -/-- These four are here rather than in test 6 because Perl has problems with - the negative versions of the properties. --/ +/-- These are here rather than in test 6 because Perl has problems with + the negative versions of the properties and behaves has changed how + it behaves for caseless matching. --/ /\p{^Lu}/8i 1234 @@ -149,6 +168,12 @@ a \x{1d00} +/\p{Lu}/8i + A + aZ + ** Failers + abc + /[\x{c0}\x{391}]/8i \x{c0} \x{e0} @@ -668,5 +693,146 @@ of case for anything other than the ASCII letters. --/ /is{2}t/8i iskt + +/-- This property is a PCRE special --/ + +/^\p{Xuc}/8 + $abc + @abc + `abc + \x{1234}abc + ** Failers + abc + +/^\p{Xuc}+/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\p{Xuc}+?/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\p{Xuc}+?\*/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\p{Xuc}++/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\p{Xuc}{3,5}/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\p{Xuc}{3,5}?/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^[\p{Xuc}]/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^[\p{Xuc}]+/8 + $@`\x{a0}\x{1234}\x{e000}** + ** Failers + \x{9f} + +/^\P{Xuc}/8 + abc + ** Failers + $abc + @abc + `abc + \x{1234}abc + +/^[\P{Xuc}]/8 + abc + ** Failers + $abc + @abc + `abc + \x{1234}abc + +/-- Some auto-possessification tests --/ + +/\pN+\z/BZ + +/\PN+\z/BZ + +/\pN+/BZ + +/\PN+/BZ + +/\p{Any}+\p{Any} \p{Any}+\P{Any} \p{Any}+\p{L&} \p{Any}+\p{L} \p{Any}+\p{Lu} \p{Any}+\p{Han} \p{Any}+\p{Xan} \p{Any}+\p{Xsp} \p{Any}+\p{Xps} \p{Xwd}+\p{Any} \p{Any}+\p{Xuc}/BWZx + +/\p{L&}+\p{Any} \p{L&}+\p{L&} \P{L&}+\p{L&} \p{L&}+\p{L} \p{L&}+\p{Lu} \p{L&}+\p{Han} \p{L&}+\p{Xan} \p{L&}+\P{Xan} \p{L&}+\p{Xsp} \p{L&}+\p{Xps} \p{Xwd}+\p{L&} \p{L&}+\p{Xuc}/BWZx + +/\p{N}+\p{Any} \p{N}+\p{L&} \p{N}+\p{L} \p{N}+\P{L} \p{N}+\P{N} \p{N}+\p{Lu} \p{N}+\p{Han} \p{N}+\p{Xan} \p{N}+\p{Xsp} \p{N}+\p{Xps} \p{Xwd}+\p{N} \p{N}+\p{Xuc}/BWZx + +/\p{Lu}+\p{Any} \p{Lu}+\p{L&} \p{Lu}+\p{L} \p{Lu}+\p{Lu} \P{Lu}+\p{Lu} \p{Lu}+\p{Nd} \p{Lu}+\P{Nd} \p{Lu}+\p{Han} \p{Lu}+\p{Xan} \p{Lu}+\p{Xsp} \p{Lu}+\p{Xps} \p{Xwd}+\p{Lu} \p{Lu}+\p{Xuc}/BWZx + +/\p{Han}+\p{Lu} \p{Han}+\p{L&} \p{Han}+\p{L} \p{Han}+\p{Lu} \p{Han}+\p{Arabic} \p{Arabic}+\p{Arabic} \p{Han}+\p{Xan} \p{Han}+\p{Xsp} \p{Han}+\p{Xps} \p{Xwd}+\p{Han} \p{Han}+\p{Xuc}/BWZx + +/\p{Xan}+\p{Any} \p{Xan}+\p{L&} \P{Xan}+\p{L&} \p{Xan}+\p{L} \p{Xan}+\p{Lu} \p{Xan}+\p{Han} \p{Xan}+\p{Xan} \p{Xan}+\P{Xan} \p{Xan}+\p{Xsp} \p{Xan}+\p{Xps} \p{Xwd}+\p{Xan} \p{Xan}+\p{Xuc}/BWZx + +/\p{Xsp}+\p{Any} \p{Xsp}+\p{L&} \p{Xsp}+\p{L} \p{Xsp}+\p{Lu} \p{Xsp}+\p{Han} \p{Xsp}+\p{Xan} \p{Xsp}+\p{Xsp} \P{Xsp}+\p{Xsp} \p{Xsp}+\p{Xps} \p{Xwd}+\p{Xsp} \p{Xsp}+\p{Xuc}/BWZx + +/\p{Xwd}+\p{Any} \p{Xwd}+\p{L&} \p{Xwd}+\p{L} \p{Xwd}+\p{Lu} \p{Xwd}+\p{Han} \p{Xwd}+\p{Xan} \p{Xwd}+\p{Xsp} \p{Xwd}+\p{Xps} \p{Xwd}+\p{Xwd} \p{Xwd}+\P{Xwd} \p{Xwd}+\p{Xuc}/BWZx + +/\p{Xuc}+\p{Any} \p{Xuc}+\p{L&} \p{Xuc}+\p{L} \p{Xuc}+\p{Lu} \p{Xuc}+\p{Han} \p{Xuc}+\p{Xan} \p{Xuc}+\p{Xsp} \p{Xuc}+\p{Xps} \p{Xwd}+\p{Xuc} \p{Xuc}+\p{Xuc} \p{Xuc}+\P{Xuc}/BWZx + +/\p{N}+\p{Ll} \p{N}+\p{Nd} \p{N}+\P{Nd}/BWZx + +/\p{Xan}+\p{L} \p{Xan}+\p{N} \p{Xan}+\p{C} \p{Xan}+\P{L} \P{Xan}+\p{N} \p{Xan}+\P{C}/BWZx + +/\p{L}+\p{Xan} \p{N}+\p{Xan} \p{C}+\p{Xan} \P{L}+\p{Xan} \p{N}+\p{Xan} \P{C}+\p{Xan} \p{L}+\P{Xan}/BWZx + +/\p{Xan}+\p{Lu} \p{Xan}+\p{Nd} \p{Xan}+\p{Cc} \p{Xan}+\P{Ll} \P{Xan}+\p{No} \p{Xan}+\P{Cf}/BWZx + +/\p{Lu}+\p{Xan} \p{Nd}+\p{Xan} \p{Cs}+\p{Xan} \P{Lt}+\p{Xan} \p{Nl}+\p{Xan} \P{Cc}+\p{Xan} \p{Lt}+\P{Xan}/BWZx + +/\w+\p{P} \w+\p{Po} \w+\s \p{Xan}+\s \s+\p{Xan} \s+\w/BWZx + +/\w+\P{P} \W+\p{Po} \w+\S \P{Xan}+\s \s+\P{Xan} \s+\W/BWZx + +/\w+\p{Po} \w+\p{Pc} \W+\p{Po} \W+\p{Pc} \w+\P{Po} \w+\P{Pc}/BWZx + +/\p{Nl}+\p{Xan} \P{Nl}+\p{Xan} \p{Nl}+\P{Xan} \P{Nl}+\P{Xan}/BWZx + +/\p{Xan}+\p{Nl} \P{Xan}+\p{Nl} \p{Xan}+\P{Nl} \P{Xan}+\P{Nl}/BWZx + +/\p{Xan}+\p{Nd} \P{Xan}+\p{Nd} \p{Xan}+\P{Nd} \P{Xan}+\P{Nd}/BWZx + +/-- End auto-possessification tests --/ + +/\w+/8CWBZ + abcd + +/[\p{N}]?+/BZO + +/[\p{L}ab]{2,3}+/BZO + +/\D+\X \d+\X \S+\X \s+\X \W+\X \w+\X \C+\X \R+\X \H+\X \h+\X \V+\X \v+\X a+\X \n+\X .+\X/BZx + +/.+\X/BZxs + +/\X+$/BZxm + +/\X+\D \X+\d \X+\S \X+\s \X+\W \X+\w \X+. \X+\C \X+\R \X+\H \X+\h \X+\V \X+\v \X+\X \X+\Z \X+\z \X+$/BZx + +/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/8WBZ + +/[RST]+/8iWBZ + +/[R-T]+/8iWBZ + +/[Q-U]+/8iWBZ /-- End of testinput7 --/ diff --git a/tools/pcre/testdata/testinput8 b/tools/pcre/testdata/testinput8 index e235445e..bb2747b1 100644 --- a/tools/pcre/testdata/testinput8 +++ b/tools/pcre/testdata/testinput8 @@ -1,5 +1,8 @@ -/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). - The -dfa flag must be used with pcretest when running it. --/ +/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(), + excluding UTF and Unicode property support. The -dfa flag must be used with + pcretest when running it. --/ + +< forbid 8W /abc/ abc @@ -16,7 +19,7 @@ ac ab -/a*/ +/a*/O a aaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -177,19 +180,19 @@ ayzq axyzq -/[^a]+/ +/[^a]+/O bac bcdefax *** Failers aaaaa -/[^a]*/ +/[^a]*/O bac bcdefax *** Failers aaaaa -/[^a]{3,5}/ +/[^a]{3,5}/O xyz awxyza abcdefa @@ -937,16 +940,16 @@ *** Failers the abc -/^[ab]{1,3}(ab*|b)/ +/^[ab]{1,3}(ab*|b)/O aabbbbb -/^[ab]{1,3}?(ab*|b)/ +/^[ab]{1,3}?(ab*|b)/O aabbbbb -/^[ab]{1,3}?(ab*?|b)/ +/^[ab]{1,3}?(ab*?|b)/O aabbbbb -/^[ab]{1,3}(ab*?|b)/ +/^[ab]{1,3}(ab*?|b)/O aabbbbb / (?: [\040\t] | \( @@ -1923,14 +1926,16 @@ abc\100\060 abc\100\60 -/abc\81/ - abc\081 - abc\0\x38\x31 - -/abc\91/ - abc\091 - abc\0\x39\x31 - +/^A\8B\9C$/ + A8B9C + *** Failers + A\08B\09C + +/^[A\8B\9C]+$/ + A8B9C + *** Failers + A8B9C\x00 + /(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ abcdefghijk\12S @@ -2049,13 +2054,13 @@ /foo(.*?)bar/ The food is under the bar in the barn. -/(.*)(\d*)/ +/(.*)(\d*)/O I have 2 numbers: 53147 /(.*)(\d+)/ I have 2 numbers: 53147 -/(.*?)(\d*)/ +/(.*?)(\d*)/O I have 2 numbers: 53147 /(.*?)(\d+)/ @@ -3825,13 +3830,6 @@ /a*/g abbab -/^[a-\d]/ - abcde - -things - 0digit - *** Failers - bcdef - /^[\d-a]/ abcde -things @@ -4699,7 +4697,7 @@ /(?(R)a*(?1)|((?R))b)/ aaaabcde -/(a+)/ +/(a+)/O \O6aaaa \O8aaaa @@ -4798,4 +4796,39 @@ xxxxxxxxabcd xx\xa0xxxxxabcd +/abcd/ + abcd\O0 + +/-- These tests show up auto-possessification --/ + +/[ab]*/ + aaaa + +/[ab]*?/ + aaaa + +/[ab]?/ + aaaa + +/[ab]??/ + aaaa + +/[ab]+/ + aaaa + +/[ab]+?/ + aaaa + +/[ab]{2,3}/ + aaaa + +/[ab]{2,3}?/ + aaaa + +/[ab]{2,}/ + aaaa + +/[ab]{2,}?/ + aaaa + /-- End of testinput8 --/ diff --git a/tools/pcre/testdata/testinput9 b/tools/pcre/testdata/testinput9 index 766c9c0f..4575ffe3 100644 --- a/tools/pcre/testdata/testinput9 +++ b/tools/pcre/testdata/testinput9 @@ -1,6 +1,8 @@ /-- This set of tests checks UTF-8 support with the DFA matching functionality - of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running - it. --/ + of pcre_dfa_exec(), excluding Unicode property support. The -dfa flag must + be used with pcretest when running it. --/ + +< forbid W /\x{100}ab/8 \x{100}ab @@ -239,16 +241,16 @@ /\x{100}{3,5}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX -/\x{100}{3,}/8 +/\x{100}{3,}/8O abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX /(?<=a\x{100}{2}b)X/8 Xyyya\x{100}\x{100}bXzzz -/\D*/8 +/\D*/8O aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/\D*/8 +/\D*/8O \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} /\D/8 @@ -584,16 +586,16 @@ a\n\n\n\rb a\r -/\h+\V?\v{3,4}/8 +/\h+\V?\v{3,4}/8O \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a -/\V?\v{3,4}/8 +/\V?\v{3,4}/8O \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a -/\h+\V?\v{3,4}/8 +/\h+\V?\v{3,4}/8O >\x09\x20\x{a0}X\x0a\x0a\x0a< -/\V?\v{3,4}/8 +/\V?\v{3,4}/8O >\x09\x20\x{a0}X\x0a\x0a\x0a< /\H\h\V\v/8 @@ -602,7 +604,7 @@ ** Failers \x{a0} X\x0a -/\H*\h+\V?\v{3,4}/8 +/\H*\h+\V?\v{3,4}/8O \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a \x09\x20\x{a0}\x0a\x0b\x0c @@ -615,7 +617,7 @@ ** Failers \x{2009} X\x0a -/\H*\h+\V?\v{3,4}/8 +/\H*\h+\V?\v{3,4}/8O \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a \x09\x20\x{202f}\x0a\x0b\x0c diff --git a/tools/pcre/testdata/testoutput1 b/tools/pcre/testdata/testoutput1 index 8310e946..4dafc049 100644 --- a/tools/pcre/testdata/testoutput1 +++ b/tools/pcre/testdata/testoutput1 @@ -1,6 +1,8 @@ /-- This set of tests is for features that are compatible with all versions of - Perl >= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and - 16-bit PCRE libraries. --/ + Perl >= 5.10, in non-UTF-8 mode. It should run clean for the 8-bit, 16-bit, + and 32-bit PCRE libraries. --/ + +< forbid 89?=ABCDEFfGILMNPTUWXZ< /the quick brown fox/ the quick brown fox @@ -2149,18 +2151,35 @@ No match abc\100\60 0: abc@0 1: abc + +/^A\8B\9C$/ + A8B9C + 0: A8B9C + *** Failers +No match + A\08B\09C +No match + +/^(A)(B)(C)(D)(E)(F)(G)(H)(I)\8\9$/ + ABCDEFGHIHI + 0: ABCDEFGHIHI + 1: A + 2: B + 3: C + 4: D + 5: E + 6: F + 7: G + 8: H + 9: I -/abc\81/ - abc\081 - 0: abc\x0081 - abc\0\x38\x31 - 0: abc\x0081 - -/abc\91/ - abc\091 - 0: abc\x0091 - abc\0\x39\x31 - 0: abc\x0091 +/^[A\8B\9C]+$/ + A8B9C + 0: A8B9C + *** Failers +No match + A8B9C\x00 +No match /(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\12\123/ abcdefghijkllS @@ -5972,18 +5991,6 @@ No match 0: 0: -/^[a-\d]/ - abcde - 0: a - -things - 0: - - 0digit - 0: 0 - *** Failers -No match - bcdef -No match - /^[\d-a]/ abcde 0: a @@ -6006,15 +6013,15 @@ No match /[\s]+/ > \x09\x0a\x0c\x0d\x0b< - 0: \x09\x0a\x0c\x0d + 0: \x09\x0a\x0c\x0d\x0b /\s+/ > \x09\x0a\x0c\x0d\x0b< - 0: \x09\x0a\x0c\x0d + 0: \x09\x0a\x0c\x0d\x0b /a b/x ab -No match + 0: ab /(?!\A)x/m a\nxb\n @@ -6160,11 +6167,9 @@ No match 1: bc 2: bc -/-- This tests for an IPv6 address in the form where it can have up to --/ -/-- eight components, one and only one of which is empty. This must be --/ -No match -/-- an internal component. --/ -No match +/-- This tests for an IPv6 address in the form where it can have up to + eight components, one and only one of which is empty. This must be + an internal component. --/ /^(?!:) # colon disallowed at start (?: # start of item @@ -6906,10 +6911,6 @@ No match bc 0: b -/^(?=(a)){0}b(?1)/ - backgammon - 0: ba - /^(?=(?1))?[az]([abc])d/ abd 0: abd @@ -7770,20 +7771,12 @@ No match 1: (ab(cd)ef) 2: ef -/^(?!a(*SKIP)b)/ - ac - 0: - /^(?=a(*SKIP)b|ac)/ ** Failers No match ac No match -/^(?=a(*THEN)b|ac)/ - ac - 0: - /^(?=a(*PRUNE)b)/ ab 0: @@ -7796,10 +7789,6 @@ No match ac 0: -/^(?(?!a(*SKIP)b))/ - ac - 0: - /(?>a\Kb)/ ab 0: b @@ -8169,46 +8158,20 @@ No match 1: AB 2: B -/\A.*?(?:a|b(*THEN)c)/ - ba - 0: ba - -/\A.*?(?:a|bc)/ - ba - 0: ba - -/\A.*?(a|b(*THEN)c)/ - ba - 0: ba - 1: a - /\A.*?(a|bc)/ ba 0: ba 1: a -/\A.*?(?:a|b(*THEN)c)++/ - ba - 0: ba - /\A.*?(?:a|bc)++/ ba 0: ba -/\A.*?(a|b(*THEN)c)++/ - ba - 0: ba - 1: a - /\A.*?(a|bc)++/ ba 0: ba 1: a -/\A.*?(?:a|b(*THEN)c|d)/ - ba - 0: ba - /\A.*?(?:a|bc|d)/ ba 0: ba @@ -8719,10 +8682,6 @@ No match aac 0: aac -/(?!a(*COMMIT)b)ac|cd/ - ac - 0: ac - /((?:a?)*)*c/ aac 0: aac @@ -8795,4 +8754,563 @@ No match abcdfooxyz 0: foo +/(?:(a(*PRUNE)b)){0}(?:(?1)|ac)/ + ac + 0: ac + +/(?:(a(*SKIP)b)){0}(?:(?1)|ac)/ + ac + 0: ac + +/(?<=(*SKIP)ac)a/ + aa +No match + +/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK + AAAC + 0: AC + +/a(*SKIP:m)x|ac(*:n)(*SKIP:n)d|ac/K + acacd + 0: acd +MK: n + +/A(*SKIP:m)x|A(*SKIP:n)x|AB/K + AB + 0: AB + +/((*SKIP:r)d){0}a(*SKIP:m)x|ac(*:n)|ac/K + acacd + 0: ac +MK: n + +/-- Tests that try to figure out how Perl works. My hypothesis is that the + first verb that is backtracked onto is the one that acts. This seems to be + the case almost all the time, but there is one exception that is perhaps a + bug. --/ + +/-- This matches "aaaac"; each PRUNE advances one character until the subject + no longer starts with 5 'a's. --/ + +/aaaaa(*PRUNE)b|a+c/ + aaaaaac + 0: aaaac + +/-- Putting SKIP in front of PRUNE makes no difference, as it is never +backtracked onto, whether or not it has a label. --/ + +/aaaaa(*SKIP)(*PRUNE)b|a+c/ + aaaaaac + 0: aaaac + +/aaaaa(*SKIP:N)(*PRUNE)b|a+c/ + aaaaaac + 0: aaaac + +/aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c/ + aaaaaac + 0: aaaac + +/-- Putting THEN in front makes no difference. */ + +/aaaaa(*THEN)(*PRUNE)b|a+c/ + aaaaaac + 0: aaaac + +/-- However, putting COMMIT in front of the prune changes it to "no match". I + think this is inconsistent and possibly a bug. For the moment, running this + test is moved out of the Perl-compatible file. --/ + +/aaaaa(*COMMIT)(*PRUNE)b|a+c/ + + +/---- OK, lets play the same game again using SKIP instead of PRUNE. ----/ + +/-- This matches "ac" because SKIP forces the next match to start on the + sixth "a". --/ + +/aaaaa(*SKIP)b|a+c/ + aaaaaac + 0: ac + +/-- Putting PRUNE in front makes no difference. --/ + +/aaaaa(*PRUNE)(*SKIP)b|a+c/ + aaaaaac + 0: ac + +/-- Putting THEN in front makes no difference. --/ + +/aaaaa(*THEN)(*SKIP)b|a+c/ + aaaaaac + 0: ac + +/-- In this case, neither does COMMIT. This still matches "ac". --/ + +/aaaaa(*COMMIT)(*SKIP)b|a+c/ + aaaaaac + 0: ac + +/-- This gives "no match", as expected. --/ + +/aaaaa(*COMMIT)b|a+c/ + aaaaaac +No match + + +/------ Tests using THEN ------/ + +/-- This matches "aaaaaac", as expected. --/ + +/aaaaa(*THEN)b|a+c/ + aaaaaac + 0: aaaaaac + +/-- Putting SKIP in front makes no difference. --/ + +/aaaaa(*SKIP)(*THEN)b|a+c/ + aaaaaac + 0: aaaaaac + +/-- Putting PRUNE in front makes no difference. --/ + +/aaaaa(*PRUNE)(*THEN)b|a+c/ + aaaaaac + 0: aaaaaac + +/-- Putting COMMIT in front makes no difference. --/ + +/aaaaa(*COMMIT)(*THEN)b|a+c/ + aaaaaac + 0: aaaaaac + +/-- End of "priority" tests --/ + +/aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+/ + aaaaaa + 0: a + +/aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+/ + aaaaaa + 0: a + +/aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+/ + aaaaaa + 0: aaaa + +/aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+/ + aaaaaa + 0: a + +/a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c/ + aaaac + 0: aac + +/a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c/ + aaaac + 0: ac + +/aaa(*PRUNE:A)a(*SKIP:A)b|a+c/ + aaaac + 0: aac + +/aaa(*MARK:A)a(*SKIP:A)b|a+c/ + aaaac + 0: ac + +/a(*:m)a(*COMMIT)(*SKIP:m)b|a+c/K + aaaaaac + 0: ac + +/.?(a|b(*THEN)c)/ + ba + 0: ba + 1: a + +/(a(*COMMIT)b)c|abd/ + abc + 0: abc + 1: ab + abd +No match + +/(?=a(*COMMIT)b)abc|abd/ + abc + 0: abc + abd + 0: abd + +/(?>a(*COMMIT)b)c|abd/ + abc + 0: abc + abd + 0: abd + +/a(?=b(*COMMIT)c)[^d]|abd/ + abd +No match + abc + 0: ab + +/a(?=bc).|abd/ + abd + 0: abd + abc + 0: ab + +/a(?>b(*COMMIT)c)d|abd/ + abceabd +No match + +/a(?>bc)d|abd/ + abceabd + 0: abd + +/(?>a(*COMMIT)b)c|abd/ + abd + 0: abd + +/(?>a(*COMMIT)c)d|abd/ + abd +No match + +/((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/ + ac + 0: ac + 1: + 2: c + +/-- These tests were formerly in test 2, but changes in PCRE and Perl have + made them compatible. --/ + +/^(a)?(?(1)a|b)+$/ + *** Failers +No match + a +No match + +/(?=a\Kb)ab/ + ab + 0: b + +/(?!a\Kb)ac/ + ac + 0: ac + +/^abc(?<=b\Kc)d/ + abcd + 0: cd + +/^abc(?b))/K + abc + 0: b +MK: m(m + +/(*PRUNE:m(m)(?&y)(?(DEFINE)(?b))/K + abc + 0: b +MK: m(m + +/(*SKIP:m(m)(?&y)(?(DEFINE)(?b))/K + abc + 0: b + +/(*THEN:m(m)(?&y)(?(DEFINE)(?b))/K + abc + 0: b +MK: m(m + +/^\d*\w{4}/ + 1234 + 0: 1234 + 123 +No match + +/^[^b]*\w{4}/ + aaaa + 0: aaaa + aaa +No match + +/^[^b]*\w{4}/i + aaaa + 0: aaaa + aaa +No match + +/^a*\w{4}/ + aaaa + 0: aaaa + aaa +No match + +/^a*\w{4}/i + aaaa + 0: aaaa + aaa +No match + +/(?(?=ab)ab)/+ + ca + 0: + 0+ ca + cd + 0: + 0+ cd + +/(?:(?foo)|(?bar))\k/J + foofoo + 0: foofoo + 1: foo + barbar + 0: barbar + 1: + 2: bar + +/(?A)(?:(?foo)|(?bar))\k/J + AfooA + 0: AfooA + 1: A + 2: foo + AbarA + 0: AbarA + 1: A + 2: + 3: bar + ** Failers +No match + Afoofoo +No match + Abarbar +No match + +/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ + 1 IN SOA non-sp1 non-sp2( + 0: 1 IN SOA non-sp1 non-sp2( + 1: 1 + 2: non-sp1 + 3: non-sp2 + +/^ (?:(?A)|(?'B'B)(?A)) (?('A')x) (?()y)$/xJ + Ax + 0: Ax + 1: A + BAxy + 0: BAxy + 1: + 2: B + 3: A + +/^A\xZ/ + A\0Z + 0: A\x00Z + +/^A\o{123}B/ + A\123B + 0: ASB + +/ ^ a + + b $ /x + aaaab + 0: aaaab + +/ ^ a + #comment + + b $ /x + aaaab + 0: aaaab + +/ ^ a + #comment + #comment + + b $ /x + aaaab + 0: aaaab + +/ ^ (?> a + ) b $ /x + aaaab + 0: aaaab + +/ ^ ( a + ) + + \w $ /x + aaaab + 0: aaaab + 1: aaaa + +/(?:a\Kb)*+/+ + ababc + 0: b + 0+ c + +/(?>a\Kb)*/+ + ababc + 0: b + 0+ c + +/(?:a\Kb)*/+ + ababc + 0: b + 0+ c + +/(a\Kb)*+/+ + ababc + 0: b + 0+ c + 1: ab + +/(a\Kb)*/+ + ababc + 0: b + 0+ c + 1: ab + /-- End of testinput1 --/ diff --git a/tools/pcre/testdata/testoutput10 b/tools/pcre/testdata/testoutput10 index 049d4463..b89169cd 100644 --- a/tools/pcre/testdata/testoutput10 +++ b/tools/pcre/testdata/testoutput10 @@ -39,9 +39,6 @@ No match /^\pL+/8 abcd 0: abcd - 1: abc - 2: ab - 3: a a 0: a *** Failers @@ -50,45 +47,24 @@ No match /^\PL+/8 1234 0: 1234 - 1: 123 - 2: 12 - 3: 1 = 0: = *** Failers 0: *** - 1: *** - 2: ** - 3: * abcd No match /^\X+/8 abcdA\x{300}\x{301}\x{302} 0: abcdA\x{300}\x{301}\x{302} - 1: abcd - 2: abc - 3: ab - 4: a A\x{300}\x{301}\x{302} 0: A\x{300}\x{301}\x{302} A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} - 1: A\x{300}\x{301}\x{302} a 0: a *** Failers 0: *** Failers - 1: *** Failer - 2: *** Faile - 3: *** Fail - 4: *** Fai - 5: *** Fa - 6: *** F - 7: *** - 8: *** - 9: ** -10: * \x{300}\x{301}\x{302} 0: \x{300}\x{301}\x{302} @@ -255,6 +231,18 @@ No match /^\p{Cf}/8 \x{601} 0: \x{601} + \x{180e} + 0: \x{180e} + \x{061c} + 0: \x{61c} + \x{2066} + 0: \x{2066} + \x{2067} + 0: \x{2067} + \x{2068} + 0: \x{2068} + \x{2069} + 0: \x{2069} ** Failers No match \x{09f} @@ -353,6 +341,8 @@ No match /^\p{Mn}/8 \x{300} 0: \x{300} + \x{1a1b} + 0: \x{1a1b} ** Failers No match X @@ -360,7 +350,7 @@ No match \x{903} No match -/^\p{Nd}+/8 +/^\p{Nd}+/8O 0123456789\x{660}\x{661}\x{662}\x{663}\x{664}\x{665}\x{666}\x{667}\x{668}\x{669}\x{66a} 0: 0123456789\x{660}\x{661}\x{662}\x{663}\x{664}\x{665}\x{666}\x{667}\x{668}\x{669} 1: 0123456789\x{660}\x{661}\x{662}\x{663}\x{664}\x{665}\x{666}\x{667}\x{668} @@ -466,6 +456,10 @@ No match 0: } \x{f3b} 0: \x{f3b} + \x{2309} + 0: \x{2309} + \x{230b} + 0: \x{230b} ** Failers No match X @@ -480,7 +474,7 @@ No match No match \x{f3c} No match - + /^\p{Pf}/8 \x{bb} 0: \x{bb} @@ -526,6 +520,10 @@ No match 0: { \x{f3c} 0: \x{f3c} + \x{2308} + 0: \x{2308} + \x{230a} + 0: \x{230a} ** Failers No match X @@ -542,10 +540,6 @@ No match /^\p{Sc}+/8 $\x{a2}\x{a3}\x{a4}\x{a5}\x{a6} 0: $\x{a2}\x{a3}\x{a4}\x{a5} - 1: $\x{a2}\x{a3}\x{a4} - 2: $\x{a2}\x{a3} - 3: $\x{a2} - 4: $ \x{9f2} 0: \x{9f2} ** Failers @@ -568,11 +562,6 @@ No match /^\p{Sm}+/8 +<|~\x{ac}\x{2044} 0: +<|~\x{ac}\x{2044} - 1: +<|~\x{ac} - 2: +<|~ - 3: +<| - 4: +< - 5: + ** Failers No match X @@ -619,8 +608,6 @@ No match 0: \x{a0} \x{1680} 0: \x{1680} - \x{180e} - 0: \x{180e} \x{2000} 0: \x{2000} \x{2001} @@ -767,23 +754,10 @@ No match /[\p{Nd}+-]+/8 1234 0: 1234 - 1: 123 - 2: 12 - 3: 1 12-34 0: 12-34 - 1: 12-3 - 2: 12- - 3: 12 - 4: 1 12+\x{661}-34 0: 12+\x{661}-34 - 1: 12+\x{661}-3 - 2: 12+\x{661}- - 3: 12+\x{661} - 4: 12+ - 5: 12 - 6: 1 ** Failers No match abcd @@ -792,28 +766,16 @@ No match /[\P{Nd}]+/8 abcd 0: abcd - 1: abc - 2: ab - 3: a ** Failers 0: ** Failers - 1: ** Failer - 2: ** Faile - 3: ** Fail - 4: ** Fai - 5: ** Fa - 6: ** F - 7: ** - 8: ** - 9: * 1234 No match -/\D+/8 +/\D+/8O 11111111111111111111111111111111111111111111111111111111111111111111111 No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -837,11 +799,11 @@ Matched, but too many subsidiary matches 20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/\P{Nd}+/8 +/\P{Nd}+/8O 11111111111111111111111111111111111111111111111111111111111111111111111 No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -865,11 +827,11 @@ Matched, but too many subsidiary matches 20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/[\D]+/8 +/[\D]+/8O 11111111111111111111111111111111111111111111111111111111111111111111111 No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -893,11 +855,11 @@ Matched, but too many subsidiary matches 20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/[\P{Nd}]+/8 +/[\P{Nd}]+/8O 11111111111111111111111111111111111111111111111111111111111111111111111 No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -921,11 +883,11 @@ Matched, but too many subsidiary matches 20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/[\D\P{Nd}]+/8 +/[\D\P{Nd}]+/8O 11111111111111111111111111111111111111111111111111111111111111111111111 No match aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1046,10 +1008,6 @@ No match /\x{391}+/8i \x{391}\x{3b1}\x{3b1}\x{3b1}\x{391} 0: \x{391}\x{3b1}\x{3b1}\x{3b1}\x{391} - 1: \x{391}\x{3b1}\x{3b1}\x{3b1} - 2: \x{391}\x{3b1}\x{3b1} - 3: \x{391}\x{3b1} - 4: \x{391} /\x{391}{3,5}(.)/8i \x{391}\x{3b1}\x{3b1}\x{3b1}\x{391}X @@ -1236,8 +1194,6 @@ No match /^\p{Han}+/8 \x{2e81}\x{3007}\x{2f804}\x{31a0} 0: \x{2e81}\x{3007}\x{2f804} - 1: \x{2e81}\x{3007} - 2: \x{2e81} ** Failers No match \x{2e7f} @@ -1248,15 +1204,6 @@ No match 0: \x{3105} ** Failers 0: ** Failers - 1: ** Failer - 2: ** Faile - 3: ** Fail - 4: ** Fai - 5: ** Fa - 6: ** F - 7: ** - 8: ** - 9: * \x{30ff} No match @@ -1469,12 +1416,8 @@ No match /^\p{Any}{3,5}/8 abcdefgh 0: abcde - 1: abcd - 2: abc \x{1234}\n\r\x{3456}xyz 0: \x{1234}\x{0a}\x{0d}\x{3456}x - 1: \x{1234}\x{0a}\x{0d}\x{3456} - 2: \x{1234}\x{0a}\x{0d} /^\P{Any}{3,5}?/8 ** Failers @@ -1639,14 +1582,10 @@ No match /\x{c0}+\x{116}+/8i \x{c0}\x{e0}\x{116}\x{117} 0: \x{c0}\x{e0}\x{116}\x{117} - 1: \x{c0}\x{e0}\x{116} /[\x{c0}\x{116}]+/8i \x{c0}\x{e0}\x{116}\x{117} 0: \x{c0}\x{e0}\x{116}\x{117} - 1: \x{c0}\x{e0}\x{116} - 2: \x{c0}\x{e0} - 3: \x{c0} /Check property support in non-UTF-8 mode/ @@ -1693,16 +1632,6 @@ No match /^\p{Xan}+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 1: ABCD1234\x{6ca}\x{a6c} - 2: ABCD1234\x{6ca} - 3: ABCD1234 - 4: ABCD123 - 5: ABCD12 - 6: ABCD1 - 7: ABCD - 8: ABC - 9: AB -10: A ** Failers No match _ABC @@ -1711,28 +1640,10 @@ No match /^\p{Xan}*/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 1: ABCD1234\x{6ca}\x{a6c} - 2: ABCD1234\x{6ca} - 3: ABCD1234 - 4: ABCD123 - 5: ABCD12 - 6: ABCD1 - 7: ABCD - 8: ABC - 9: AB -10: A -11: /^\p{Xan}{2,9}/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca} - 1: ABCD1234 - 2: ABCD123 - 3: ABCD12 - 4: ABCD1 - 5: ABCD - 6: ABC - 7: AB /^[\p{Xan}]/8 ABCD1234_ @@ -1753,16 +1664,6 @@ No match /^[\p{Xan}]+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 1: ABCD1234\x{6ca}\x{a6c} - 2: ABCD1234\x{6ca} - 3: ABCD1234 - 4: ABCD123 - 5: ABCD12 - 6: ABCD1 - 7: ABCD - 8: ABC - 9: AB -10: A ** Failers No match _ABC @@ -1776,53 +1677,57 @@ No match \x{0b} No match -/^>\p{Xsp}+/8 +/^>\p{Xsp}+/8O > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 3: > \x{09}\x{0a}\x{0c}\x{0d} - 4: > \x{09}\x{0a}\x{0c} - 5: > \x{09}\x{0a} - 6: > \x{09} - 7: > + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 4: > \x{09}\x{0a}\x{0c}\x{0d} + 5: > \x{09}\x{0a}\x{0c} + 6: > \x{09}\x{0a} + 7: > \x{09} + 8: > -/^>\p{Xsp}*/8 +/^>\p{Xsp}*/8O > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 3: > \x{09}\x{0a}\x{0c}\x{0d} - 4: > \x{09}\x{0a}\x{0c} - 5: > \x{09}\x{0a} - 6: > \x{09} - 7: > - 8: > + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 4: > \x{09}\x{0a}\x{0c}\x{0d} + 5: > \x{09}\x{0a}\x{0c} + 6: > \x{09}\x{0a} + 7: > \x{09} + 8: > + 9: > -/^>\p{Xsp}{2,9}/8 +/^>\p{Xsp}{2,9}/8O > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 3: > \x{09}\x{0a}\x{0c}\x{0d} - 4: > \x{09}\x{0a}\x{0c} - 5: > \x{09}\x{0a} - 6: > \x{09} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 4: > \x{09}\x{0a}\x{0c}\x{0d} + 5: > \x{09}\x{0a}\x{0c} + 6: > \x{09}\x{0a} + 7: > \x{09} -/^>[\p{Xsp}]/8 +/^>[\p{Xsp}]/8O >\x{2028}\x{0b} 0: >\x{2028} -/^>[\p{Xsp}]+/8 +/^>[\p{Xsp}]+/8O > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 3: > \x{09}\x{0a}\x{0c}\x{0d} - 4: > \x{09}\x{0a}\x{0c} - 5: > \x{09}\x{0a} - 6: > \x{09} - 7: > + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 4: > \x{09}\x{0a}\x{0c}\x{0d} + 5: > \x{09}\x{0a}\x{0c} + 6: > \x{09}\x{0a} + 7: > \x{09} + 8: > /^>\p{Xps}/8 >\x{1680}\x{2028}\x{0b} @@ -1837,14 +1742,6 @@ No match /^>\p{Xps}+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 4: > \x{09}\x{0a}\x{0c}\x{0d} - 5: > \x{09}\x{0a}\x{0c} - 6: > \x{09}\x{0a} - 7: > \x{09} - 8: > /^>\p{Xps}+?/8 >\x{1680}\x{2028}\x{0b} @@ -1855,26 +1752,10 @@ No match /^>\p{Xps}*/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 4: > \x{09}\x{0a}\x{0c}\x{0d} - 5: > \x{09}\x{0a}\x{0c} - 6: > \x{09}\x{0a} - 7: > \x{09} - 8: > - 9: > /^>\p{Xps}{2,9}/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 4: > \x{09}\x{0a}\x{0c}\x{0d} - 5: > \x{09}\x{0a}\x{0c} - 6: > \x{09}\x{0a} - 7: > \x{09} /^>\p{Xps}{2,9}?/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} @@ -1894,14 +1775,6 @@ No match /^>[\p{Xps}]+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 4: > \x{09}\x{0a}\x{0c}\x{0d} - 5: > \x{09}\x{0a}\x{0c} - 6: > \x{09}\x{0a} - 7: > \x{09} - 8: > /^\p{Xwd}/8 ABCD @@ -1924,42 +1797,14 @@ No match /^\p{Xwd}+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 2: ABCD1234\x{6ca}\x{a6c} - 3: ABCD1234\x{6ca} - 4: ABCD1234 - 5: ABCD123 - 6: ABCD12 - 7: ABCD1 - 8: ABCD - 9: ABC -10: AB -11: A /^\p{Xwd}*/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 2: ABCD1234\x{6ca}\x{a6c} - 3: ABCD1234\x{6ca} - 4: ABCD1234 - 5: ABCD123 - 6: ABCD12 - 7: ABCD1 - 8: ABCD - 9: ABC -10: AB -11: A -12: /^\p{Xwd}{2,9}/8 A_12\x{6ca}\x{a6c}\x{10a7} 0: A_12\x{6ca}\x{a6c}\x{10a7} - 1: A_12\x{6ca}\x{a6c} - 2: A_12\x{6ca} - 3: A_12 - 4: A_1 - 5: A_ /^[\p{Xwd}]/8 ABCD1234_ @@ -1982,17 +1827,6 @@ No match /^[\p{Xwd}]+/8 ABCD1234\x{6ca}\x{a6c}\x{10a7}_ 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 2: ABCD1234\x{6ca}\x{a6c} - 3: ABCD1234\x{6ca} - 4: ABCD1234 - 5: ABCD123 - 6: ABCD12 - 7: ABCD1 - 8: ABCD - 9: ABC -10: AB -11: A /-- Unicode properties for \b abd \B --/ @@ -2043,7 +1877,6 @@ No match /[^\x{100}]+/8i \x{100}\x{101}XX 0: XX - 1: X /^\X/8 A\P @@ -2090,7 +1923,6 @@ Partial match: A\x{300}\x{301}A\x{300}\x{301} /^\X+/8 AA\P 0: AA - 1: A AA\P\P Partial match: AA @@ -2271,435 +2103,299 @@ Partial match: AA /\x{1e9e}+/8i \x{1e9e}\x{00df} 0: \x{1e9e}\x{df} - 1: \x{1e9e} /[z\x{1e9e}]+/8i \x{1e9e}\x{00df} 0: \x{1e9e}\x{df} - 1: \x{1e9e} /\x{00df}+/8i \x{1e9e}\x{00df} 0: \x{1e9e}\x{df} - 1: \x{1e9e} /[z\x{00df}]+/8i \x{1e9e}\x{00df} 0: \x{1e9e}\x{df} - 1: \x{1e9e} /\x{1f88}+/8i \x{1f88}\x{1f80} 0: \x{1f88}\x{1f80} - 1: \x{1f88} /[z\x{1f88}]+/8i \x{1f88}\x{1f80} 0: \x{1f88}\x{1f80} - 1: \x{1f88} /-- Perl matches these --/ /\x{00b5}+/8i \x{00b5}\x{039c}\x{03bc} 0: \x{b5}\x{39c}\x{3bc} - 1: \x{b5}\x{39c} - 2: \x{b5} /\x{039c}+/8i \x{00b5}\x{039c}\x{03bc} 0: \x{b5}\x{39c}\x{3bc} - 1: \x{b5}\x{39c} - 2: \x{b5} /\x{03bc}+/8i \x{00b5}\x{039c}\x{03bc} 0: \x{b5}\x{39c}\x{3bc} - 1: \x{b5}\x{39c} - 2: \x{b5} /\x{00c5}+/8i \x{00c5}\x{00e5}\x{212b} 0: \x{c5}\x{e5}\x{212b} - 1: \x{c5}\x{e5} - 2: \x{c5} /\x{00e5}+/8i \x{00c5}\x{00e5}\x{212b} 0: \x{c5}\x{e5}\x{212b} - 1: \x{c5}\x{e5} - 2: \x{c5} /\x{212b}+/8i \x{00c5}\x{00e5}\x{212b} 0: \x{c5}\x{e5}\x{212b} - 1: \x{c5}\x{e5} - 2: \x{c5} /\x{01c4}+/8i \x{01c4}\x{01c5}\x{01c6} 0: \x{1c4}\x{1c5}\x{1c6} - 1: \x{1c4}\x{1c5} - 2: \x{1c4} /\x{01c5}+/8i \x{01c4}\x{01c5}\x{01c6} 0: \x{1c4}\x{1c5}\x{1c6} - 1: \x{1c4}\x{1c5} - 2: \x{1c4} /\x{01c6}+/8i \x{01c4}\x{01c5}\x{01c6} 0: \x{1c4}\x{1c5}\x{1c6} - 1: \x{1c4}\x{1c5} - 2: \x{1c4} /\x{01c7}+/8i \x{01c7}\x{01c8}\x{01c9} 0: \x{1c7}\x{1c8}\x{1c9} - 1: \x{1c7}\x{1c8} - 2: \x{1c7} /\x{01c8}+/8i \x{01c7}\x{01c8}\x{01c9} 0: \x{1c7}\x{1c8}\x{1c9} - 1: \x{1c7}\x{1c8} - 2: \x{1c7} /\x{01c9}+/8i \x{01c7}\x{01c8}\x{01c9} 0: \x{1c7}\x{1c8}\x{1c9} - 1: \x{1c7}\x{1c8} - 2: \x{1c7} /\x{01ca}+/8i \x{01ca}\x{01cb}\x{01cc} 0: \x{1ca}\x{1cb}\x{1cc} - 1: \x{1ca}\x{1cb} - 2: \x{1ca} /\x{01cb}+/8i \x{01ca}\x{01cb}\x{01cc} 0: \x{1ca}\x{1cb}\x{1cc} - 1: \x{1ca}\x{1cb} - 2: \x{1ca} /\x{01cc}+/8i \x{01ca}\x{01cb}\x{01cc} 0: \x{1ca}\x{1cb}\x{1cc} - 1: \x{1ca}\x{1cb} - 2: \x{1ca} /\x{01f1}+/8i \x{01f1}\x{01f2}\x{01f3} 0: \x{1f1}\x{1f2}\x{1f3} - 1: \x{1f1}\x{1f2} - 2: \x{1f1} /\x{01f2}+/8i \x{01f1}\x{01f2}\x{01f3} 0: \x{1f1}\x{1f2}\x{1f3} - 1: \x{1f1}\x{1f2} - 2: \x{1f1} /\x{01f3}+/8i \x{01f1}\x{01f2}\x{01f3} 0: \x{1f1}\x{1f2}\x{1f3} - 1: \x{1f1}\x{1f2} - 2: \x{1f1} /\x{0345}+/8i \x{0345}\x{0399}\x{03b9}\x{1fbe} 0: \x{345}\x{399}\x{3b9}\x{1fbe} - 1: \x{345}\x{399}\x{3b9} - 2: \x{345}\x{399} - 3: \x{345} /\x{0399}+/8i \x{0345}\x{0399}\x{03b9}\x{1fbe} 0: \x{345}\x{399}\x{3b9}\x{1fbe} - 1: \x{345}\x{399}\x{3b9} - 2: \x{345}\x{399} - 3: \x{345} /\x{03b9}+/8i \x{0345}\x{0399}\x{03b9}\x{1fbe} 0: \x{345}\x{399}\x{3b9}\x{1fbe} - 1: \x{345}\x{399}\x{3b9} - 2: \x{345}\x{399} - 3: \x{345} /\x{1fbe}+/8i \x{0345}\x{0399}\x{03b9}\x{1fbe} 0: \x{345}\x{399}\x{3b9}\x{1fbe} - 1: \x{345}\x{399}\x{3b9} - 2: \x{345}\x{399} - 3: \x{345} /\x{0392}+/8i \x{0392}\x{03b2}\x{03d0} 0: \x{392}\x{3b2}\x{3d0} - 1: \x{392}\x{3b2} - 2: \x{392} /\x{03b2}+/8i \x{0392}\x{03b2}\x{03d0} 0: \x{392}\x{3b2}\x{3d0} - 1: \x{392}\x{3b2} - 2: \x{392} /\x{03d0}+/8i \x{0392}\x{03b2}\x{03d0} 0: \x{392}\x{3b2}\x{3d0} - 1: \x{392}\x{3b2} - 2: \x{392} /\x{0395}+/8i \x{0395}\x{03b5}\x{03f5} 0: \x{395}\x{3b5}\x{3f5} - 1: \x{395}\x{3b5} - 2: \x{395} /\x{03b5}+/8i \x{0395}\x{03b5}\x{03f5} 0: \x{395}\x{3b5}\x{3f5} - 1: \x{395}\x{3b5} - 2: \x{395} /\x{03f5}+/8i \x{0395}\x{03b5}\x{03f5} 0: \x{395}\x{3b5}\x{3f5} - 1: \x{395}\x{3b5} - 2: \x{395} /\x{0398}+/8i \x{0398}\x{03b8}\x{03d1}\x{03f4} 0: \x{398}\x{3b8}\x{3d1}\x{3f4} - 1: \x{398}\x{3b8}\x{3d1} - 2: \x{398}\x{3b8} - 3: \x{398} /\x{03b8}+/8i \x{0398}\x{03b8}\x{03d1}\x{03f4} 0: \x{398}\x{3b8}\x{3d1}\x{3f4} - 1: \x{398}\x{3b8}\x{3d1} - 2: \x{398}\x{3b8} - 3: \x{398} /\x{03d1}+/8i \x{0398}\x{03b8}\x{03d1}\x{03f4} 0: \x{398}\x{3b8}\x{3d1}\x{3f4} - 1: \x{398}\x{3b8}\x{3d1} - 2: \x{398}\x{3b8} - 3: \x{398} /\x{03f4}+/8i \x{0398}\x{03b8}\x{03d1}\x{03f4} 0: \x{398}\x{3b8}\x{3d1}\x{3f4} - 1: \x{398}\x{3b8}\x{3d1} - 2: \x{398}\x{3b8} - 3: \x{398} /\x{039a}+/8i \x{039a}\x{03ba}\x{03f0} 0: \x{39a}\x{3ba}\x{3f0} - 1: \x{39a}\x{3ba} - 2: \x{39a} /\x{03ba}+/8i \x{039a}\x{03ba}\x{03f0} 0: \x{39a}\x{3ba}\x{3f0} - 1: \x{39a}\x{3ba} - 2: \x{39a} /\x{03f0}+/8i \x{039a}\x{03ba}\x{03f0} 0: \x{39a}\x{3ba}\x{3f0} - 1: \x{39a}\x{3ba} - 2: \x{39a} /\x{03a0}+/8i \x{03a0}\x{03c0}\x{03d6} 0: \x{3a0}\x{3c0}\x{3d6} - 1: \x{3a0}\x{3c0} - 2: \x{3a0} /\x{03c0}+/8i \x{03a0}\x{03c0}\x{03d6} 0: \x{3a0}\x{3c0}\x{3d6} - 1: \x{3a0}\x{3c0} - 2: \x{3a0} /\x{03d6}+/8i \x{03a0}\x{03c0}\x{03d6} 0: \x{3a0}\x{3c0}\x{3d6} - 1: \x{3a0}\x{3c0} - 2: \x{3a0} /\x{03a1}+/8i \x{03a1}\x{03c1}\x{03f1} 0: \x{3a1}\x{3c1}\x{3f1} - 1: \x{3a1}\x{3c1} - 2: \x{3a1} /\x{03c1}+/8i \x{03a1}\x{03c1}\x{03f1} 0: \x{3a1}\x{3c1}\x{3f1} - 1: \x{3a1}\x{3c1} - 2: \x{3a1} /\x{03f1}+/8i \x{03a1}\x{03c1}\x{03f1} 0: \x{3a1}\x{3c1}\x{3f1} - 1: \x{3a1}\x{3c1} - 2: \x{3a1} /\x{03a3}+/8i \x{03A3}\x{03C2}\x{03C3} 0: \x{3a3}\x{3c2}\x{3c3} - 1: \x{3a3}\x{3c2} - 2: \x{3a3} /\x{03c2}+/8i \x{03A3}\x{03C2}\x{03C3} 0: \x{3a3}\x{3c2}\x{3c3} - 1: \x{3a3}\x{3c2} - 2: \x{3a3} /\x{03c3}+/8i \x{03A3}\x{03C2}\x{03C3} 0: \x{3a3}\x{3c2}\x{3c3} - 1: \x{3a3}\x{3c2} - 2: \x{3a3} /\x{03a6}+/8i \x{03a6}\x{03c6}\x{03d5} 0: \x{3a6}\x{3c6}\x{3d5} - 1: \x{3a6}\x{3c6} - 2: \x{3a6} /\x{03c6}+/8i \x{03a6}\x{03c6}\x{03d5} 0: \x{3a6}\x{3c6}\x{3d5} - 1: \x{3a6}\x{3c6} - 2: \x{3a6} /\x{03d5}+/8i \x{03a6}\x{03c6}\x{03d5} 0: \x{3a6}\x{3c6}\x{3d5} - 1: \x{3a6}\x{3c6} - 2: \x{3a6} /\x{03c9}+/8i \x{03c9}\x{03a9}\x{2126} 0: \x{3c9}\x{3a9}\x{2126} - 1: \x{3c9}\x{3a9} - 2: \x{3c9} /\x{03a9}+/8i \x{03c9}\x{03a9}\x{2126} 0: \x{3c9}\x{3a9}\x{2126} - 1: \x{3c9}\x{3a9} - 2: \x{3c9} /\x{2126}+/8i \x{03c9}\x{03a9}\x{2126} 0: \x{3c9}\x{3a9}\x{2126} - 1: \x{3c9}\x{3a9} - 2: \x{3c9} /\x{1e60}+/8i \x{1e60}\x{1e61}\x{1e9b} 0: \x{1e60}\x{1e61}\x{1e9b} - 1: \x{1e60}\x{1e61} - 2: \x{1e60} /\x{1e61}+/8i \x{1e60}\x{1e61}\x{1e9b} 0: \x{1e60}\x{1e61}\x{1e9b} - 1: \x{1e60}\x{1e61} - 2: \x{1e60} /\x{1e9b}+/8i \x{1e60}\x{1e61}\x{1e9b} 0: \x{1e60}\x{1e61}\x{1e9b} - 1: \x{1e60}\x{1e61} - 2: \x{1e60} /\x{1e9e}+/8i \x{1e9e}\x{00df} 0: \x{1e9e}\x{df} - 1: \x{1e9e} /\x{00df}+/8i \x{1e9e}\x{00df} 0: \x{1e9e}\x{df} - 1: \x{1e9e} /\x{1f88}+/8i \x{1f88}\x{1f80} 0: \x{1f88}\x{1f80} - 1: \x{1f88} /\x{1f80}+/8i \x{1f88}\x{1f80} 0: \x{1f88}\x{1f80} - 1: \x{1f88} /\x{004b}+/8i \x{004b}\x{006b}\x{212a} 0: Kk\x{212a} - 1: Kk - 2: K /\x{006b}+/8i \x{004b}\x{006b}\x{212a} 0: Kk\x{212a} - 1: Kk - 2: K /\x{212a}+/8i \x{004b}\x{006b}\x{212a} 0: Kk\x{212a} - 1: Kk - 2: K /\x{0053}+/8i \x{0053}\x{0073}\x{017f} 0: Ss\x{17f} - 1: Ss - 2: S /\x{0073}+/8i \x{0053}\x{0073}\x{017f} 0: Ss\x{17f} - 1: Ss - 2: S /\x{017f}+/8i \x{0053}\x{0073}\x{017f} 0: Ss\x{17f} - 1: Ss - 2: S /ist/8i ikt @@ -2723,4 +2419,129 @@ No match iskt No match +/^\p{Xuc}/8 + $abc + 0: $ + @abc + 0: @ + `abc + 0: ` + \x{1234}abc + 0: \x{1234} + ** Failers +No match + abc +No match + +/^\p{Xuc}+/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234}\x{e000} + ** Failers +No match + \x{9f} +No match + +/^\p{Xuc}+?/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234}\x{e000} + 1: $@`\x{a0}\x{1234} + 2: $@`\x{a0} + 3: $@` + 4: $@ + 5: $ + ** Failers +No match + \x{9f} +No match + +/^\p{Xuc}+?\*/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234}\x{e000}* + ** Failers +No match + \x{9f} +No match + +/^\p{Xuc}++/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234}\x{e000} + ** Failers +No match + \x{9f} +No match + +/^\p{Xuc}{3,5}/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234} + ** Failers +No match + \x{9f} +No match + +/^\p{Xuc}{3,5}?/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234} + 1: $@`\x{a0} + 2: $@` + ** Failers +No match + \x{9f} +No match + +/^[\p{Xuc}]/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $ + ** Failers +No match + \x{9f} +No match + +/^[\p{Xuc}]+/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234}\x{e000} + ** Failers +No match + \x{9f} +No match + +/^\P{Xuc}/8 + abc + 0: a + ** Failers + 0: * + $abc +No match + @abc +No match + `abc +No match + \x{1234}abc +No match + +/^[\P{Xuc}]/8 + abc + 0: a + ** Failers + 0: * + $abc +No match + @abc +No match + `abc +No match + \x{1234}abc +No match + +/^A\s+Z/8W + A\x{2005}Z + 0: A\x{2005}Z + A\x{85}\x{180e}\x{2005}Z + 0: A\x{85}\x{180e}\x{2005}Z + +/^A[\s]+Z/8W + A\x{2005}Z + 0: A\x{2005}Z + A\x{85}\x{180e}\x{2005}Z + 0: A\x{85}\x{180e}\x{2005}Z + /-- End of testinput10 --/ diff --git a/tools/pcre/testdata/testoutput11-16 b/tools/pcre/testdata/testoutput11-16 index dff72b94..f1ad8887 100644 --- a/tools/pcre/testdata/testoutput11-16 +++ b/tools/pcre/testdata/testoutput11-16 @@ -63,6 +63,7 @@ Memory allocation (code space): 10 4 End ------------------------------------------------------------------ Capturing subpattern count = 0 +May match empty string Options: extended No first char No need char @@ -99,15 +100,13 @@ Memory allocation (code space): 14 ------------------------------------------------------------------ /x{1,3}+/BM -Memory allocation (code space): 28 +Memory allocation (code space): 20 ------------------------------------------------------------------ - 0 11 Bra - 2 7 Once - 4 x - 6 x{0,2} - 9 7 Ket - 11 11 Ket - 13 End + 0 7 Bra + 2 x + 4 x{0,2}+ + 7 7 Ket + 9 End ------------------------------------------------------------------ /(x)*+/BM @@ -138,7 +137,7 @@ Memory allocation (code space): 142 39 [bc]+ 57 21 Ket 59 5 CBra 5 - 62 \w* + 62 \w*+ 64 5 Ket 66 63 Ket 68 68 Ket @@ -327,7 +326,7 @@ Memory allocation (code space): 16 ------------------------------------------------------------------ /\x{110000}/8BM -Failed: character value in \x{...} sequence is too large at offset 9 +Failed: character value in \x{} or \o{} is too large at offset 9 /[\x{ff}]/8BM Memory allocation (code space): 14 @@ -503,7 +502,7 @@ Memory allocation (code space): 24 Memory allocation (code space): 58 ------------------------------------------------------------------ 0 26 Bra - 2 [+\-\p{Nd}]+ + 2 [+\-\p{Nd}]++ 26 26 Ket 28 End ------------------------------------------------------------------ @@ -652,7 +651,7 @@ Memory allocation (code space): 14 /[[:^alpha:][:^cntrl:]]+/8WB ------------------------------------------------------------------ 0 26 Bra - 2 [ -~\x80-\xff\P{L}]+ + 2 [ -~\x80-\xff\P{L}]++ 26 26 Ket 28 End ------------------------------------------------------------------ @@ -660,7 +659,7 @@ Memory allocation (code space): 14 /[[:^cntrl:][:^alpha:]]+/8WB ------------------------------------------------------------------ 0 26 Bra - 2 [ -~\x80-\xff\P{L}]+ + 2 [ -~\x80-\xff\P{L}]++ 26 26 Ket 28 End ------------------------------------------------------------------ @@ -668,7 +667,7 @@ Memory allocation (code space): 14 /[[:alpha:]]+/8WB ------------------------------------------------------------------ 0 10 Bra - 2 [\p{L}]+ + 2 [\p{L}]++ 10 10 Ket 12 End ------------------------------------------------------------------ @@ -676,7 +675,7 @@ Memory allocation (code space): 14 /[[:^alpha:]\S]+/8WB ------------------------------------------------------------------ 0 13 Bra - 2 [\P{L}\P{Xsp}]+ + 2 [\P{L}\P{Xsp}]++ 13 13 Ket 15 End ------------------------------------------------------------------ diff --git a/tools/pcre/testdata/testoutput11-32 b/tools/pcre/testdata/testoutput11-32 index 8335fb82..266e55d0 100644 --- a/tools/pcre/testdata/testoutput11-32 +++ b/tools/pcre/testdata/testoutput11-32 @@ -63,6 +63,7 @@ Memory allocation (code space): 20 4 End ------------------------------------------------------------------ Capturing subpattern count = 0 +May match empty string Options: extended No first char No need char @@ -99,15 +100,13 @@ Memory allocation (code space): 28 ------------------------------------------------------------------ /x{1,3}+/BM -Memory allocation (code space): 56 +Memory allocation (code space): 40 ------------------------------------------------------------------ - 0 11 Bra - 2 7 Once - 4 x - 6 x{0,2} - 9 7 Ket - 11 11 Ket - 13 End + 0 7 Bra + 2 x + 4 x{0,2}+ + 7 7 Ket + 9 End ------------------------------------------------------------------ /(x)*+/BM @@ -138,7 +137,7 @@ Memory allocation (code space): 220 31 [bc]+ 41 13 Ket 43 5 CBra 5 - 46 \w* + 46 \w*+ 48 5 Ket 50 47 Ket 52 52 Ket @@ -327,7 +326,7 @@ Memory allocation (code space): 28 ------------------------------------------------------------------ /\x{110000}/8BM -Failed: character value in \x{...} sequence is too large at offset 9 +Failed: character value in \x{} or \o{} is too large at offset 9 /[\x{ff}]/8BM Memory allocation (code space): 28 @@ -503,7 +502,7 @@ Memory allocation (code space): 48 Memory allocation (code space): 84 ------------------------------------------------------------------ 0 18 Bra - 2 [+\-\p{Nd}]+ + 2 [+\-\p{Nd}]++ 18 18 Ket 20 End ------------------------------------------------------------------ @@ -652,7 +651,7 @@ Memory allocation (code space): 28 /[[:^alpha:][:^cntrl:]]+/8WB ------------------------------------------------------------------ 0 18 Bra - 2 [ -~\x80-\xff\P{L}]+ + 2 [ -~\x80-\xff\P{L}]++ 18 18 Ket 20 End ------------------------------------------------------------------ @@ -660,7 +659,7 @@ Memory allocation (code space): 28 /[[:^cntrl:][:^alpha:]]+/8WB ------------------------------------------------------------------ 0 18 Bra - 2 [ -~\x80-\xff\P{L}]+ + 2 [ -~\x80-\xff\P{L}]++ 18 18 Ket 20 End ------------------------------------------------------------------ @@ -668,7 +667,7 @@ Memory allocation (code space): 28 /[[:alpha:]]+/8WB ------------------------------------------------------------------ 0 10 Bra - 2 [\p{L}]+ + 2 [\p{L}]++ 10 10 Ket 12 End ------------------------------------------------------------------ @@ -676,7 +675,7 @@ Memory allocation (code space): 28 /[[:^alpha:]\S]+/8WB ------------------------------------------------------------------ 0 13 Bra - 2 [\P{L}\P{Xsp}]+ + 2 [\P{L}\P{Xsp}]++ 13 13 Ket 15 End ------------------------------------------------------------------ diff --git a/tools/pcre/testdata/testoutput11-8 b/tools/pcre/testdata/testoutput11-8 index c1c85f9a..d4a21334 100644 --- a/tools/pcre/testdata/testoutput11-8 +++ b/tools/pcre/testdata/testoutput11-8 @@ -63,6 +63,7 @@ Memory allocation (code space): 7 6 End ------------------------------------------------------------------ Capturing subpattern count = 0 +May match empty string Options: extended No first char No need char @@ -99,15 +100,13 @@ Memory allocation (code space): 9 ------------------------------------------------------------------ /x{1,3}+/BM -Memory allocation (code space): 19 +Memory allocation (code space): 13 ------------------------------------------------------------------ - 0 15 Bra - 3 9 Once - 6 x - 8 x{0,2} - 12 9 Ket - 15 15 Ket - 18 End + 0 9 Bra + 3 x + 5 x{0,2}+ + 9 9 Ket + 12 End ------------------------------------------------------------------ /(x)*+/BM @@ -138,7 +137,7 @@ Memory allocation (code space): 120 66 [bc]+ 100 39 Ket 103 7 CBra 5 -108 \w* +108 \w*+ 110 7 Ket 113 109 Ket 116 116 Ket @@ -327,7 +326,7 @@ Memory allocation (code space): 12 ------------------------------------------------------------------ /\x{110000}/8BM -Failed: character value in \x{...} sequence is too large at offset 9 +Failed: character value in \x{} or \o{} is too large at offset 9 /[\x{ff}]/8BM Memory allocation (code space): 10 @@ -503,7 +502,7 @@ Memory allocation (code space): 15 Memory allocation (code space): 48 ------------------------------------------------------------------ 0 44 Bra - 3 [+\-\p{Nd}]+ + 3 [+\-\p{Nd}]++ 44 44 Ket 47 End ------------------------------------------------------------------ @@ -652,7 +651,7 @@ Memory allocation (code space): 10 /[[:^alpha:][:^cntrl:]]+/8WB ------------------------------------------------------------------ 0 44 Bra - 3 [ -~\x80-\xff\P{L}]+ + 3 [ -~\x80-\xff\P{L}]++ 44 44 Ket 47 End ------------------------------------------------------------------ @@ -660,7 +659,7 @@ Memory allocation (code space): 10 /[[:^cntrl:][:^alpha:]]+/8WB ------------------------------------------------------------------ 0 44 Bra - 3 [ -~\x80-\xff\P{L}]+ + 3 [ -~\x80-\xff\P{L}]++ 44 44 Ket 47 End ------------------------------------------------------------------ @@ -668,7 +667,7 @@ Memory allocation (code space): 10 /[[:alpha:]]+/8WB ------------------------------------------------------------------ 0 12 Bra - 3 [\p{L}]+ + 3 [\p{L}]++ 12 12 Ket 15 End ------------------------------------------------------------------ @@ -676,7 +675,7 @@ Memory allocation (code space): 10 /[[:^alpha:]\S]+/8WB ------------------------------------------------------------------ 0 15 Bra - 3 [\P{L}\P{Xsp}]+ + 3 [\P{L}\P{Xsp}]++ 15 15 Ket 18 End ------------------------------------------------------------------ diff --git a/tools/pcre/testdata/testoutput12 b/tools/pcre/testdata/testoutput12 index 559f48d3..67ad2c8a 100644 --- a/tools/pcre/testdata/testoutput12 +++ b/tools/pcre/testdata/testoutput12 @@ -8,16 +8,26 @@ No options First char = 'a' Need char = 'c' Subject length lower bound = 3 -No set of starting bytes +No starting char list JIT study was successful -/ab(*THEN)/S+I +/(?(?C1)(?=a)a)/S+I Capturing subpattern count = 0 +May match empty string No options -First char = 'a' -Need char = 'b' -Subject length lower bound = 2 -No set of starting bytes +No first char +No need char +Study returned NULL +JIT study was not successful + +/(?(?C1)(?=a)a)/S!+I +Capturing subpattern count = 0 +May match empty string +No options +No first char +No need char +Subject length lower bound = -1 +No starting char list JIT study was not successful /abc/S+I>testsavedregex @@ -26,7 +36,7 @@ No options First char = 'a' Need char = 'c' Subject length lower bound = 3 -No set of starting bytes +No starting char list JIT study was successful Compiled pattern written to testsavedregex Study data written to testsavedregex @@ -39,6 +49,7 @@ Study data loaded from testsavedregex /a*/SI Capturing subpattern count = 0 +May match empty string No options No first char No need char @@ -154,28 +165,15 @@ No options First char = 'a' Need char = 'd' Subject length lower bound = 4 -No set of starting bytes +No starting char list JIT study was successful /(*NO_START_OPT)a(*:m)b/KS++ a No match, mark = m (JIT) -/.?(*THEN)/S+I -Capturing subpattern count = 0 -No options -No first char -No need char -Study returned NULL -JIT study was not successful - -/.?(*THEN)/S!+I -Capturing subpattern count = 0 -No options -No first char -No need char -Subject length lower bound = -1 -No set of starting bytes -JIT study was not successful +/^12345678abcd/mS++ + 12345678abcd + 0: 12345678abcd (JIT) /-- End of testinput12 --/ diff --git a/tools/pcre/testdata/testoutput13 b/tools/pcre/testdata/testoutput13 index e9cbbcf0..d6fb8a5c 100644 --- a/tools/pcre/testdata/testoutput13 +++ b/tools/pcre/testdata/testoutput13 @@ -8,11 +8,12 @@ No options First char = 'a' Need char = 'c' Subject length lower bound = 3 -No set of starting bytes +No starting char list JIT support is not available in this version of PCRE /a*/SI Capturing subpattern count = 0 +May match empty string No options No first char No need char diff --git a/tools/pcre/testdata/testoutput14 b/tools/pcre/testdata/testoutput14 index 5f05d77d..ae85681e 100644 --- a/tools/pcre/testdata/testoutput14 +++ b/tools/pcre/testdata/testoutput14 @@ -1,6 +1,9 @@ -/-- 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. --/ +/-- This set of tests is run only with the 8-bit library. They do not require + UTF-8 or Unicode property support. The file starts with all the tests of + the POSIX interface, because that is supported only with the 8-bit library. + --/ + +< forbid 8W /abc/P abc @@ -146,10 +149,17 @@ No match A\x{123}B ** Character \x{123} is greater than 255 and UTF-8 mode is not enabled. ** Truncation will probably give the wrong result. +No match + A\o{443}B +** Character \x{123} is greater than 255 and UTF-8 mode is not enabled. +** Truncation will probably give the wrong result. No match /\x{100}/I -Failed: character value in \x{...} sequence is too large at offset 6 +Failed: character value in \x{} or \o{} is too large at offset 6 + +/\o{400}/I +Failed: character value in \x{} or \o{} is too large at offset 6 / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* @@ -351,7 +361,7 @@ 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 +Starting chars: \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 @@ -378,7 +388,15 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: \x09 \x20 \xa0 +Starting chars: \x09 \x20 \xa0 + +/\H/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No starting char list /\v/SI Capturing subpattern count = 0 @@ -386,7 +404,15 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 +Starting chars: \x0a \x0b \x0c \x0d \x85 + +/\V/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No starting char list /\R/SI Capturing subpattern count = 0 @@ -394,7 +420,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 +Starting chars: \x0a \x0b \x0c \x0d \x85 /[\h]/BZ ------------------------------------------------------------------ @@ -409,7 +435,7 @@ Starting byte set: \x0a \x0b \x0c \x0d \x85 /[\h]+/BZ ------------------------------------------------------------------ Bra - [\x09 \xa0]+ + [\x09 \xa0]++ Ket End ------------------------------------------------------------------ @@ -473,4 +499,32 @@ 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 +/[^\x00-a]{12,}[^b-\xff]*/BZ +------------------------------------------------------------------ + Bra + [b-\xff] (neg){12,}+ + [\x00-a] (neg)*+ + Ket + End +------------------------------------------------------------------ + +/[^\s]*\s* [^\W]+\W+ [^\d]*?\d0 [^\d\w]{4,6}?\w*A/BZ +------------------------------------------------------------------ + Bra + [\x00-\x08\x0e-\x1f!-\xff] (neg)*+ + \s* + + [0-9A-Z_a-z]++ + \W+ + + [\x00-/:-\xff] (neg)*+ + \d + 0 + [\x00-/:-@[-^`{-\xff] (neg){4,6}+ + \w* + A + Ket + End +------------------------------------------------------------------ + /-- End of testinput14 --/ diff --git a/tools/pcre/testdata/testoutput15 b/tools/pcre/testdata/testoutput15 index d6b7d094..5af369d0 100644 --- a/tools/pcre/testdata/testoutput15 +++ b/tools/pcre/testdata/testoutput15 @@ -1,5 +1,7 @@ -/-- This set of tests is for UTF-8 support, and is relevant only to the 8-bit - library. --/ +/-- This set of tests is for UTF-8 support but not Unicode property support, + and is relevant only to the 8-bit library. --/ + +< forbid W /X(\C{3})/8 X\x{1234} @@ -72,7 +74,7 @@ Failed: invalid UTF-8 string at offset 0 /ÃÃÃxxx/8 Failed: invalid UTF-8 string at offset 0 -/ÃÃÃxxx/8?DZSS +/ÃÃÃxxx/8?DZSSO ------------------------------------------------------------------ Bra \X{c0}\X{c0}\X{c0}xxx @@ -80,7 +82,7 @@ Failed: invalid UTF-8 string at offset 0 End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf no_utf_check +Options: no_auto_possessify utf no_utf_check First char = \x{c3} Need char = 'x' @@ -163,8 +165,6 @@ Error -10 (bad UTF-8 string) offset=0 reason=20 Error -10 (bad UTF-8 string) offset=0 reason=21 \xff Error -10 (bad UTF-8 string) offset=0 reason=21 - \xef\xb7\x90 -Error -10 (bad UTF-8 string) offset=0 reason=22 /badutf/8 \xfb\x80\x80\x80\x80 @@ -250,140 +250,6 @@ No match \?\xfd\x83\x80\x80\x80\x80 No match -/noncharacter/8 - \x{fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{1fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{1ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{2fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{2ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{3fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{3ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{4fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{4ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{5fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{5ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{6fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{6ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{7fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{7ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{8fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{8ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{9fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{9ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{afffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{affff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{bfffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{bffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{cfffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{cffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{dfffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{dffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{efffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{effff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{ffffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{10fffe} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{10ffff} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdd0} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdd1} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdd2} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdd3} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdd4} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdd5} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdd6} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdd7} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdd8} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdd9} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdda} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fddb} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fddc} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fddd} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdde} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fddf} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fde0} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fde1} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fde2} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fde3} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fde4} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fde5} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fde6} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fde7} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fde8} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fde9} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdea} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdeb} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdec} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fded} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdee} -Error -10 (bad UTF-8 string) offset=0 reason=22 - \x{fdef} -Error -10 (bad UTF-8 string) offset=0 reason=22 - /\x{100}/8DZ ------------------------------------------------------------------ Bra @@ -615,7 +481,7 @@ 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 +Starting chars: \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 @@ -644,7 +510,7 @@ No match ------------------------------------------------------------------ Bra \x{100}{3} - \x{100}? + \x{100}?+ Ket End ------------------------------------------------------------------ @@ -653,7 +519,7 @@ Options: utf First char = \x{c4} Need char = \x{80} Subject length lower bound = 3 -No set of starting bytes +No starting char list \x{100}\x{100}\x{100}\x{100\x{100} 0: \x{100}\x{100}\x{100} @@ -661,7 +527,7 @@ No set of starting bytes ------------------------------------------------------------------ Bra CBra 1 - \x{100}+ + \x{100}++ Alt x Ket @@ -673,7 +539,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: x \xc4 +Starting chars: x \xc4 /(\x{100}*a|x)/8SDZ ------------------------------------------------------------------ @@ -692,13 +558,13 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: a x \xc4 +Starting chars: a x \xc4 /(\x{100}{0,2}a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 - \x{100}{0,2} + \x{100}{0,2}+ a Alt x @@ -711,14 +577,14 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: a x \xc4 +Starting chars: a x \xc4 /(\x{100}{1,2}a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100} - \x{100}{0,1} + \x{100}{0,1}+ a Alt x @@ -731,7 +597,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: x \xc4 +Starting chars: x \xc4 /\x{100}/8DZ ------------------------------------------------------------------ @@ -749,7 +615,7 @@ Need char = \x{80} ------------------------------------------------------------------ Bra a\x{100} - \x{101}* + \x{101}*+ Ket End ------------------------------------------------------------------ @@ -762,7 +628,7 @@ Need char = \x{80} ------------------------------------------------------------------ Bra a\x{100} - \x{101}+ + \x{101}++ Ket End ------------------------------------------------------------------ @@ -891,8 +757,6 @@ 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} -Error -10 (bad UTF-8 string) offset=7 reason=22 \x{d800} Error -10 (bad UTF-8 string) offset=0 reason=14 \x{d800}\? @@ -935,7 +799,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: \x09 \x20 \xc2 \xe1 \xe2 \xe3 +Starting chars: \x09 \x20 \xc2 \xe1 \xe2 \xe3 ABC\x{09} 0: \x{09} ABC\x{20} @@ -961,7 +825,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 +Starting chars: \x0a \x0b \x0c \x0d \xc2 \xe2 ABC\x{0a} 0: \x{0a} ABC\x{0b} @@ -981,7 +845,7 @@ Options: utf No first char Need char = 'A' Subject length lower bound = 1 -Starting byte set: \x09 \x20 A \xc2 \xe1 \xe2 \xe3 +Starting chars: \x09 \x20 A \xc2 \xe1 \xe2 \xe3 CDBABC 0: A @@ -991,7 +855,7 @@ Options: utf No first char Need char = 'A' Subject length lower bound = 2 -Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 +Starting chars: \x0a \x0b \x0c \x0d \xc2 \xe2 /\s?xxx\s/8SI Capturing subpattern count = 0 @@ -999,7 +863,7 @@ Options: utf No first char Need char = 'x' Subject length lower bound = 4 -Starting byte set: \x09 \x0a \x0c \x0d \x20 x +Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 x /\sxxx\s/I8ST1 Capturing subpattern count = 0 @@ -1007,7 +871,7 @@ Options: utf No first char Need char = 'x' Subject length lower bound = 5 -Starting byte set: \x09 \x0a \x0c \x0d \x20 \xc2 +Starting chars: \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 @@ -1019,7 +883,7 @@ 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 +Starting chars: \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 @@ -1053,7 +917,7 @@ Options: caseless utf No first char No need char Subject length lower bound = 1 -Starting byte set: \xe1 +Starting chars: \xe1 /\x{1234}+?/iS8I Capturing subpattern count = 0 @@ -1061,7 +925,7 @@ Options: caseless utf No first char No need char Subject length lower bound = 1 -Starting byte set: \xe1 +Starting chars: \xe1 /\x{1234}++/iS8I Capturing subpattern count = 0 @@ -1069,7 +933,7 @@ Options: caseless utf No first char No need char Subject length lower bound = 1 -Starting byte set: \xe1 +Starting chars: \xe1 /\x{1234}{2}/iS8I Capturing subpattern count = 0 @@ -1077,7 +941,7 @@ Options: caseless utf No first char No need char Subject length lower bound = 2 -Starting byte set: \xe1 +Starting chars: \xe1 /[^\x{c4}]/8DZ ------------------------------------------------------------------ @@ -1110,7 +974,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 +Starting chars: \x0a \x0b \x0c \x0d \xc2 \xe2 /\777/8DZ ------------------------------------------------------------------ @@ -1266,4 +1130,10 @@ Need char = \x{bf} \x{7f000041} Error -10 (bad UTF-8 string) offset=0 reason=12 +/(*UTF8)abc/9 +Failed: setting UTF is disabled by the application at offset 0 + +/abc/89 +Failed: setting UTF is disabled by the application at offset 0 + /-- End of testinput15 --/ diff --git a/tools/pcre/testdata/testoutput16 b/tools/pcre/testdata/testoutput16 index 1d5f31d9..63e9eb06 100644 --- a/tools/pcre/testdata/testoutput16 +++ b/tools/pcre/testdata/testoutput16 @@ -64,7 +64,7 @@ Options: caseless utf No first char No need char Subject length lower bound = 17 -Starting byte set: \xd0 \xd1 +Starting chars: \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} @@ -92,7 +92,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: \x09 \x20 \xa0 +Starting chars: \x09 \x20 \xa0 /\v/SI Capturing subpattern count = 0 @@ -100,7 +100,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 +Starting chars: \x0a \x0b \x0c \x0d \x85 /\R/SI Capturing subpattern count = 0 @@ -108,7 +108,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 +Starting chars: \x0a \x0b \x0c \x0d \x85 /[[:blank:]]/WBZ ------------------------------------------------------------------ diff --git a/tools/pcre/testdata/testoutput17 b/tools/pcre/testdata/testoutput17 index ef82dc9d..1a3b492f 100644 --- a/tools/pcre/testdata/testoutput17 +++ b/tools/pcre/testdata/testoutput17 @@ -1,6 +1,8 @@ /-- This set of tests is for the 16- and 32-bit library's basic (non-UTF-16 or -32) features that are not compatible with the 8-bit library, or which give different output in 16- or 32-bit mode. --/ + +< forbid 8W /a\Cb/ aXb @@ -226,7 +228,7 @@ 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 +Starting chars: \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 @@ -243,7 +245,7 @@ Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8 /[\h]+/BZ ------------------------------------------------------------------ Bra - [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]+ + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]++ Ket End ------------------------------------------------------------------ @@ -272,7 +274,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: \x09 \x20 \xa0 \xff +Starting chars: \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} @@ -281,7 +283,7 @@ Starting byte set: \x09 \x20 \xa0 \xff /[\h\x{dc00}]+/BZSI ------------------------------------------------------------------ Bra - [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{dc00}]+ + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{dc00}]++ Ket End ------------------------------------------------------------------ @@ -290,7 +292,7 @@ No options No first char No need char Subject length lower bound = 1 -No set of starting bytes +Starting chars: \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} @@ -302,7 +304,7 @@ No options No first char No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list \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} @@ -328,7 +330,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff +Starting chars: \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 @@ -337,7 +339,7 @@ Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff /[\v\x{dc00}]+/BZSI ------------------------------------------------------------------ Bra - [\x0a-\x0d\x85\x{2028}-\x{2029}\x{dc00}]+ + [\x0a-\x0d\x85\x{2028}-\x{2029}\x{dc00}]++ Ket End ------------------------------------------------------------------ @@ -346,7 +348,7 @@ No options No first char No need char Subject length lower bound = 1 -No set of starting bytes +Starting chars: \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 @@ -358,7 +360,7 @@ No options No first char No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list \x{2028}\x{2029}\x{2027}\x{2030} 0: \x{2027}\x{2030} \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 @@ -376,7 +378,7 @@ Options: bsr_unicode No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff +Starting chars: \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 @@ -440,10 +442,8 @@ Need char = \x{dd00} /i [^\x{8000}]* /i [^\x{7fff}]{2} /i [^\x{7fff}]{0,7}? - Once /i [^\x{100}]{5} - /i [^\x{100}]? - Ket + /i [^\x{100}]?+ Ket End ------------------------------------------------------------------ @@ -502,4 +502,57 @@ MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789AB \x{ffff} 0: \x{ffff} +/[^\x00-a]{12,}[^b-\xff]*/BZ +------------------------------------------------------------------ + Bra + [b-\xff] (neg){12,} + [\x00-a] (neg)*+ + Ket + End +------------------------------------------------------------------ + +/[^\s]*\s* [^\W]+\W+ [^\d]*?\d0 [^\d\w]{4,6}?\w*A/BZ +------------------------------------------------------------------ + Bra + [\x00-\x08\x0e-\x1f!-\xff] (neg)* + \s* + + [0-9A-Z_a-z]++ + \W+ + + [\x00-/:-\xff] (neg)*? + \d + 0 + [\x00-/:-@[-^`{-\xff] (neg){4,6}? + \w* + A + Ket + End +------------------------------------------------------------------ + +/a*[b-\x{200}]?a#a*[b-\x{200}]?b#[a-f]*[g-\x{200}]*#[g-\x{200}]*[a-c]*#[g-\x{200}]*[a-h]*/BZ +------------------------------------------------------------------ + Bra + a* + [b-\xff\x{100}-\x{200}]?+ + a# + a*+ + [b-\xff\x{100}-\x{200}]? + b# + [a-f]*+ + [g-\xff\x{100}-\x{200}]*+ + # + [g-\xff\x{100}-\x{200}]*+ + [a-c]*+ + # + [g-\xff\x{100}-\x{200}]* + [a-h]*+ + Ket + End +------------------------------------------------------------------ + +/^[\x{1234}\x{4321}]{2,4}?/ + \x{1234}\x{1234}\x{1234} + 0: \x{1234}\x{1234} + /-- End of testinput17 --/ diff --git a/tools/pcre/testdata/testoutput18-16 b/tools/pcre/testdata/testoutput18-16 index 50a8301d..a1962057 100644 --- a/tools/pcre/testdata/testoutput18-16 +++ b/tools/pcre/testdata/testoutput18-16 @@ -1,5 +1,7 @@ -/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to the - 16- and 32-bit library. --/ +/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to + the 16- and 32-bit libraries. --/ + +< forbid W /ÃÃÃxxx/8?DZSS **Failed: invalid UTF-8 string cannot be converted to UTF-16 @@ -337,7 +339,7 @@ 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 +Starting chars: \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 @@ -367,7 +369,7 @@ No match ------------------------------------------------------------------ Bra \x{100}{3} - \x{100}? + \x{100}?+ Ket End ------------------------------------------------------------------ @@ -376,7 +378,7 @@ Options: utf First char = \x{100} Need char = \x{100} Subject length lower bound = 3 -No set of starting bytes +No starting char list \x{100}\x{100}\x{100}\x{100\x{100} 0: \x{100}\x{100}\x{100} @@ -384,7 +386,7 @@ No set of starting bytes ------------------------------------------------------------------ Bra CBra 1 - \x{100}+ + \x{100}++ Alt x Ket @@ -396,7 +398,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: x \xff +Starting chars: x \xff /(\x{100}*a|x)/8SDZ ------------------------------------------------------------------ @@ -415,13 +417,13 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: a x \xff +Starting chars: a x \xff /(\x{100}{0,2}a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 - \x{100}{0,2} + \x{100}{0,2}+ a Alt x @@ -434,14 +436,14 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: a x \xff +Starting chars: a x \xff /(\x{100}{1,2}a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100} - \x{100}{0,1} + \x{100}{0,1}+ a Alt x @@ -454,7 +456,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: x \xff +Starting chars: x \xff /\x{100}/8DZ ------------------------------------------------------------------ @@ -472,7 +474,7 @@ No need char ------------------------------------------------------------------ Bra a\x{100} - \x{101}* + \x{101}*+ Ket End ------------------------------------------------------------------ @@ -485,7 +487,7 @@ Need char = \x{100} ------------------------------------------------------------------ Bra a\x{100} - \x{101}+ + \x{101}++ Ket End ------------------------------------------------------------------ @@ -608,8 +610,6 @@ Need char = 'X' Failed: missing terminating ] for character class at offset 13 /X/8 - \x{0}\x{d7ff}\x{e000}\x{10ffff} -Error -10 (bad UTF-16 string) offset=4 reason=4 \x{d800} Error -10 (bad UTF-16 string) offset=0 reason=1 \x{d800}\? @@ -634,8 +634,6 @@ No match ** Failed: character \x{110000} is greater than 0x10ffff and so cannot be converted to UTF-16 \x{d800}\x{1234} Error -10 (bad UTF-16 string) offset=1 reason=2 - \x{fffe} -Error -10 (bad UTF-16 string) offset=0 reason=4 /(*UTF16)\x{11234}/ abcd\x{11234}pqr @@ -650,7 +648,7 @@ Need char = \x{de34} 0: \x{11234} /(*UTF-32)\x{11234}/ -Failed: (*VERB) not recognized at offset 5 +Failed: (*VERB) not recognized or malformed at offset 5 /(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I Capturing subpattern count = 0 @@ -660,7 +658,7 @@ First char = 'a' Need char = 'b' /(*CRLF)(*UTF32)(*BSR_UNICODE)a\Rb/I -Failed: (*VERB) not recognized at offset 12 +Failed: (*VERB) not recognized or malformed at offset 12 /\h/SI8 Capturing subpattern count = 0 @@ -668,7 +666,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: \x09 \x20 \xa0 \xff +Starting chars: \x09 \x20 \xa0 \xff ABC\x{09} 0: \x{09} ABC\x{20} @@ -694,7 +692,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff +Starting chars: \x0a \x0b \x0c \x0d \x85 \xff ABC\x{0a} 0: \x{0a} ABC\x{0b} @@ -714,19 +712,19 @@ Options: utf No first char Need char = 'A' Subject length lower bound = 1 -Starting byte set: \x09 \x20 A \xa0 \xff +Starting chars: \x09 \x20 A \xa0 \xff CDBABC 0: A \x{2000}ABC 0: \x{2000}A -/\R*A/SI8 +/\R*A/SI8 Capturing subpattern count = 0 -Options: utf +Options: bsr_unicode utf No first char Need char = 'A' Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d A \x85 \xff +Starting chars: \x0a \x0b \x0c \x0d A \x85 \xff CDBABC 0: A \x{2028}A @@ -738,7 +736,7 @@ Options: utf No first char Need char = 'A' Subject length lower bound = 2 -Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff +Starting chars: \x0a \x0b \x0c \x0d \x85 \xff /\s?xxx\s/8SI Capturing subpattern count = 0 @@ -746,7 +744,7 @@ Options: utf No first char Need char = 'x' Subject length lower bound = 4 -Starting byte set: \x09 \x0a \x0c \x0d \x20 x +Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 x /\sxxx\s/I8ST1 Capturing subpattern count = 0 @@ -754,7 +752,7 @@ Options: utf No first char Need char = 'x' Subject length lower bound = 5 -Starting byte set: \x09 \x0a \x0c \x0d \x20 \x85 \xa0 +Starting chars: \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 @@ -766,7 +764,7 @@ 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 +Starting chars: \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 @@ -805,7 +803,7 @@ Options: caseless utf First char = \x{1234} No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list /\x{1234}+?/iS8I Capturing subpattern count = 0 @@ -813,7 +811,7 @@ Options: caseless utf First char = \x{1234} No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list /\x{1234}++/iS8I Capturing subpattern count = 0 @@ -821,7 +819,7 @@ Options: caseless utf First char = \x{1234} No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list /\x{1234}{2}/iS8I Capturing subpattern count = 0 @@ -829,7 +827,7 @@ Options: caseless utf First char = \x{1234} Need char = \x{1234} Subject length lower bound = 2 -No set of starting bytes +No starting char list /[^\x{c4}]/8DZ ------------------------------------------------------------------ @@ -862,7 +860,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff +Starting chars: \x0a \x0b \x0c \x0d \x85 \xff /-- Check bad offset --/ @@ -1019,4 +1017,10 @@ Failed: invalid UTF-16 string at offset 0 \x{a0}\x20! 0: \x{a0} ! +/(*UTF)abc/9 +Failed: setting UTF is disabled by the application at offset 0 + +/abc/89 +Failed: setting UTF is disabled by the application at offset 0 + /-- End of testinput18 --/ diff --git a/tools/pcre/testdata/testoutput18-32 b/tools/pcre/testdata/testoutput18-32 index 334fae0c..1525994d 100644 --- a/tools/pcre/testdata/testoutput18-32 +++ b/tools/pcre/testdata/testoutput18-32 @@ -1,5 +1,7 @@ -/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to the - 16- and 32-bit library. --/ +/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to + the 16- and 32-bit libraries. --/ + +< forbid W /ÃÃÃxxx/8?DZSS **Failed: invalid UTF-8 string cannot be converted to UTF-32 @@ -335,7 +337,7 @@ 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 +Starting chars: \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 @@ -365,7 +367,7 @@ No match ------------------------------------------------------------------ Bra \x{100}{3} - \x{100}? + \x{100}?+ Ket End ------------------------------------------------------------------ @@ -374,7 +376,7 @@ Options: utf First char = \x{100} Need char = \x{100} Subject length lower bound = 3 -No set of starting bytes +No starting char list \x{100}\x{100}\x{100}\x{100\x{100} 0: \x{100}\x{100}\x{100} @@ -382,7 +384,7 @@ No set of starting bytes ------------------------------------------------------------------ Bra CBra 1 - \x{100}+ + \x{100}++ Alt x Ket @@ -394,7 +396,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: x \xff +Starting chars: x \xff /(\x{100}*a|x)/8SDZ ------------------------------------------------------------------ @@ -413,13 +415,13 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: a x \xff +Starting chars: a x \xff /(\x{100}{0,2}a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 - \x{100}{0,2} + \x{100}{0,2}+ a Alt x @@ -432,14 +434,14 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: a x \xff +Starting chars: a x \xff /(\x{100}{1,2}a|x)/8SDZ ------------------------------------------------------------------ Bra CBra 1 \x{100} - \x{100}{0,1} + \x{100}{0,1}+ a Alt x @@ -452,7 +454,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: x \xff +Starting chars: x \xff /\x{100}/8DZ ------------------------------------------------------------------ @@ -470,7 +472,7 @@ No need char ------------------------------------------------------------------ Bra a\x{100} - \x{101}* + \x{101}*+ Ket End ------------------------------------------------------------------ @@ -483,7 +485,7 @@ Need char = \x{100} ------------------------------------------------------------------ Bra a\x{100} - \x{101}+ + \x{101}++ Ket End ------------------------------------------------------------------ @@ -606,8 +608,6 @@ Need char = 'X' Failed: missing terminating ] for character class at offset 13 /X/8 - \x{0}\x{d7ff}\x{e000}\x{10ffff} -Error -10 (bad UTF-32 string) offset=3 reason=2 \x{d800} Error -10 (bad UTF-32 string) offset=0 reason=1 \x{d800}\? @@ -632,11 +632,9 @@ No match Error -10 (bad UTF-32 string) offset=0 reason=3 \x{d800}\x{1234} Error -10 (bad UTF-32 string) offset=0 reason=1 - \x{fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 /(*UTF16)\x{11234}/ -Failed: (*VERB) not recognized at offset 5 +Failed: (*VERB) not recognized or malformed at offset 5 /(*UTF)\x{11234}/I Capturing subpattern count = 0 @@ -647,10 +645,10 @@ No need char 0: \x{11234} /(*UTF-32)\x{11234}/ -Failed: (*VERB) not recognized at offset 5 +Failed: (*VERB) not recognized or malformed at offset 5 /(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I -Failed: (*VERB) not recognized at offset 12 +Failed: (*VERB) not recognized or malformed at offset 12 /(*CRLF)(*UTF32)(*BSR_UNICODE)a\Rb/I Capturing subpattern count = 0 @@ -665,7 +663,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: \x09 \x20 \xa0 \xff +Starting chars: \x09 \x20 \xa0 \xff ABC\x{09} 0: \x{09} ABC\x{20} @@ -691,7 +689,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff +Starting chars: \x0a \x0b \x0c \x0d \x85 \xff ABC\x{0a} 0: \x{0a} ABC\x{0b} @@ -711,19 +709,19 @@ Options: utf No first char Need char = 'A' Subject length lower bound = 1 -Starting byte set: \x09 \x20 A \xa0 \xff +Starting chars: \x09 \x20 A \xa0 \xff CDBABC 0: A \x{2000}ABC 0: \x{2000}A -/\R*A/SI8 +/\R*A/SI8 Capturing subpattern count = 0 -Options: utf +Options: bsr_unicode utf No first char Need char = 'A' Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d A \x85 \xff +Starting chars: \x0a \x0b \x0c \x0d A \x85 \xff CDBABC 0: A \x{2028}A @@ -735,7 +733,7 @@ Options: utf No first char Need char = 'A' Subject length lower bound = 2 -Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff +Starting chars: \x0a \x0b \x0c \x0d \x85 \xff /\s?xxx\s/8SI Capturing subpattern count = 0 @@ -743,7 +741,7 @@ Options: utf No first char Need char = 'x' Subject length lower bound = 4 -Starting byte set: \x09 \x0a \x0c \x0d \x20 x +Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 x /\sxxx\s/I8ST1 Capturing subpattern count = 0 @@ -751,7 +749,7 @@ Options: utf No first char Need char = 'x' Subject length lower bound = 5 -Starting byte set: \x09 \x0a \x0c \x0d \x20 \x85 \xa0 +Starting chars: \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 @@ -763,7 +761,7 @@ 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 +Starting chars: \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 @@ -802,7 +800,7 @@ Options: caseless utf First char = \x{1234} No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list /\x{1234}+?/iS8I Capturing subpattern count = 0 @@ -810,7 +808,7 @@ Options: caseless utf First char = \x{1234} No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list /\x{1234}++/iS8I Capturing subpattern count = 0 @@ -818,7 +816,7 @@ Options: caseless utf First char = \x{1234} No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list /\x{1234}{2}/iS8I Capturing subpattern count = 0 @@ -826,7 +824,7 @@ Options: caseless utf First char = \x{1234} Need char = \x{1234} Subject length lower bound = 2 -No set of starting bytes +No starting char list /[^\x{c4}]/8DZ ------------------------------------------------------------------ @@ -859,7 +857,7 @@ Options: utf No first char No need char Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff +Starting chars: \x0a \x0b \x0c \x0d \x85 \xff /-- Check bad offset --/ @@ -1016,4 +1014,10 @@ Error -24 (bad offset value) \x{a0}\x20! 0: \x{a0} ! +/(*UTF)abc/9 +Failed: setting UTF is disabled by the application at offset 0 + +/abc/89 +Failed: setting UTF is disabled by the application at offset 0 + /-- End of testinput18 --/ diff --git a/tools/pcre/testdata/testoutput19 b/tools/pcre/testdata/testoutput19 index ccc198cc..21fe6779 100644 --- a/tools/pcre/testdata/testoutput19 +++ b/tools/pcre/testdata/testoutput19 @@ -55,7 +55,7 @@ Options: caseless utf First char = \x{401} (caseless) Need char = \x{42f} (caseless) Subject length lower bound = 17 -No set of starting bytes +No starting char list \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} diff --git a/tools/pcre/testdata/testoutput2 b/tools/pcre/testdata/testoutput2 index e9cddf80..b6da7df1 100644 --- a/tools/pcre/testdata/testoutput2 +++ b/tools/pcre/testdata/testoutput2 @@ -7,9 +7,12 @@ NOTE: This is a non-UTF set of tests. When UTF support is needed, use test 5, and if Unicode Property Support is needed, use test 7. --/ + +< forbid 8W /(a)b|/I Capturing subpattern count = 1 +May match empty string No options No first char No need char @@ -175,7 +178,7 @@ No options No first char No need char Subject length lower bound = 3 -Starting byte set: c d e +Starting chars: c d e this sentence eventually mentions a cat 0: cat this sentences rambles on and on for a while and then reaches elephant @@ -187,7 +190,7 @@ Options: caseless No first char No need char Subject length lower bound = 3 -Starting byte set: C D E c d e +Starting chars: C D E c d e this sentence eventually mentions a CAT cat 0: CAT this sentences rambles on and on for a while to elephant ElePhant @@ -199,7 +202,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: a b c d +Starting chars: a b c d /(a|[^\dZ])/IS Capturing subpattern count = 1 @@ -207,7 +210,7 @@ No options 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 +Starting chars: \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 ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ 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 [ \ ] ^ _ ` a b c d @@ -228,7 +231,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: \x09 \x0a \x0c \x0d \x20 a b +Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 a b /(ab\2)/ Failed: reference to non-existent subpattern at offset 6 @@ -448,10 +451,10 @@ Need char = '=' /(?.*)(?<=(abcd)|(xyz))/I Capturing subpattern count = 2 +Max lookbehind = 4 +May match empty string No options No first char No need char -Max lookbehind = 4 alphabetabcd 0: alphabetabcd 1: abcd @@ -781,10 +788,10 @@ Max lookbehind = 4 /(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/I Capturing subpattern count = 0 +Max lookbehind = 4 No options First char = 'Z' Need char = 'Z' -Max lookbehind = 4 abxyZZ 0: ZZ abXyZZ @@ -810,10 +817,10 @@ No match /(?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 ------------------------------------------------------------------ @@ -3247,10 +3272,10 @@ Max lookbehind = 1 End ------------------------------------------------------------------ Capturing subpattern count = 0 +Max lookbehind = 1 No options First char = '$' Need char = 'X' -Max lookbehind = 1 /(.*)\d+\1/I Capturing subpattern count = 1 @@ -3304,6 +3329,7 @@ Need char = 'b' /(?=a).*/I Capturing subpattern count = 0 +May match empty string No options First char = 'a' No need char @@ -3322,6 +3348,7 @@ Need char = 'z' (caseless) /(?=a)(?=b)/I Capturing subpattern count = 0 +May match empty string No options First char = 'a' No need char @@ -3388,6 +3415,7 @@ Need char = 'a' /(a)*/I Capturing subpattern count = 1 +May match empty string No options No first char No need char @@ -3410,7 +3438,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: a b +Starting chars: a b /[^a]/I Capturing subpattern count = 0 @@ -3430,7 +3458,7 @@ No options No first char Need char = '6' Subject length lower bound = 4 -Starting byte set: 0 1 2 3 4 5 6 7 8 9 +Starting chars: 0 1 2 3 4 5 6 7 8 9 /a^b/I Capturing subpattern count = 0 @@ -3464,7 +3492,7 @@ Options: caseless No first char No need char Subject length lower bound = 1 -Starting byte set: A B a b +Starting chars: A B a b /[ab](?i)cd/IS Capturing subpattern count = 0 @@ -3472,7 +3500,7 @@ No options No first char Need char = 'd' (caseless) Subject length lower bound = 3 -Starting byte set: a b +Starting chars: a b /abc(?C)def/I Capturing subpattern count = 0 @@ -3513,7 +3541,7 @@ 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 +Starting chars: 0 1 2 3 4 5 6 7 8 9 1234abcdef --->1234abcdef 1 ^ \d @@ -3616,6 +3644,7 @@ No match /(?C0)(abc(?C1))*/I Capturing subpattern count = 1 +May match empty string No options No first char No need char @@ -3649,6 +3678,7 @@ No need char /(\d{3}(?C))*/I Capturing subpattern count = 1 +May match empty string No options No first char No need char @@ -3763,10 +3793,10 @@ Callout 2: last capture = -1 /(?<=(abc)(?C))xyz/I Capturing subpattern count = 1 +Max lookbehind = 3 No options First char = 'x' Need char = 'z' -Max lookbehind = 3 abcxyz\C+ Callout 0: last capture = 1 0: @@ -3784,20 +3814,6 @@ Need char = 'b' abbbbbccc\C*1 --->abbbbbccc 1 ^ ^ -Callout data = 1 - 1 ^ ^ -Callout data = 1 - 1 ^ ^ -Callout data = 1 - 1 ^ ^ -Callout data = 1 - 1 ^ ^ -Callout data = 1 - 1 ^ ^ -Callout data = 1 - 1 ^ ^ -Callout data = 1 - 1 ^ ^ Callout data = 1 No match @@ -3844,7 +3860,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: a b +Starting chars: a b /(?R)/I Failed: recursive call could loop indefinitely at offset 3 @@ -3895,6 +3911,7 @@ Failed: recursive call could loop indefinitely at offset 16 /^([^()]|\((?1)*\))*$/I Capturing subpattern count = 1 +May match empty string Options: anchored No first char No need char @@ -4174,6 +4191,7 @@ Named capturing subpatterns: one 1 three 3 two 2 +May match empty string Options: anchored caseless No first char No need char @@ -4273,6 +4291,7 @@ Need char = 'z' /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/Is Capturing subpattern count = 31 +May match empty string Options: anchored dotall No first char No need char @@ -4280,6 +4299,7 @@ No need char /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/Is Capturing subpattern count = 31 Max back reference = 31 +May match empty string Options: dotall No first char No need char @@ -4287,6 +4307,7 @@ No need char /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/Is Capturing subpattern count = 32 Max back reference = 32 +May match empty string Options: dotall No first char No need char @@ -4363,7 +4384,7 @@ Minimum match() recursion limit = 6 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaz\M Minimum match() limit = 32768 -Minimum match() recursion limit = 42 +Minimum match() recursion limit = 29 No match /(aaa(?C1)bbb|ab)/I @@ -4438,6 +4459,7 @@ Capturing subpattern count = 2 Named capturing subpatterns: Tes 1 Test 2 +May match empty string No options No first char No need char @@ -4456,6 +4478,7 @@ Capturing subpattern count = 2 Named capturing subpatterns: Tes 2 Test 1 +May match empty string No options No first char No need char @@ -4533,6 +4556,7 @@ Need char = ']' End ------------------------------------------------------------------ Capturing subpattern count = 2 +May match empty string No options No first char No need char @@ -4553,6 +4577,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 2 +May match empty string No options No first char No need char @@ -4584,6 +4609,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 2 +May match empty string No options No first char No need char @@ -4591,9 +4617,7 @@ No need char /[ab]{1}+/DZ ------------------------------------------------------------------ Bra - Once - [ab]{1,1} - Ket + [ab]{1,1}+ Ket End ------------------------------------------------------------------ @@ -4617,7 +4641,7 @@ Options: caseless No first char Need char = 'g' (caseless) Subject length lower bound = 8 -No set of starting bytes +No starting char list Baby Bjorn Active Carrier - With free SHIPPING!! 0: Baby Bjorn Active Carrier - With free SHIPPING!! 1: Baby Bjorn Active Carrier - With free SHIPPING!! @@ -4636,7 +4660,7 @@ No options No first char Need char = 'b' Subject length lower bound = 1 -No set of starting bytes +No starting char list /(a|b)*.?c/ISDZ ------------------------------------------------------------------ @@ -4657,7 +4681,7 @@ No options No first char Need char = 'c' Subject length lower bound = 1 -No set of starting bytes +No starting char list /abc(?C255)de(?C)f/DZ ------------------------------------------------------------------ @@ -4730,7 +4754,7 @@ Options: No first char Need char = 'b' Subject length lower bound = 1 -Starting byte set: a b +Starting chars: a b ab --->ab +0 ^ a* @@ -4873,7 +4897,7 @@ Options: No first char Need char = 'x' Subject length lower bound = 4 -Starting byte set: a d +Starting chars: a d abcx --->abcx +0 ^ (abc|def) @@ -5107,7 +5131,7 @@ Options: No first char No need char Subject length lower bound = 2 -Starting byte set: a b x +Starting chars: a b x Note: that { does NOT introduce a quantifier --->Note: that { does NOT introduce a quantifier +0 ^ ([ab]{,4}c|xy) @@ -5305,7 +5329,7 @@ No match Callout 255 0 21 CBra 1 Callout 255 1 9 - [ab]{1,4} + [ab]{1,4}+ Callout 255 10 1 c Callout 255 11 0 @@ -5318,7 +5342,7 @@ No match Ket CBra 1 Callout 255 1 9 - [ab]{1,4} + [ab]{1,4}+ Callout 255 10 1 c Callout 255 11 0 @@ -5331,7 +5355,7 @@ No match Ket CBra 1 Callout 255 1 9 - [ab]{1,4} + [ab]{1,4}+ Callout 255 10 1 c Callout 255 11 0 @@ -5344,7 +5368,7 @@ No match Ket CBra 1 Callout 255 1 9 - [ab]{1,4} + [ab]{1,4}+ Callout 255 10 1 c Callout 255 11 0 @@ -5358,7 +5382,7 @@ No match Braminzero CBra 1 Callout 255 1 9 - [ab]{1,4} + [ab]{1,4}+ Callout 255 10 1 c Callout 255 11 0 @@ -5411,24 +5435,27 @@ Need char = '3' /\b.*/I Capturing subpattern count = 0 +Max lookbehind = 1 +May match empty string No options No first char No need char -Max lookbehind = 1 ab cd\>1 0: cd /\b.*/Is Capturing subpattern count = 0 +Max lookbehind = 1 +May match empty string Options: dotall No first char No need char -Max lookbehind = 1 ab cd\>1 0: cd /(?!.bcd).*/I Capturing subpattern count = 0 +May match empty string No options No first char No need char @@ -5584,7 +5611,7 @@ No options First char = 'a' Need char = 'c' Subject length lower bound = 3 -No set of starting bytes +No starting char list Compiled pattern written to testsavedregex Study data written to testsavedregex (?R))\)[^()]*)*/I Capturing subpattern count = 0 +May match empty string No options No first char No need char @@ -6039,6 +6068,7 @@ No need char /[^()]*(?:\((?R)\))*[^()]*/I Capturing subpattern count = 0 +May match empty string No options No first char No need char @@ -6049,6 +6079,7 @@ No need char /(?:\((?R)\))*[^()]*/I Capturing subpattern count = 0 +May match empty string No options No first char No need char @@ -6061,6 +6092,7 @@ No need char /(?:\((?R)\))|[^()]*/I Capturing subpattern count = 0 +May match empty string No options No first char No need char @@ -6110,6 +6142,17 @@ no parentheses with name "Z" 2: a1 copy substring Z failed -7 C a1 (2) A + +/(?|(?)(?)(?)|(?)(?)(?))/IJ +Capturing subpattern count = 3 +Named capturing subpatterns: + a 1 + a 3 + b 2 +May match empty string +Options: dupnames +No first char +No need char /^(?Pa)(?Pb)/IJ Capturing subpattern count = 2 @@ -6320,7 +6363,7 @@ Need char = 'X' 1: X /(?:(?(2y)a|b)(X))+/I -Failed: reference to non-existent subpattern at offset 9 +Failed: malformed number or name after (?( at offset 7 /(?:(?(ZA)a|b)(?PX))+/I Failed: reference to non-existent subpattern at offset 9 @@ -6392,9 +6435,9 @@ No options No first char Need char = ',' Subject length lower bound = 1 -Starting byte set: \x09 \x0a \x0c \x0d \x20 , +Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 , \x0b,\x0b - 0: , + 0: \x0b,\x0b \x0c,\x0d 0: \x0c,\x0d @@ -6503,7 +6546,7 @@ No match No match /^abc/Im -Unknown newline type at: +Unknown modifier at: /abc/I @@ -6512,12 +6555,13 @@ No options First char = 'a' Need char = 'c' xyz\rabc\ -Unknown newline type at: +Unknown escape sequence at: abc 0: abc /.*/I Capturing subpattern count = 0 +May match empty string Options: Forced newline sequence: LF First char at start or follows newline @@ -6559,6 +6603,7 @@ Need char = 'f' +((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)+I Capturing subpattern count = 1 +May match empty string No options No first char No need char @@ -6697,7 +6742,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: C a b c d +Starting chars: C a b c d /()[ab]xyz/IS Capturing subpattern count = 1 @@ -6705,7 +6750,7 @@ No options No first char Need char = 'z' Subject length lower bound = 4 -Starting byte set: a b +Starting chars: a b /(|)[ab]xyz/IS Capturing subpattern count = 1 @@ -6713,7 +6758,7 @@ No options No first char Need char = 'z' Subject length lower bound = 4 -Starting byte set: a b +Starting chars: a b /(|c)[ab]xyz/IS Capturing subpattern count = 1 @@ -6721,7 +6766,7 @@ No options No first char Need char = 'z' Subject length lower bound = 4 -Starting byte set: a b c +Starting chars: a b c /(|c?)[ab]xyz/IS Capturing subpattern count = 1 @@ -6729,7 +6774,7 @@ No options No first char Need char = 'z' Subject length lower bound = 4 -Starting byte set: a b c +Starting chars: a b c /(d?|c?)[ab]xyz/IS Capturing subpattern count = 1 @@ -6737,7 +6782,7 @@ No options No first char Need char = 'z' Subject length lower bound = 4 -Starting byte set: a b c d +Starting chars: a b c d /(d?|c)[ab]xyz/IS Capturing subpattern count = 1 @@ -6745,7 +6790,7 @@ No options No first char Need char = 'z' Subject length lower bound = 4 -Starting byte set: a b c d +Starting chars: a b c d /^a*b\d/DZ ------------------------------------------------------------------ @@ -6838,7 +6883,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: a b c d +Starting chars: a b c d /(a+|b*)[cd]/IS Capturing subpattern count = 1 @@ -6846,7 +6891,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: a b c d +Starting chars: a b c d /(a*|b+)[cd]/IS Capturing subpattern count = 1 @@ -6854,7 +6899,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: a b c d +Starting chars: a b c d /(a+|b+)[cd]/IS Capturing subpattern count = 1 @@ -6862,7 +6907,7 @@ No options No first char No need char Subject length lower bound = 2 -Starting byte set: a b +Starting chars: a b /(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( @@ -7482,7 +7527,7 @@ Matched, but too many substrings /a*[^a]/BZ ------------------------------------------------------------------ Bra - a* + a*+ [^a] Ket End @@ -7624,7 +7669,7 @@ No match ------------------------------------------------------------------ Bra ^ - [a-z]+ + [a-z]++ Ket End ------------------------------------------------------------------ @@ -7665,7 +7710,7 @@ No match ^ CBra 1 Cond - 2 Cond nref + 2 Cond ref y Ket [()] @@ -7725,6 +7770,7 @@ Named capturing subpatterns: one 1 three 3 two 2 +May match empty string Options: anchored caseless No first char No need char @@ -7824,15 +7870,9 @@ Failed: reference to non-existent subpattern at offset 7 1: abcabc1Xabc2XabcX 2: abcabc1Xabc2XabcX -/(? (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x +/(? (?'B' abc (?(R) (?(R&C)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x Failed: reference to non-existent subpattern at offset 29 -/(?<1> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x - abcabc1Xabc2XabcXabcabc - 0: abcabc1Xabc2XabcX - 1: abcabc1Xabc2XabcX - 2: abcabc1Xabc2XabcX - /^(?(DEFINE) abc | xyz ) /x Failed: DEFINE group contains more than one branch at offset 22 @@ -8056,7 +8096,7 @@ Failed: a numbered reference must not be zero at offset 8 /^(a)\g{3/ Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 8 -/^(a)\g{4a}/ +/^(a)\g{aa}/ Failed: reference to non-existent subpattern at offset 9 /^a.b/ @@ -8561,7 +8601,7 @@ No match \d \v++ \w - \v+ + \v++ \S \v++ \V @@ -8659,27 +8699,18 @@ No match +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) - +4 ^ ^ c+ - +2 ^ ^ b? - +4 ^ ^ c+ - +2 ^^ b? - +4 ^^ c+ +0 ^ a+ +2 ^ ^ b? +4 ^ ^ c+ +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) - +4 ^ ^ c+ - +2 ^^ b? - +4 ^^ c+ +0 ^ a+ +2 ^^ b? +4 ^ ^ c+ +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) +6 ^ ^ (*FAIL) - +4 ^^ c+ No match /a+b?(*PRUNE)c+(*FAIL)/C @@ -8803,7 +8834,7 @@ No match 1: \x0a /a(*CR)b/ -Failed: (*VERB) not recognized at offset 5 +Failed: (*VERB) not recognized or malformed at offset 5 /(*CR)a.b/ a\nb @@ -9248,8 +9279,28 @@ No match ab No match -/a(?!)+b/ -Failed: nothing to repeat at offset 5 +/a(?!)b/BZ +------------------------------------------------------------------ + Bra + a + *FAIL + b + Ket + End +------------------------------------------------------------------ + +/(?!)?a/BZ +------------------------------------------------------------------ + Bra + Brazero + Assert not + Ket + a + Ket + End +------------------------------------------------------------------ + ab + 0: a /a(*FAIL)+b/ Failed: nothing to repeat at offset 8 @@ -9260,10 +9311,11 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: x y z +Starting chars: x y z /(?(?=.*b)b|^)/CI Capturing subpattern count = 0 +May match empty string Options: No first char No need char @@ -9276,6 +9328,7 @@ No need char +7 ^ ^ b +7 ^^ b +7 ^ b ++11 ^ ^ +12 ^ ) +13 ^ 0: @@ -9367,7 +9420,7 @@ No match No match /(*NO_START_OPT)xyz/C - abcxyz + abcxyz --->abcxyz +15 ^ x +15 ^ x @@ -9377,6 +9430,15 @@ No match +17 ^ ^ z +18 ^ ^ 0: xyz + +/(*NO_AUTO_POSSESS)a+b/BZ +------------------------------------------------------------------ + Bra + a+ + b + Ket + End +------------------------------------------------------------------ /xyz/CY abcxyz @@ -9406,12 +9468,14 @@ No match +3 ^ ^ (?(?=[a])[^"]) +5 ^ ^ (?=[a]) +8 ^ ^ [a] ++17 ^ ^ | +21 ^ ^ " +18 ^ ^ b +19 ^ ^ ) +3 ^ ^ (?(?=[a])[^"]) +5 ^ ^ (?=[a]) +8 ^ ^ [a] ++17 ^ ^ | +21 ^ ^ " +22 ^ ^ $ +23 ^ ^ @@ -9719,17 +9783,17 @@ Partial match: abc12 xyzabc123pqr 0: 123 xyzabc12\P -Partial match: abc12 +Partial match at offset 6: abc12 xyzabc12\P\P -Partial match: abc12 +Partial match at offset 6: abc12 /\babc\b/ +++abc+++ 0: abc +++ab\P -Partial match: +ab +Partial match at offset 3: +ab +++ab\P\P -Partial match: +ab +Partial match at offset 3: +ab /(?&word)(?&element)(?(DEFINE)(?<[^m][^>]>[^<])(?\w*+))/BZ ------------------------------------------------------------------ @@ -10036,7 +10100,7 @@ No options No first char No need char Subject length lower bound = 2 -Starting byte set: a b +Starting chars: a b /(a|bc)\1{2,3}/SI Capturing subpattern count = 1 @@ -10045,7 +10109,7 @@ No options No first char No need char Subject length lower bound = 3 -Starting byte set: a b +Starting chars: a b /(a|bc)(?1)/SI Capturing subpattern count = 1 @@ -10053,7 +10117,7 @@ No options No first char No need char Subject length lower bound = 2 -Starting byte set: a b +Starting chars: a b /(a|b\1)(a|b\1)/SI Capturing subpattern count = 2 @@ -10062,7 +10126,7 @@ No options No first char No need char Subject length lower bound = 2 -Starting byte set: a b +Starting chars: a b /(a|b\1){2}/SI Capturing subpattern count = 1 @@ -10071,7 +10135,7 @@ No options No first char No need char Subject length lower bound = 2 -Starting byte set: a b +Starting chars: a b /(a|bbbb\1)(a|bbbb\1)/SI Capturing subpattern count = 2 @@ -10080,7 +10144,7 @@ No options No first char No need char Subject length lower bound = 2 -Starting byte set: a b +Starting chars: a b /(a|bbbb\1){2}/SI Capturing subpattern count = 1 @@ -10089,7 +10153,7 @@ No options No first char No need char Subject length lower bound = 2 -Starting byte set: a b +Starting chars: a b /^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 Capturing subpattern count = 1 @@ -10097,7 +10161,7 @@ Options: anchored No first char Need char = ':' Subject length lower bound = 22 -No set of starting bytes +No starting char list /]{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 @@ -10105,7 +10169,7 @@ Options: caseless dotall First char = '<' Need char = '>' Subject length lower bound = 47 -No set of starting bytes +No starting char list "(?>.*/)foo"SI Capturing subpattern count = 0 @@ -10113,7 +10177,7 @@ No options No first char Need char = 'o' Subject length lower bound = 4 -No set of starting bytes +No starting char list /(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /xSI Capturing subpattern count = 0 @@ -10121,7 +10185,7 @@ Options: extended No first char Need char = '-' Subject length lower bound = 8 -No set of starting bytes +No starting char list /(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/iSI Capturing subpattern count = 1 @@ -10129,7 +10193,7 @@ Options: caseless No first char No need char Subject length lower bound = 1 -Starting byte set: A B C a b c +Starting chars: A B C a b c /(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/SI Capturing subpattern count = 0 @@ -10137,7 +10201,7 @@ No options No first char Need char = 'b' Subject length lower bound = 41 -Starting byte set: c d +Starting chars: c d /A)|(?
    B))/I Capturing subpattern count = 1 Named capturing subpatterns: a 1 - a 1 No options No first char No need char @@ -10245,7 +10308,7 @@ No match Ket Ket Cond - 4 Cond nref + Cond ref 2 X Alt Y @@ -10291,7 +10354,7 @@ No match CBra 4 d Cond - Cond nrecurse 1 + Cond recurse 2 $ Alt Recurse @@ -10353,7 +10416,7 @@ Partial match: abca xxxxabcde\P\P Partial match: abcde -/-- This is not in the Perl >= 5.10 test because Perl seems currently to be +/-- This is not in the Perl-compatible test because Perl seems currently to be broken and not behaving as specified in that it *does* bumpalong after hitting (*COMMIT). --/ @@ -10391,7 +10454,7 @@ Options: No first char Need char = 'a' Subject length lower bound = 1 -No set of starting bytes +No starting char list cat 0: a 1: @@ -10405,7 +10468,7 @@ No options No first char Need char = 'a' Subject length lower bound = 3 -No set of starting bytes +No starting char list cat No match @@ -10417,7 +10480,7 @@ No options First char = 'i' No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list i 0: i @@ -10427,7 +10490,7 @@ No options No first char Need char = 'i' Subject length lower bound = 1 -Starting byte set: i +Starting chars: i ia 0: ia 1: @@ -10549,34 +10612,14 @@ No match End ------------------------------------------------------------------ -/ -- The first four of these are not in the Perl >= 5.10 test because Perl - documents that the use of \K in assertions is "not well defined". The - last is here because Perl gives the match as "b" rather than "ab". I +/ -- This one is here because Perl gives the match as "b" rather than "ab". I believe this to be a Perl bug. --/ -/(?=a\Kb)ab/ - ab - 0: b - -/(?!a\Kb)ac/ - ac - 0: ac - -/^abc(?<=b\Kc)d/ - abcd - 0: cd - -/^abc(?a\Kb)z|(ab)/ ab 0: ab 1: ab -/----------------------/ - /(?P(?P0|)|(?P>L2)(?P>L1))/ Failed: recursive call could loop indefinitely at offset 31 @@ -10596,7 +10639,7 @@ Failed: an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) at offse ACABX No match -/--- These should be different, but in Perl 5.11 are not, which I think +/--- These should be different, but in Perl they are not, which I think is a bug in Perl. ---/ /A(*THEN)B|A(*THEN)C/K @@ -10607,13 +10650,6 @@ No match AC No match -/--- This should fail; the SKIP advances by one, but when we get to AC, the - PRUNE kills it. Perl behaves differently. ---/ - -/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK - AAAC -No match, mark = A - /--- Mark names can be duplicated. Perl doesn't give a mark for this one, though PCRE does. ---/ @@ -10647,7 +10683,7 @@ No match abcccd No match -/--- Perl 5.11 gets some of these wrong ---/ +/--- Perl gets some of these wrong ---/ /(?>.(*ACCEPT))*?5/ abcde @@ -10826,21 +10862,9 @@ No match X\x0d\x0a No match -/-- Perl treats this one differently, not failing the second string. I believe - that is a bug in Perl. --/ - -/^((abc|abcx)(*THEN)y|abcd)/ - abcd - 0: abcd - 1: abcd - *** Failers -No match - abcxy -No match - /(?<=abc)def/ abc\P\P -Partial match: abc +Partial match at offset 3: abc /abc$/ abc @@ -11060,7 +11084,7 @@ No options First char = 'a' Need char = '4' Subject length lower bound = 5 -No set of starting bytes +No starting char list /([abc])++1234/SI Capturing subpattern count = 1 @@ -11068,7 +11092,7 @@ No options No first char Need char = '4' Subject length lower bound = 5 -Starting byte set: a b c +Starting chars: a b c /(?<=(abc)+)X/ Failed: lookbehind assertion is not fixed length at offset 10 @@ -11087,12 +11111,14 @@ No need char /(^ab|^)+/I Capturing subpattern count = 1 +May match empty string Options: anchored No first char No need char /(^ab|^)++/I Capturing subpattern count = 1 +May match empty string Options: anchored No first char No need char @@ -11111,12 +11137,14 @@ No need char /(?:^ab|^)+/I Capturing subpattern count = 0 +May match empty string Options: anchored No first char No need char /(?:^ab|^)++/I Capturing subpattern count = 0 +May match empty string Options: anchored No first char No need char @@ -11135,12 +11163,14 @@ Need char = 'b' /(.*ab|.*)+/I Capturing subpattern count = 1 +May match empty string No options First char at start or follows newline No need char /(.*ab|.*)++/I Capturing subpattern count = 1 +May match empty string No options First char at start or follows newline No need char @@ -11159,12 +11189,14 @@ Need char = 'b' /(?:.*ab|.*)+/I Capturing subpattern count = 0 +May match empty string No options First char at start or follows newline No need char /(?:.*ab|.*)++/I Capturing subpattern count = 0 +May match empty string No options First char at start or follows newline No need char @@ -11319,7 +11351,6 @@ No match /(a)b|ac/++SS ac\O3 -Matched, but too many substrings 0: ac 0+ @@ -11342,7 +11373,7 @@ No options No first char No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list /(a(?2)|b)(b(?1)|a)(?:(?1)|(?2))/SI Capturing subpattern count = 2 @@ -11350,7 +11381,7 @@ No options No first char No need char Subject length lower bound = 3 -Starting byte set: a b +Starting chars: a b /(a(?2)|b)(b(?1)|a)(?1)(?2)/SI Capturing subpattern count = 2 @@ -11358,7 +11389,7 @@ No options No first char No need char Subject length lower bound = 4 -Starting byte set: a b +Starting chars: a b /(abc)(?1)/SI Capturing subpattern count = 1 @@ -11366,7 +11397,7 @@ No options First char = 'a' Need char = 'c' Subject length lower bound = 6 -No set of starting bytes +No starting char list /^(?>a)++/ aa\M @@ -11571,7 +11602,7 @@ Matched, but too many substrings Assert not a Ket - \w+ + \w++ Ket End ------------------------------------------------------------------ @@ -11679,28 +11710,30 @@ No match /\btype\b\W*?\btext\b\W*?\bjavascript\b/IS Capturing subpattern count = 0 +Max lookbehind = 1 No options First char = 't' Need char = 't' -Max lookbehind = 1 Subject length lower bound = 18 -No set of starting bytes +No starting char list /\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|a+)(?>(z+))\w/BZ ------------------------------------------------------------------ Bra ^ Once_NC - a+ + a++ Ket Once CBra 1 - z+ + z++ Ket Ket \w @@ -11888,14 +11862,14 @@ No match /^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/ \Maabbccddee -Minimum match() limit = 12 -Minimum match() recursion limit = 3 +Minimum match() limit = 7 +Minimum match() recursion limit = 2 0: aabbccddee /^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/ \Maabbccddee -Minimum match() limit = 22 -Minimum match() recursion limit = 21 +Minimum match() limit = 17 +Minimum match() recursion limit = 16 0: aabbccddee 1: aa 2: bb @@ -11905,8 +11879,8 @@ Minimum match() recursion limit = 21 /^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/ \Maabbccddee -Minimum match() limit = 18 -Minimum match() recursion limit = 13 +Minimum match() limit = 13 +Minimum match() recursion limit = 10 0: aabbccddee 1: aa 2: cc @@ -11997,7 +11971,10 @@ No match Failed: \N is not supported in a class at offset 3 /a[B-\Nc]/ -Failed: \N is not supported in a class at offset 5 +Failed: invalid range in character class at offset 5 + +/a[B\Nc]/ +Failed: \N is not supported in a class at offset 4 /(a)(?2){0,1999}?(b)/ @@ -12336,47 +12313,27 @@ Partial match: \x0d\x0d \r\r\r\P\P 0: \x0d\x0d -/-- These two are here because Perl does not match: it seems to allow the -COMMIT to escape from the assertion. --/ - -/(?=a(*COMMIT)b|ac)ac|ac/ - ac - 0: ac - -/(?=a(*COMMIT)b|(ac)) ac | (a)c/x - ac - 0: ac - 1: - 2: a - "AB(C(D))(E(F))?(?(?=\2)(?=\4))" ABCDGHI\O03 Matched, but too many substrings 0: ABCD -/-- This one is here because Perl does not confine the *COMMIT to the -assertion, and therefore fails the entire subroutine call. --/ - -/((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/ - ac - 0: ac - /-- These are all run as real matches in test 1; here we are just checking the settings of the anchored and startline bits. --/ /(?>.*?a)(?<=ba)/I Capturing subpattern count = 0 +Max lookbehind = 2 No options No first char Need char = 'a' -Max lookbehind = 2 /(?:.*?a)(?<=ba)/I Capturing subpattern count = 0 +Max lookbehind = 2 No options First char at start or follows newline Need char = 'a' -Max lookbehind = 2 /.*?a(*PRUNE)b/I Capturing subpattern count = 0 @@ -12422,17 +12379,19 @@ No need char /(?>.*?)(?<=(abcd)|(wxyz))/I Capturing subpattern count = 2 +Max lookbehind = 4 +May match empty string No options No first char No need char -Max lookbehind = 4 /(?>.*)(?<=(abcd)|(wxyz))/I Capturing subpattern count = 2 +Max lookbehind = 4 +May match empty string No options No first char No need char -Max lookbehind = 4 "(?>.*)foo"I Capturing subpattern count = 0 @@ -12468,6 +12427,7 @@ Need char = 'c' /.?/S-I Capturing subpattern count = 0 +May match empty string No options No first char No need char @@ -12475,10 +12435,1718 @@ Study returned NULL /.?/S!I Capturing subpattern count = 0 +May match empty string No options No first char No need char Subject length lower bound = -1 -No set of starting bytes +No starting char list + +/(?:(a)+(?C1)bb|aa(?C2)b)/ + aab\C+ +Callout 1: last capture = 1 + 0: + 1: a +--->aab + ^ ^ b +Callout 1: last capture = 1 + 0: + 1: a +--->aab + ^^ b +Callout 2: last capture = -1 + 0: +--->aab + ^ ^ b + 0: aab + +/(?:(a)++(?C1)bb|aa(?C2)b)/ + aab\C+ +Callout 1: last capture = 1 + 0: + 1: a +--->aab + ^ ^ b +Callout 2: last capture = -1 + 0: +--->aab + ^ ^ b + 0: aab + +/(?:(?>(a))(?C1)bb|aa(?C2)b)/ + aab\C+ +Callout 1: last capture = 1 + 0: + 1: a +--->aab + ^^ b +Callout 2: last capture = -1 + 0: +--->aab + ^ ^ b + 0: aab + +/(?:(?1)(?C1)x|ab(?C2))((a)){0}/ + aab\C+ +Callout 1: last capture = -1 + 0: +--->aab + ^^ x +Callout 1: last capture = -1 + 0: +--->aab + ^^ x +Callout 2: last capture = -1 + 0: +--->aab + ^ ^ ) + 0: ab + +/(?1)(?C1)((a)(?C2)){0}/ + aab\C+ +Callout 2: last capture = 2 + 0: + 1: + 2: a +--->aab + ^^ ) +Callout 1: last capture = -1 + 0: +--->aab + ^^ ((a)(?C2)){0} + 0: a + +/(?:(a)+(?C1)bb|aa(?C2)b)++/ + aab\C+ +Callout 1: last capture = 1 + 0: + 1: a +--->aab + ^ ^ b +Callout 1: last capture = 1 + 0: + 1: a +--->aab + ^^ b +Callout 2: last capture = -1 + 0: +--->aab + ^ ^ b + 0: aab + aab\C+\O2 +Callout 1: last capture = 1 + 0: +--->aab + ^ ^ b +Callout 1: last capture = 1 + 0: +--->aab + ^^ b +Callout 2: last capture = -1 + 0: +--->aab + ^ ^ b + 0: aab + +/(ab)x|ab/ + ab\O3 + 0: ab + ab\O2 + 0: ab + +/(ab)/ + ab\O3 +Matched, but too many substrings + 0: ab + ab\O2 +Matched, but too many substrings + 0: ab + +/(?<=123)(*MARK:xx)abc/K + xxxx123a\P\P +Partial match at offset 7, mark=xx: 123a + xxxx123a\P +Partial match at offset 7, mark=xx: 123a + +/123\Kabc/ + xxxx123a\P\P +Partial match: 123a + xxxx123a\P +Partial match: 123a + +/^(?(?=a)aa|bb)/C + bb +--->bb + +0 ^ ^ + +1 ^ (?(?=a)aa|bb) + +3 ^ (?=a) + +6 ^ a ++11 ^ b ++12 ^^ b ++13 ^ ^ ) ++14 ^ ^ + 0: bb + +/(?C1)^(?C2)(?(?C99)(?=(?C3)a(?C4))(?C5)a(?C6)a(?C7)|(?C8)b(?C9)b(?C10))(?C11)/ + bb +--->bb + 1 ^ ^ + 2 ^ (?(?C99)(?=(?C3)a(?C4))(?C5)a(?C6)a(?C7)|(?C8)b(?C9)b(?C10)) + 99 ^ (?=(?C3)a(?C4)) + 3 ^ a + 8 ^ b + 9 ^^ b + 10 ^ ^ ) + 11 ^ ^ + 0: bb + +/-- Perl seems to have a bug with this one --/ + +/aaaaa(*COMMIT)(*PRUNE)b|a+c/ + aaaaaac + 0: aaaac + +/-- Here are some that Perl treats differently because of the way it handles +backtracking verbs. --/ + + /(?!a(*COMMIT)b)ac|ad/ + ac + 0: ac + ad + 0: ad + +/^(?!a(*THEN)b|ac)../ + ac +No match + ad + 0: ad + +/^(?=a(*THEN)b|ac)/ + ac + 0: + +/\A.*?(?:a|b(*THEN)c)/ + ba + 0: ba + +/\A.*?(?:a|b(*THEN)c)++/ + ba + 0: ba + +/\A.*?(?:a|b(*THEN)c|d)/ + ba + 0: ba + +/(?:(a(*MARK:X)a+(*SKIP:X)b)){0}(?:(?1)|aac)/ + aac + 0: aac + +/\A.*?(a|b(*THEN)c)/ + ba + 0: ba + 1: a + +/^(A(*THEN)B|A(*THEN)D)/ + AD + 0: AD + 1: AD + +/(?!b(*THEN)a)bn|bnn/ + bnn + 0: bn + +/(?(?=b(*SKIP)a)bn|bnn)/ + bnn +No match + +/(?=b(*THEN)a|)bn|bnn/ + bnn + 0: bn + +/-------------------------/ + +/(*LIMIT_MATCH=12bc)abc/ +Failed: (*VERB) not recognized or malformed at offset 7 + +/(*LIMIT_MATCH=4294967290)abc/ +Failed: (*VERB) not recognized or malformed at offset 7 + +/(*LIMIT_RECURSION=4294967280)abc/I +Capturing subpattern count = 0 +Recursion limit = 4294967280 +No options +First char = 'a' +Need char = 'c' + +/(a+)*zz/ + aaaaaaaaaaaaaz +No match + aaaaaaaaaaaaaz\q3000 +Error -8 (match limit exceeded) + +/(a+)*zz/S- + aaaaaaaaaaaaaz\Q10 +Error -21 (recursion limit exceeded) + +/(*LIMIT_MATCH=3000)(a+)*zz/I +Capturing subpattern count = 1 +Match limit = 3000 +No options +No first char +Need char = 'z' + aaaaaaaaaaaaaz +Error -8 (match limit exceeded) + aaaaaaaaaaaaaz\q60000 +Error -8 (match limit exceeded) + +/(*LIMIT_MATCH=60000)(*LIMIT_MATCH=3000)(a+)*zz/I +Capturing subpattern count = 1 +Match limit = 3000 +No options +No first char +Need char = 'z' + aaaaaaaaaaaaaz +Error -8 (match limit exceeded) + +/(*LIMIT_MATCH=60000)(a+)*zz/I +Capturing subpattern count = 1 +Match limit = 60000 +No options +No first char +Need char = 'z' + aaaaaaaaaaaaaz +No match + aaaaaaaaaaaaaz\q3000 +Error -8 (match limit exceeded) + +/(*LIMIT_RECURSION=10)(a+)*zz/IS- +Capturing subpattern count = 1 +Recursion limit = 10 +No options +No first char +Need char = 'z' +Subject length lower bound = 2 +Starting chars: a z + aaaaaaaaaaaaaz +Error -21 (recursion limit exceeded) + aaaaaaaaaaaaaz\Q1000 +Error -21 (recursion limit exceeded) + +/(*LIMIT_RECURSION=10)(*LIMIT_RECURSION=1000)(a+)*zz/IS- +Capturing subpattern count = 1 +Recursion limit = 10 +No options +No first char +Need char = 'z' +Subject length lower bound = 2 +Starting chars: a z + aaaaaaaaaaaaaz +Error -21 (recursion limit exceeded) + +/(*LIMIT_RECURSION=1000)(a+)*zz/IS- +Capturing subpattern count = 1 +Recursion limit = 1000 +No options +No first char +Need char = 'z' +Subject length lower bound = 2 +Starting chars: a z + aaaaaaaaaaaaaz +No match + aaaaaaaaaaaaaz\Q10 +Error -21 (recursion limit exceeded) + +/-- This test causes a segfault with Perl 5.18.0 --/ + +/^(?=(a)){0}b(?1)/ + backgammon + 0: ba + +/(?|(?f)|(?b))/JI +Capturing subpattern count = 1 +Named capturing subpatterns: + n 1 +Options: dupnames +No first char +No need char + +/(?abc)(?z)\k()/JDZS +------------------------------------------------------------------ + Bra + CBra 1 + abc + Ket + CBra 2 + z + Ket + \k2 + CBra 3 + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 3 +Max back reference = 2 +Named capturing subpatterns: + a 1 + a 2 +Options: dupnames +First char = 'a' +Need char = 'z' +Subject length lower bound = 5 +No starting char list + +/a*[bcd]/BZ +------------------------------------------------------------------ + Bra + a*+ + [b-d] + Ket + End +------------------------------------------------------------------ + +/[bcd]*a/BZ +------------------------------------------------------------------ + Bra + [b-d]*+ + a + Ket + End +------------------------------------------------------------------ + +/-- A complete set of tests for auto-possessification of character types --/ + +/\D+\D \D+\d \D+\S \D+\s \D+\W \D+\w \D+. \D+\C \D+\R \D+\H \D+\h \D+\V \D+\v \D+\Z \D+\z \D+$/BZx +------------------------------------------------------------------ + Bra + \D+ + \D + \D++ + \d + \D+ + \S + \D+ + \s + \D+ + \W + \D+ + \w + \D+ + Any + \D+ + AllAny + \D+ + \R + \D+ + \H + \D+ + \h + \D+ + \V + \D+ + \v + \D+ + \Z + \D++ + \z + \D+ + $ + Ket + End +------------------------------------------------------------------ + +/\d+\D \d+\d \d+\S \d+\s \d+\W \d+\w \d+. \d+\C \d+\R \d+\H \d+\h \d+\V \d+\v \d+\Z \d+\z \d+$/BZx +------------------------------------------------------------------ + Bra + \d++ + \D + \d+ + \d + \d+ + \S + \d++ + \s + \d++ + \W + \d+ + \w + \d+ + Any + \d+ + AllAny + \d++ + \R + \d+ + \H + \d++ + \h + \d+ + \V + \d++ + \v + \d++ + \Z + \d++ + \z + \d++ + $ + Ket + End +------------------------------------------------------------------ + +/\S+\D \S+\d \S+\S \S+\s \S+\W \S+\w \S+. \S+\C \S+\R \S+\H \S+\h \S+\V \S+\v \S+\Z \S+\z \S+$/BZx +------------------------------------------------------------------ + Bra + \S+ + \D + \S+ + \d + \S+ + \S + \S++ + \s + \S+ + \W + \S+ + \w + \S+ + Any + \S+ + AllAny + \S++ + \R + \S+ + \H + \S++ + \h + \S+ + \V + \S++ + \v + \S++ + \Z + \S++ + \z + \S++ + $ + Ket + End +------------------------------------------------------------------ + +/\s+\D \s+\d \s+\S \s+\s \s+\W \s+\w \s+. \s+\C \s+\R \s+\H \s+\h \s+\V \s+\v \s+\Z \s+\z \s+$/BZx +------------------------------------------------------------------ + Bra + \s+ + \D + \s++ + \d + \s++ + \S + \s+ + \s + \s+ + \W + \s++ + \w + \s+ + Any + \s+ + AllAny + \s+ + \R + \s+ + \H + \s+ + \h + \s+ + \V + \s+ + \v + \s+ + \Z + \s++ + \z + \s+ + $ + Ket + End +------------------------------------------------------------------ + +/\W+\D \W+\d \W+\S \W+\s \W+\W \W+\w \W+. \W+\C \W+\R \W+\H \W+\h \W+\V \W+\v \W+\Z \W+\z \W+$/BZx +------------------------------------------------------------------ + Bra + \W+ + \D + \W++ + \d + \W+ + \S + \W+ + \s + \W+ + \W + \W++ + \w + \W+ + Any + \W+ + AllAny + \W+ + \R + \W+ + \H + \W+ + \h + \W+ + \V + \W+ + \v + \W+ + \Z + \W++ + \z + \W+ + $ + Ket + End +------------------------------------------------------------------ + +/\w+\D \w+\d \w+\S \w+\s \w+\W \w+\w \w+. \w+\C \w+\R \w+\H \w+\h \w+\V \w+\v \w+\Z \w+\z \w+$/BZx +------------------------------------------------------------------ + Bra + \w+ + \D + \w+ + \d + \w+ + \S + \w++ + \s + \w++ + \W + \w+ + \w + \w+ + Any + \w+ + AllAny + \w++ + \R + \w+ + \H + \w++ + \h + \w+ + \V + \w++ + \v + \w++ + \Z + \w++ + \z + \w++ + $ + Ket + End +------------------------------------------------------------------ + +/\C+\D \C+\d \C+\S \C+\s \C+\W \C+\w \C+. \C+\C \C+\R \C+\H \C+\h \C+\V \C+\v \C+\Z \C+\z \C+$/BZx +------------------------------------------------------------------ + Bra + AllAny+ + \D + AllAny+ + \d + AllAny+ + \S + AllAny+ + \s + AllAny+ + \W + AllAny+ + \w + AllAny+ + Any + AllAny+ + AllAny + AllAny+ + \R + AllAny+ + \H + AllAny+ + \h + AllAny+ + \V + AllAny+ + \v + AllAny+ + \Z + AllAny++ + \z + AllAny+ + $ + Ket + End +------------------------------------------------------------------ + +/\R+\D \R+\d \R+\S \R+\s \R+\W \R+\w \R+. \R+\C \R+\R \R+\H \R+\h \R+\V \R+\v \R+\Z \R+\z \R+$/BZx +------------------------------------------------------------------ + Bra + \R+ + \D + \R++ + \d + \R+ + \S + \R++ + \s + \R+ + \W + \R++ + \w + \R++ + Any + \R+ + AllAny + \R+ + \R + \R+ + \H + \R++ + \h + \R+ + \V + \R+ + \v + \R+ + \Z + \R++ + \z + \R+ + $ + Ket + End +------------------------------------------------------------------ + +/\H+\D \H+\d \H+\S \H+\s \H+\W \H+\w \H+. \H+\C \H+\R \H+\H \H+\h \H+\V \H+\v \H+\Z \H+\z \H+$/BZx +------------------------------------------------------------------ + Bra + \H+ + \D + \H+ + \d + \H+ + \S + \H+ + \s + \H+ + \W + \H+ + \w + \H+ + Any + \H+ + AllAny + \H+ + \R + \H+ + \H + \H++ + \h + \H+ + \V + \H+ + \v + \H+ + \Z + \H++ + \z + \H+ + $ + Ket + End +------------------------------------------------------------------ + +/\h+\D \h+\d \h+\S \h+\s \h+\W \h+\w \h+. \h+\C \h+\R \h+\H \h+\h \h+\V \h+\v \h+\Z \h+\z \h+$/BZx +------------------------------------------------------------------ + Bra + \h+ + \D + \h++ + \d + \h++ + \S + \h+ + \s + \h+ + \W + \h++ + \w + \h+ + Any + \h+ + AllAny + \h++ + \R + \h++ + \H + \h+ + \h + \h+ + \V + \h++ + \v + \h+ + \Z + \h++ + \z + \h+ + $ + Ket + End +------------------------------------------------------------------ + +/\V+\D \V+\d \V+\S \V+\s \V+\W \V+\w \V+. \V+\C \V+\R \V+\H \V+\h \V+\V \V+\v \V+\Z \V+\z \V+$/BZx +------------------------------------------------------------------ + Bra + \V+ + \D + \V+ + \d + \V+ + \S + \V+ + \s + \V+ + \W + \V+ + \w + \V+ + Any + \V+ + AllAny + \V++ + \R + \V+ + \H + \V+ + \h + \V+ + \V + \V++ + \v + \V+ + \Z + \V++ + \z + \V+ + $ + Ket + End +------------------------------------------------------------------ + +/\v+\D \v+\d \v+\S \v+\s \v+\W \v+\w \v+. \v+\C \v+\R \v+\H \v+\h \v+\V \v+\v \v+\Z \v+\z \v+$/BZx +------------------------------------------------------------------ + Bra + \v+ + \D + \v++ + \d + \v++ + \S + \v+ + \s + \v+ + \W + \v++ + \w + \v+ + Any + \v+ + AllAny + \v+ + \R + \v+ + \H + \v++ + \h + \v++ + \V + \v+ + \v + \v+ + \Z + \v++ + \z + \v+ + $ + Ket + End +------------------------------------------------------------------ + +/ a+\D a+\d a+\S a+\s a+\W a+\w a+. a+\C a+\R a+\H a+\h a+\V a+\v a+\Z a+\z a+$/BZx +------------------------------------------------------------------ + Bra + a+ + \D + a++ + \d + a+ + \S + a++ + \s + a++ + \W + a+ + \w + a+ + Any + a+ + AllAny + a++ + \R + a+ + \H + a++ + \h + a+ + \V + a++ + \v + a++ + \Z + a++ + \z + a++ + $ + Ket + End +------------------------------------------------------------------ + +/\n+\D \n+\d \n+\S \n+\s \n+\W \n+\w \n+. \n+\C \n+\R \n+\H \n+\h \n+\V \n+\v \n+\Z \n+\z \n+$/BZx +------------------------------------------------------------------ + Bra + \x0a+ + \D + \x0a++ + \d + \x0a++ + \S + \x0a+ + \s + \x0a+ + \W + \x0a++ + \w + \x0a+ + Any + \x0a+ + AllAny + \x0a+ + \R + \x0a+ + \H + \x0a++ + \h + \x0a++ + \V + \x0a+ + \v + \x0a+ + \Z + \x0a++ + \z + \x0a+ + $ + Ket + End +------------------------------------------------------------------ + +/ .+\D .+\d .+\S .+\s .+\W .+\w .+. .+\C .+\R .+\H .+\h .+\V .+\v .+\Z .+\z .+$/BZx +------------------------------------------------------------------ + Bra + Any+ + \D + Any+ + \d + Any+ + \S + Any+ + \s + Any+ + \W + Any+ + \w + Any+ + Any + Any+ + AllAny + Any++ + \R + Any+ + \H + Any+ + \h + Any+ + \V + Any+ + \v + Any+ + \Z + Any++ + \z + Any+ + $ + Ket + End +------------------------------------------------------------------ + +/ .+\D .+\d .+\S .+\s .+\W .+\w .+. .+\C .+\R .+\H .+\h .+\V .+\v .+\Z .+\z .+$/BZxs +------------------------------------------------------------------ + Bra + AllAny+ + \D + AllAny+ + \d + AllAny+ + \S + AllAny+ + \s + AllAny+ + \W + AllAny+ + \w + AllAny+ + AllAny + AllAny+ + AllAny + AllAny+ + \R + AllAny+ + \H + AllAny+ + \h + AllAny+ + \V + AllAny+ + \v + AllAny+ + \Z + AllAny++ + \z + AllAny+ + $ + Ket + End +------------------------------------------------------------------ + +/\D+$ \d+$ \S+$ \s+$ \W+$ \w+$ \C+$ \R+$ \H+$ \h+$ \V+$ \v+$ a+$ \n+$ .+$ .+$/BZxm +------------------------------------------------------------------ + Bra + \D+ + /m $ + \d++ + /m $ + \S++ + /m $ + \s+ + /m $ + \W+ + /m $ + \w++ + /m $ + AllAny+ + /m $ + \R+ + /m $ + \H+ + /m $ + \h+ + /m $ + \V+ + /m $ + \v+ + /m $ + a+ + /m $ + \x0a+ + /m $ + Any+ + /m $ + Any+ + /m $ + Ket + End +------------------------------------------------------------------ + +/(?=a+)a(a+)++a/BZ +------------------------------------------------------------------ + Bra + Assert + a++ + Ket + a + CBraPos 1 + a++ + KetRpos + a + Ket + End +------------------------------------------------------------------ + +/a+(bb|cc)a+(?:bb|cc)a+(?>bb|cc)a+(?:bb|cc)+a+(aa)a+(?:bb|aa)/BZ +------------------------------------------------------------------ + Bra + a++ + CBra 1 + bb + Alt + cc + Ket + a++ + Bra + bb + Alt + cc + Ket + a++ + Once_NC + bb + Alt + cc + Ket + a++ + Bra + bb + Alt + cc + KetRmax + a+ + CBra 2 + aa + Ket + a+ + Bra + bb + Alt + aa + Ket + Ket + End +------------------------------------------------------------------ + +/a+(bb|cc)?#a+(?:bb|cc)??#a+(?:bb|cc)?+#a+(?:bb|cc)*#a+(bb|cc)?a#a+(?:aa)?/BZ +------------------------------------------------------------------ + Bra + a++ + Brazero + CBra 1 + bb + Alt + cc + Ket + # + a++ + Braminzero + Bra + bb + Alt + cc + Ket + # + a++ + Once + Brazero + Bra + bb + Alt + cc + Ket + Ket + # + a++ + Brazero + Bra + bb + Alt + cc + KetRmax + # + a+ + Brazero + CBra 2 + bb + Alt + cc + Ket + a# + a+ + Brazero + Bra + aa + Ket + Ket + End +------------------------------------------------------------------ + +/a+(?:bb)?a#a+(?:|||)#a+(?:|b)a#a+(?:|||)?a/BZ +------------------------------------------------------------------ + Bra + a+ + Brazero + Bra + bb + Ket + a# + a++ + Bra + Alt + Alt + Alt + Ket + # + a+ + Bra + Alt + b + Ket + a# + a+ + Brazero + Bra + Alt + Alt + Alt + Ket + a + Ket + End +------------------------------------------------------------------ + +/[ab]*/BZ +------------------------------------------------------------------ + Bra + [ab]*+ + Ket + End +------------------------------------------------------------------ + aaaa + 0: aaaa + +/[ab]*?/BZ +------------------------------------------------------------------ + Bra + [ab]*? + Ket + End +------------------------------------------------------------------ + aaaa + 0: + +/[ab]?/BZ +------------------------------------------------------------------ + Bra + [ab]?+ + Ket + End +------------------------------------------------------------------ + aaaa + 0: a + +/[ab]??/BZ +------------------------------------------------------------------ + Bra + [ab]?? + Ket + End +------------------------------------------------------------------ + aaaa + 0: + +/[ab]+/BZ +------------------------------------------------------------------ + Bra + [ab]++ + Ket + End +------------------------------------------------------------------ + aaaa + 0: aaaa + +/[ab]+?/BZ +------------------------------------------------------------------ + Bra + [ab]+? + Ket + End +------------------------------------------------------------------ + aaaa + 0: a + +/[ab]{2,3}/BZ +------------------------------------------------------------------ + Bra + [ab]{2,3}+ + Ket + End +------------------------------------------------------------------ + aaaa + 0: aaa + +/[ab]{2,3}?/BZ +------------------------------------------------------------------ + Bra + [ab]{2,3}? + Ket + End +------------------------------------------------------------------ + aaaa + 0: aa + +/[ab]{2,}/BZ +------------------------------------------------------------------ + Bra + [ab]{2,}+ + Ket + End +------------------------------------------------------------------ + aaaa + 0: aaaa + +/[ab]{2,}?/BZ +------------------------------------------------------------------ + Bra + [ab]{2,}? + Ket + End +------------------------------------------------------------------ + aaaa + 0: aa + +/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/BZ +------------------------------------------------------------------ + Bra + \d++ + \s{0,5}+ + = + \s*+ + \S? + = + \w{0,4}+ + \W*+ + Ket + End +------------------------------------------------------------------ + +/[a-d]{5,12}[e-z0-9]*#[^a-z]+[b-y]*a[2-7]?[^0-9a-z]+/BZ +------------------------------------------------------------------ + Bra + [a-d]{5,12}+ + [0-9e-z]*+ + # + [\x00-`{-\xff] (neg)++ + [b-y]*+ + a + [2-7]?+ + [\x00-/:-`{-\xff] (neg)++ + Ket + End +------------------------------------------------------------------ + +/[a-z]*\s#[ \t]?\S#[a-c]*\S#[C-G]+?\d#[4-8]*\D#[4-9,]*\D#[!$]{0,5}\w#[M-Xf-l]+\W#[a-c,]?\W/BZ +------------------------------------------------------------------ + Bra + [a-z]*+ + \s + # + [\x09 ]?+ + \S + # + [a-c]* + \S + # + [C-G]++ + \d + # + [4-8]*+ + \D + # + [,4-9]* + \D + # + [!$]{0,5}+ + \w + # + [M-Xf-l]++ + \W + # + [,a-c]? + \W + Ket + End +------------------------------------------------------------------ + +/a+(aa|bb)*c#a*(bb|cc)*a#a?(bb|cc)*d#[a-f]*(g|hh)*f/BZ +------------------------------------------------------------------ + Bra + a+ + Brazero + CBra 1 + aa + Alt + bb + KetRmax + c# + a* + Brazero + CBra 2 + bb + Alt + cc + KetRmax + a# + a?+ + Brazero + CBra 3 + bb + Alt + cc + KetRmax + d# + [a-f]* + Brazero + CBra 4 + g + Alt + hh + KetRmax + f + Ket + End +------------------------------------------------------------------ + +/[a-f]*(g|hh|i)*i#[a-x]{4,}(y{0,6})*y#[a-k]+(ll|mm)+n/BZ +------------------------------------------------------------------ + Bra + [a-f]*+ + Brazero + CBra 1 + g + Alt + hh + Alt + i + KetRmax + i# + [a-x]{4,} + Brazero + SCBra 2 + y{0,6} + KetRmax + y# + [a-k]++ + CBra 3 + ll + Alt + mm + KetRmax + n + Ket + End +------------------------------------------------------------------ + +/[a-f]*(?>gg|hh)+#[a-f]*(?>gg|hh)?#[a-f]*(?>gg|hh)*a#[a-f]*(?>gg|hh)*h/BZ +------------------------------------------------------------------ + Bra + [a-f]*+ + Once_NC + gg + Alt + hh + KetRmax + # + [a-f]*+ + Brazero + Once_NC + gg + Alt + hh + Ket + # + [a-f]* + Brazero + Once_NC + gg + Alt + hh + KetRmax + a# + [a-f]*+ + Brazero + Once_NC + gg + Alt + hh + KetRmax + h + Ket + End +------------------------------------------------------------------ + +/[a-c]*d/DZS +------------------------------------------------------------------ + Bra + [a-c]*+ + d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +Need char = 'd' +Subject length lower bound = 1 +Starting chars: a b c d + +/[a-c]+d/DZS +------------------------------------------------------------------ + Bra + [a-c]++ + d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +Need char = 'd' +Subject length lower bound = 2 +Starting chars: a b c + +/[a-c]?d/DZS +------------------------------------------------------------------ + Bra + [a-c]?+ + d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +Need char = 'd' +Subject length lower bound = 1 +Starting chars: a b c d + +/[a-c]{4,6}d/DZS +------------------------------------------------------------------ + Bra + [a-c]{4,6}+ + d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +Need char = 'd' +Subject length lower bound = 5 +Starting chars: a b c + +/[a-c]{0,6}d/DZS +------------------------------------------------------------------ + Bra + [a-c]{0,6}+ + d + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +Need char = 'd' +Subject length lower bound = 1 +Starting chars: a b c d + +/-- End of special auto-possessive tests --/ + +/^A\o{1239}B/ +Failed: non-octal character in \o{} (closing brace missing?) at offset 8 + +/^A\oB/ +Failed: missing opening brace after \o at offset 3 + +/^A\x{zz}B/ +Failed: non-hex character in \x{} (closing brace missing?) at offset 5 + +/^A\x{12Z/ +Failed: non-hex character in \x{} (closing brace missing?) at offset 7 + +/^A\x{/ +Failed: non-hex character in \x{} (closing brace missing?) at offset 5 + +/[ab]++/BZO +------------------------------------------------------------------ + Bra + [ab]++ + Ket + End +------------------------------------------------------------------ + +/[^ab]*+/BZO +------------------------------------------------------------------ + Bra + [\x00-`c-\xff] (neg)*+ + Ket + End +------------------------------------------------------------------ + +/a{4}+/BZO +------------------------------------------------------------------ + Bra + a{4} + Ket + End +------------------------------------------------------------------ + +/a{4}+/BZOi +------------------------------------------------------------------ + Bra + /i a{4} + Ket + End +------------------------------------------------------------------ + +/[a-[:digit:]]+/ +Failed: invalid range in character class at offset 3 + +/[A-[:digit:]]+/ +Failed: invalid range in character class at offset 3 + +/[a-[.xxx.]]+/ +Failed: invalid range in character class at offset 3 + +/[a-[=xxx=]]+/ +Failed: invalid range in character class at offset 3 + +/[a-[!xxx!]]+/ +Failed: range out of order in character class at offset 3 + +/[A-[!xxx!]]+/ + A]]] + 0: A]]] + +/[a-\d]+/ +Failed: invalid range in character class at offset 4 + +/(?<0abc>xx)/ +Failed: group name must start with a non-digit at offset 3 + +/(?&1abc)xx(?<1abc>y)/ +Failed: group name must start with a non-digit at offset 3 + +/(?xx)/ +Failed: syntax error in subpattern name (missing terminator) at offset 5 + +/(?'0abc'xx)/ +Failed: group name must start with a non-digit at offset 3 + +/(?P<0abc>xx)/ +Failed: group name must start with a non-digit at offset 4 + +/\k<5ghj>/ +Failed: group name must start with a non-digit at offset 3 + +/\k'5ghj'/ +Failed: group name must start with a non-digit at offset 3 + +/\k{2fgh}/ +Failed: group name must start with a non-digit at offset 3 + +/(?P=8yuki)/ +Failed: group name must start with a non-digit at offset 4 + +/\g{4df}/ +Failed: group name must start with a non-digit at offset 3 + +/(?&1abc)xx(?<1abc>y)/ +Failed: group name must start with a non-digit at offset 3 + +/(?P>1abc)xx(?<1abc>y)/ +Failed: group name must start with a non-digit at offset 4 + +/\g'3gh'/ +Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 7 + +/\g<5fg>/ +Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 7 + +/(?(<4gh>)abc)/ +Failed: group name must start with a non-digit at offset 4 + +/(?('4gh')abc)/ +Failed: group name must start with a non-digit at offset 4 + +/(?(4gh)abc)/ +Failed: malformed number or name after (?( at offset 4 + +/(?(R&6yh)abc)/ +Failed: group name must start with a non-digit at offset 5 + +/-- Test the ugly "start or end of word" compatibility syntax --/ + +/[[:<:]]red[[:>:]]/BZ +------------------------------------------------------------------ + Bra + \b + Assert + \w + Ket + red + \b + AssertB + Reverse + \w + Ket + Ket + End +------------------------------------------------------------------ + little red riding hood + 0: red + a /red/ thing + 0: red + red is a colour + 0: red + put it all on red + 0: red + ** Failers +No match + no reduction +No match + Alfred Winifred +No match + +/[a[:<:]] should give error/ +Failed: unknown POSIX class name at offset 4 + +/(?=ab\K)/+ + abcd +Start of matched string is beyond its end - displaying from end to start. + 0: ab + 0+ abcd + +/abcd/f + xx\nxabcd +No match + +/ -- Test stack check external calls --/ + +/(((((a)))))/Q0 + +/(((((a)))))/Q1 +Failed: parentheses are too deeply nested (stack check) at offset 0 + +/(((((a)))))/Q +** Missing 0 or 1 after /Q /-- End of testinput2 --/ diff --git a/tools/pcre/testdata/testoutput20 b/tools/pcre/testdata/testoutput20 index 7753be2d..c1b20ee8 100644 --- a/tools/pcre/testdata/testoutput20 +++ b/tools/pcre/testdata/testoutput20 @@ -8,12 +8,10 @@ /^\x{ffff}?/i \x{ffff} 0: \x{ffff} - 1: /^\x{ffff}*/i \x{ffff} 0: \x{ffff} - 1: /^\x{ffff}{3}/i \x{ffff}\x{ffff}\x{ffff} @@ -22,6 +20,5 @@ /^\x{ffff}{0,3}/i \x{ffff} 0: \x{ffff} - 1: /-- End of testinput20 --/ diff --git a/tools/pcre/testdata/testoutput21-16 b/tools/pcre/testdata/testoutput21-16 index 05107989..da194d90 100644 --- a/tools/pcre/testdata/testoutput21-16 +++ b/tools/pcre/testdata/testoutput21-16 @@ -1,5 +1,6 @@ -/-- Tests for reloading pre-compile patterns. The first one gives an error -right away. The others require the linke size to be 2. */ +/-- Tests for reloading pre-compiled patterns. The first one gives an error +right away, and can be any old pattern compiled in 8-bit mode ("abc" is +typical). The others require the link size to be 2. */x (?:[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}$ --/ +%-- Generated from: + /^[aL](?P(?:[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}$ + /x + + In 16-bit mode with options: S>testdata/saved16LE-1 + FS>testdata/saved16BE-1 + In 32-bit mode with options: S>testdata/saved32LE-1 + FS>testdata/saved32BE-1 +--%x (?:[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}$ --/ +%-- Generated from: + /^[aL](?P(?:[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}$ + /x + + In 16-bit mode with options: S>testdata/saved16LE-1 + FS>testdata/saved16BE-1 + In 32-bit mode with options: S>testdata/saved32LE-1 + FS>testdata/saved32BE-1 +--%x [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 +%-- Generated from: + /(?P[aZ\x{400}-\x{10ffff}]{4,} + [\x{f123}\x{10039}\x{20000}-\x{21234}]?| + [A-Cx-z\x{100000}-\x{1000a7}\x{101234}]) + (?[^az])/x + + In 16-bit mode with options: S8>testdata/saved16LE-2 + FS8>testdata/saved16BE-2 + In 32-bit mode with options: S8>testdata/saved32LE-2 + FS8>testdata/saved32BE-2 +--%8x [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 +%-- Generated from: + /(?P[aZ\x{400}-\x{10ffff}]{4,} + [\x{f123}\x{10039}\x{20000}-\x{21234}]?| + [A-Cx-z\x{100000}-\x{1000a7}\x{101234}]) + (?[^az])/x + + In 16-bit mode with options: S8>testdata/saved16LE-2 + FS8>testdata/saved16BE-2 + In 32-bit mode with options: S8>testdata/saved32LE-2 + FS8>testdata/saved32BE-2 +--%8x ? @ 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 \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 \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 /[\V]/BZSI ------------------------------------------------------------------ Bra - [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{ffff}] + [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffff}] Ket End ------------------------------------------------------------------ @@ -37,6 +54,19 @@ No options No first char No need char Subject length lower bound = 1 -No set of starting bytes +Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \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 [ \ ] ^ _ ` 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 \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 /-- End of testinput23 --/ diff --git a/tools/pcre/testdata/testoutput24 b/tools/pcre/testdata/testoutput24 index bf58abb6..0714a0fe 100644 --- a/tools/pcre/testdata/testoutput24 +++ b/tools/pcre/testdata/testoutput24 @@ -1,138 +1,6 @@ /-- Tests for the 16-bit library with UTF-16 support only */ -/noncharacter/8 - \x{fffe} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{ffff} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{1fffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{1ffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{2fffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{2ffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{3fffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{3ffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{4fffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{4ffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{5fffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{5ffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{6fffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{6ffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{7fffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{7ffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{8fffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{8ffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{9fffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{9ffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{afffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{affff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{bfffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{bffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{cfffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{cffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{dfffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{dffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{efffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{effff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{ffffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{fffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{10fffe} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{10ffff} -Error -10 (bad UTF-16 string) offset=1 reason=4 - \x{fdd0} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdd1} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdd2} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdd3} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdd4} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdd5} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdd6} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdd7} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdd8} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdd9} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdda} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fddb} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fddc} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fddd} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdde} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fddf} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fde0} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fde1} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fde2} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fde3} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fde4} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fde5} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fde6} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fde7} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fde8} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fde9} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdea} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdeb} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdec} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fded} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdee} -Error -10 (bad UTF-16 string) offset=0 reason=4 - \x{fdef} -Error -10 (bad UTF-16 string) offset=0 reason=4 +< forbid W /bad/8 \x{d800} diff --git a/tools/pcre/testdata/testoutput25 b/tools/pcre/testdata/testoutput25 index 2a4066df..4c62c8d8 100644 --- a/tools/pcre/testdata/testoutput25 +++ b/tools/pcre/testdata/testoutput25 @@ -1,5 +1,7 @@ /-- Tests for the 32-bit library only */ +< forbid 8W + /-- Check maximum character size --/ /\x{110000}/ @@ -10,6 +12,18 @@ /\x{ffffffff}/ +/\x{100000000}/ +Failed: character value in \x{} or \o{} is too large at offset 12 + +/\o{17777777777}/ + +/\o{20000000000}/ + +/\o{37777777777}/ + +/\o{40000000000}/ +Failed: character value in \x{} or \o{} is too large at offset 14 + /\x{7fffffff}\x{7fffffff}/I Capturing subpattern count = 0 No options @@ -51,7 +65,7 @@ Need char = \x{800000} /[\H]/BZSI ------------------------------------------------------------------ Bra - [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffffffff}] + [\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{ffffffff}] Ket End ------------------------------------------------------------------ @@ -60,12 +74,25 @@ No options No first char No need char Subject length lower bound = 1 -No set of starting bytes +Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0a \x0b + \x0c \x0d \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 \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 \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 /[\V]/BZSI ------------------------------------------------------------------ Bra - [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{ffffffff}] + [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffffffff}] Ket End ------------------------------------------------------------------ @@ -74,6 +101,19 @@ No options No first char No need char Subject length lower bound = 1 -No set of starting bytes +Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \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 [ \ ] ^ _ ` 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 \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 /-- End of testinput25 --/ diff --git a/tools/pcre/testdata/testoutput26 b/tools/pcre/testdata/testoutput26 index a22ead2f..28f8d42a 100644 --- a/tools/pcre/testdata/testoutput26 +++ b/tools/pcre/testdata/testoutput26 @@ -1,148 +1,17 @@ /-- Tests for the 32-bit library with UTF-32 support only */ +< forbid W + /-- Non-UTF characters --/ /\x{110000}/8 -Failed: character value in \x{...} sequence is too large at offset 9 +Failed: character value in \x{} or \o{} is too large at offset 9 + +/\o{4200000}/8 +Failed: character value in \x{} or \o{} is too large at offset 10 /\C/8 \x{110000} Error -10 (bad UTF-32 string) offset=0 reason=3 -/-- Invalid UTF-32 --/ - -/noncharacter/8 - \x{fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{1fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{1ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{2fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{2ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{3fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{3ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{4fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{4ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{5fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{5ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{6fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{6ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{7fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{7ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{8fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{8ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{9fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{9ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{afffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{affff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{bfffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{bffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{cfffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{cffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{dfffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{dffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{efffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{effff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{ffffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{10fffe} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{10ffff} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdd0} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdd1} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdd2} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdd3} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdd4} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdd5} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdd6} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdd7} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdd8} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdd9} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdda} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fddb} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fddc} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fddd} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdde} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fddf} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fde0} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fde1} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fde2} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fde3} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fde4} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fde5} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fde6} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fde7} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fde8} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fde9} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdea} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdeb} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdec} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fded} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdee} -Error -10 (bad UTF-32 string) offset=0 reason=2 - \x{fdef} -Error -10 (bad UTF-32 string) offset=0 reason=2 - /-- End of testinput26 --/ diff --git a/tools/pcre/testdata/testoutput3 b/tools/pcre/testdata/testoutput3 index 7b0a3e92..73119ab4 100644 --- a/tools/pcre/testdata/testoutput3 +++ b/tools/pcre/testdata/testoutput3 @@ -1,6 +1,11 @@ -/-- This set of tests checks local-specific features, using the fr_FR locale. - It is not Perl-compatible. There is different version called wintestinput3 - f or use on Windows, where the locale is called "french". --/ +/-- This set of tests checks local-specific features, using the "fr_FR" locale. + It is not Perl-compatible. When run via RunTest, the locale is edited to + be whichever of "fr_FR", "french", or "fr" is found to exist. There is + different version of this file called wintestinput3 for use on Windows, + where the locale is called "french" and the tests are run using + RunTest.bat. --/ + +< forbid 8W /^[\w]+/ *** Failers @@ -88,7 +93,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P +Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z /\w/ISLfr_FR @@ -97,7 +102,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P +Starting chars: 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 ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ diff --git a/tools/pcre/testdata/testoutput3A b/tools/pcre/testdata/testoutput3A new file mode 100644 index 00000000..0bde024e --- /dev/null +++ b/tools/pcre/testdata/testoutput3A @@ -0,0 +1,174 @@ +/-- This set of tests checks local-specific features, using the "fr_FR" locale. + It is not Perl-compatible. When run via RunTest, the locale is edited to + be whichever of "fr_FR", "french", or "fr" is found to exist. There is + different version of this file called wintestinput3 for use on Windows, + where the locale is called "french" and the tests are run using + RunTest.bat. --/ + +< forbid 8W + +/^[\w]+/ + *** Failers +No match + École +No match + +/^[\w]+/Lfr_FR + École + 0: École + +/^[\w]+/ + *** Failers +No match + École +No match + +/^[\W]+/ + École + 0: \xc9 + +/^[\W]+/Lfr_FR + *** Failers + 0: *** + École +No match + +/[\b]/ + \b + 0: \x08 + *** Failers +No match + a +No match + +/[\b]/Lfr_FR + \b + 0: \x08 + *** Failers +No match + a +No match + +/^\w+/ + *** Failers +No match + École +No match + +/^\w+/Lfr_FR + École + 0: École + +/(.+)\b(.+)/ + École + 0: \xc9cole + 1: \xc9 + 2: cole + +/(.+)\b(.+)/Lfr_FR + *** Failers + 0: *** Failers + 1: *** + 2: Failers + École +No match + +/École/i + École + 0: \xc9cole + *** Failers +No match + école +No match + +/École/iLfr_FR + École + 0: École + école + 0: école + +/\w/IS +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P + Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z + +/\w/ISLfr_FR +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P + Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z + ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â + ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ + +/^[\xc8-\xc9]/iLfr_FR + École + 0: É + école + 0: é + +/^[\xc8-\xc9]/Lfr_FR + École + 0: É + *** Failers +No match + école +No match + +/\W+/Lfr_FR + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/[\W]+/Lfr_FR + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/[^[:alpha:]]+/Lfr_FR + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/\w+/Lfr_FR + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[\w]+/Lfr_FR + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[[:alpha:]]+/Lfr_FR + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[[:alpha:]][[:lower:]][[:upper:]]/DZLfr_FR +------------------------------------------------------------------ + Bra + [A-Za-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\xff] + [a-z\xaa\xb5\xba\xdf-\xf6\xf8-\xff] + [A-Z\xc0-\xd6\xd8-\xde] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/-- End of testinput3 --/ diff --git a/tools/pcre/testdata/testoutput3B b/tools/pcre/testdata/testoutput3B new file mode 100644 index 00000000..8d9fe7df --- /dev/null +++ b/tools/pcre/testdata/testoutput3B @@ -0,0 +1,174 @@ +/-- This set of tests checks local-specific features, using the "fr_FR" locale. + It is not Perl-compatible. When run via RunTest, the locale is edited to + be whichever of "fr_FR", "french", or "fr" is found to exist. There is + different version of this file called wintestinput3 for use on Windows, + where the locale is called "french" and the tests are run using + RunTest.bat. --/ + +< forbid 8W + +/^[\w]+/ + *** Failers +No match + École +No match + +/^[\w]+/Lfr_FR + École + 0: École + +/^[\w]+/ + *** Failers +No match + École +No match + +/^[\W]+/ + École + 0: \xc9 + +/^[\W]+/Lfr_FR + *** Failers + 0: *** + École +No match + +/[\b]/ + \b + 0: \x08 + *** Failers +No match + a +No match + +/[\b]/Lfr_FR + \b + 0: \x08 + *** Failers +No match + a +No match + +/^\w+/ + *** Failers +No match + École +No match + +/^\w+/Lfr_FR + École + 0: École + +/(.+)\b(.+)/ + École + 0: \xc9cole + 1: \xc9 + 2: cole + +/(.+)\b(.+)/Lfr_FR + *** Failers + 0: *** Failers + 1: *** + 2: Failers + École +No match + +/École/i + École + 0: \xc9cole + *** Failers +No match + école +No match + +/École/iLfr_FR + École + 0: École + école + 0: école + +/\w/IS +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P + Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z + +/\w/ISLfr_FR +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P + Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z + ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â + ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ + +/^[\xc8-\xc9]/iLfr_FR + École + 0: É + école + 0: é + +/^[\xc8-\xc9]/Lfr_FR + École + 0: É + *** Failers +No match + école +No match + +/\W+/Lfr_FR + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/[\W]+/Lfr_FR + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/[^[:alpha:]]+/Lfr_FR + >>>\xaa<<< + 0: >>> + >>>\xba<<< + 0: >>> + +/\w+/Lfr_FR + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[\w]+/Lfr_FR + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[[:alpha:]]+/Lfr_FR + >>>\xaa<<< + 0: ª + >>>\xba<<< + 0: º + +/[[:alpha:]][[:lower:]][[:upper:]]/DZLfr_FR +------------------------------------------------------------------ + Bra + [A-Za-z\x83\x8a\x8c\x8e\x9a\x9c\x9e\x9f\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\xff] + [a-z\x83\x9a\x9c\x9e\xaa\xb5\xba\xdf-\xf6\xf8-\xff] + [A-Z\x8a\x8c\x8e\x9f\xc0-\xd6\xd8-\xde] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/-- End of testinput3 --/ diff --git a/tools/pcre/testdata/testoutput4 b/tools/pcre/testdata/testoutput4 index 2082721c..dcf13b08 100644 --- a/tools/pcre/testdata/testoutput4 +++ b/tools/pcre/testdata/testoutput4 @@ -1,6 +1,8 @@ /-- This set of tests is for UTF support, excluding Unicode properties. It is compatible with all versions of Perl >= 5.10 and both the 8-bit and 16-bit PCRE libraries. --/ + +< forbid 9?=ABCDEFfGILMNPTUWXZ< /a.b/8 acb @@ -1091,4 +1093,182 @@ MK: a\x{1234}b 0: a MK: a\x{a3}b +/-- Noncharacters --/ + +/./8 + \x{fffe} + 0: \x{fffe} + \x{ffff} + 0: \x{ffff} + \x{1fffe} + 0: \x{1fffe} + \x{1ffff} + 0: \x{1ffff} + \x{2fffe} + 0: \x{2fffe} + \x{2ffff} + 0: \x{2ffff} + \x{3fffe} + 0: \x{3fffe} + \x{3ffff} + 0: \x{3ffff} + \x{4fffe} + 0: \x{4fffe} + \x{4ffff} + 0: \x{4ffff} + \x{5fffe} + 0: \x{5fffe} + \x{5ffff} + 0: \x{5ffff} + \x{6fffe} + 0: \x{6fffe} + \x{6ffff} + 0: \x{6ffff} + \x{7fffe} + 0: \x{7fffe} + \x{7ffff} + 0: \x{7ffff} + \x{8fffe} + 0: \x{8fffe} + \x{8ffff} + 0: \x{8ffff} + \x{9fffe} + 0: \x{9fffe} + \x{9ffff} + 0: \x{9ffff} + \x{afffe} + 0: \x{afffe} + \x{affff} + 0: \x{affff} + \x{bfffe} + 0: \x{bfffe} + \x{bffff} + 0: \x{bffff} + \x{cfffe} + 0: \x{cfffe} + \x{cffff} + 0: \x{cffff} + \x{dfffe} + 0: \x{dfffe} + \x{dffff} + 0: \x{dffff} + \x{efffe} + 0: \x{efffe} + \x{effff} + 0: \x{effff} + \x{ffffe} + 0: \x{ffffe} + \x{fffff} + 0: \x{fffff} + \x{10fffe} + 0: \x{10fffe} + \x{10ffff} + 0: \x{10ffff} + \x{fdd0} + 0: \x{fdd0} + \x{fdd1} + 0: \x{fdd1} + \x{fdd2} + 0: \x{fdd2} + \x{fdd3} + 0: \x{fdd3} + \x{fdd4} + 0: \x{fdd4} + \x{fdd5} + 0: \x{fdd5} + \x{fdd6} + 0: \x{fdd6} + \x{fdd7} + 0: \x{fdd7} + \x{fdd8} + 0: \x{fdd8} + \x{fdd9} + 0: \x{fdd9} + \x{fdda} + 0: \x{fdda} + \x{fddb} + 0: \x{fddb} + \x{fddc} + 0: \x{fddc} + \x{fddd} + 0: \x{fddd} + \x{fdde} + 0: \x{fdde} + \x{fddf} + 0: \x{fddf} + \x{fde0} + 0: \x{fde0} + \x{fde1} + 0: \x{fde1} + \x{fde2} + 0: \x{fde2} + \x{fde3} + 0: \x{fde3} + \x{fde4} + 0: \x{fde4} + \x{fde5} + 0: \x{fde5} + \x{fde6} + 0: \x{fde6} + \x{fde7} + 0: \x{fde7} + \x{fde8} + 0: \x{fde8} + \x{fde9} + 0: \x{fde9} + \x{fdea} + 0: \x{fdea} + \x{fdeb} + 0: \x{fdeb} + \x{fdec} + 0: \x{fdec} + \x{fded} + 0: \x{fded} + \x{fdee} + 0: \x{fdee} + \x{fdef} + 0: \x{fdef} + +/^\d*\w{4}/8 + 1234 + 0: 1234 + 123 +No match + +/^[^b]*\w{4}/8 + aaaa + 0: aaaa + aaa +No match + +/^[^b]*\w{4}/8i + aaaa + 0: aaaa + aaa +No match + +/^\x{100}*.{4}/8 + \x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100}\x{100} + \x{100}\x{100}\x{100} +No match + +/^\x{100}*.{4}/8i + \x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100}\x{100} + \x{100}\x{100}\x{100} +No match + +/^a+[a\x{200}]/8 + aa + 0: aa + +/^.\B.\B./8 + \x{10123}\x{10124}\x{10125} + 0: \x{10123}\x{10124}\x{10125} + +/^#[^\x{ffff}]#[^\x{ffff}]#[^\x{ffff}]#/8 + #\x{10000}#\x{100}#\x{10ffff}# + 0: #\x{10000}#\x{100}#\x{10ffff}# + /-- End of testinput4 --/ diff --git a/tools/pcre/testdata/testoutput5 b/tools/pcre/testdata/testoutput5 index 0e840540..5c098e65 100644 --- a/tools/pcre/testdata/testoutput5 +++ b/tools/pcre/testdata/testoutput5 @@ -1,26 +1,47 @@ /-- This set of tests checks the API, internals, and non-Perl stuff for UTF support, excluding Unicode properties. However, tests that give different results in 8-bit and 16-bit modes are excluded (see tests 16 and 17). --/ + +< forbid W /\x{110000}/8DZ -Failed: character value in \x{...} sequence is too large at offset 9 +Failed: character value in \x{} or \o{} is too large at offset 9 + +/\o{4200000}/8DZ +Failed: character value in \x{} or \o{} is too large at offset 10 /\x{ffffffff}/8 -Failed: character value in \x{...} sequence is too large at offset 11 +Failed: character value in \x{} or \o{} is too large at offset 11 + +/\o{37777777777}/8 +Failed: character value in \x{} or \o{} is too large at offset 14 /\x{100000000}/8 -Failed: character value in \x{...} sequence is too large at offset 12 +Failed: character value in \x{} or \o{} is too large at offset 12 + +/\o{77777777777}/8 +Failed: character value in \x{} or \o{} is too large at offset 14 /\x{d800}/8 Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 +/\o{154000}/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 9 + /\x{dfff}/8 Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 +/\o{157777}/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 9 + /\x{d7ff}/8 +/\o{153777}/8 + /\x{e000}/8 +/\o{170000}/8 + /^\x{100}a\x{1234}/8 \x{100}a\x{1234}bcd 0: \x{100}a\x{1234} @@ -146,11 +167,12 @@ No match /\x{100}*/8DZ ------------------------------------------------------------------ Bra - \x{100}* + \x{100}*+ Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 +May match empty string Options: utf No first char No need char @@ -159,7 +181,7 @@ No need char ------------------------------------------------------------------ Bra a - \x{100}* + \x{100}*+ Ket End ------------------------------------------------------------------ @@ -172,7 +194,7 @@ No need char ------------------------------------------------------------------ Bra ab - \x{100}* + \x{100}*+ Ket End ------------------------------------------------------------------ @@ -248,7 +270,7 @@ No match /[z-\x{100}]/8DZ ------------------------------------------------------------------ Bra - [z-\x{100}] + [z-\xff\x{100}] Ket End ------------------------------------------------------------------ @@ -373,6 +395,7 @@ Need char = 'z' End ------------------------------------------------------------------ Capturing subpattern count = 2 +May match empty string Options: utf No first char No need char @@ -404,6 +427,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 2 +May match empty string Options: utf No first char No need char @@ -424,6 +448,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 2 +May match empty string Options: utf No first char No need char @@ -455,6 +480,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 2 +May match empty string Options: utf No first char No need char @@ -768,7 +794,7 @@ No match /[\h]{3,}/8BZ ------------------------------------------------------------------ Bra - [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]{3,} + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]{3,}+ Ket End ------------------------------------------------------------------ @@ -786,7 +812,7 @@ No match /[\H]/8BZ ------------------------------------------------------------------ Bra - [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}] + [\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 ------------------------------------------------------------------ @@ -794,7 +820,7 @@ No match /[\V]/8BZ ------------------------------------------------------------------ Bra - [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{10ffff}] + [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}] Ket End ------------------------------------------------------------------ @@ -1510,7 +1536,7 @@ Options: caseless utf No first char No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list /[^\x{1234}]+?/iS8I Capturing subpattern count = 0 @@ -1518,7 +1544,7 @@ Options: caseless utf No first char No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list /[^\x{1234}]++/iS8I Capturing subpattern count = 0 @@ -1526,7 +1552,7 @@ Options: caseless utf No first char No need char Subject length lower bound = 1 -No set of starting bytes +No starting char list /[^\x{1234}]{2}/iS8I Capturing subpattern count = 0 @@ -1534,7 +1560,7 @@ Options: caseless utf No first char No need char Subject length lower bound = 2 -No set of starting bytes +No starting char list // Failed: inconsistent NEWLINE options at offset 0 @@ -1572,7 +1598,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 /[\h\x{e000}]+/8BZ ------------------------------------------------------------------ Bra - [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{e000}]+ + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{e000}]++ Ket End ------------------------------------------------------------------ @@ -1594,7 +1620,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 /[\H\x{d7ff}]+/8BZ ------------------------------------------------------------------ Bra - [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}\x{d7ff}]+ + [\x00-\x08\x0a-\x1f!-\x9f\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 ------------------------------------------------------------------ @@ -1616,7 +1642,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 /[\v\x{e000}]+/8BZ ------------------------------------------------------------------ Bra - [\x0a-\x0d\x85\x{2028}-\x{2029}\x{e000}]+ + [\x0a-\x0d\x85\x{2028}-\x{2029}\x{e000}]++ Ket End ------------------------------------------------------------------ @@ -1634,7 +1660,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 /[\V\x{d7ff}]+/8BZ ------------------------------------------------------------------ Bra - [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]+ + [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]++ Ket End ------------------------------------------------------------------ @@ -1808,20 +1834,18 @@ Partial match: \x{0d}\x{0d} /i [^\x{8000}]* /i [^\x{7fff}]{2} /i [^\x{7fff}]{0,7}? - Once /i [^\x{fffff}]{5} - /i [^\x{fffff}]? - Ket + /i [^\x{fffff}]?+ Ket End ------------------------------------------------------------------ /(?<=\x{1234}\x{1234})\bxy/I8 Capturing subpattern count = 0 +Max lookbehind = 2 Options: utf First char = 'x' Need char = 'y' -Max lookbehind = 2 /(?8 Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 5 +/^a+[a\x{200}]/8BZ +------------------------------------------------------------------ + Bra + ^ + a+ + [a\x{200}] + Ket + End +------------------------------------------------------------------ + aa + 0: aa + +/[b-d\x{200}-\x{250}]*[ae-h]?#[\x{200}-\x{250}]{0,8}[\x00-\xff]*#[\x{200}-\x{250}]+[a-z]/8BZ +------------------------------------------------------------------ + Bra + [b-d\x{200}-\x{250}]*+ + [ae-h]?+ + # + [\x{200}-\x{250}]{0,8}+ + [\x00-\xff]* + # + [\x{200}-\x{250}]++ + [a-z] + Ket + End +------------------------------------------------------------------ + /-- End of testinput5 --/ diff --git a/tools/pcre/testdata/testoutput6 b/tools/pcre/testdata/testoutput6 index 01827461..f355e601 100644 --- a/tools/pcre/testdata/testoutput6 +++ b/tools/pcre/testdata/testoutput6 @@ -1,5 +1,7 @@ /-- This set of tests is for Unicode property support. It is compatible with Perl >= 5.15. --/ + +< forbid 9?=ABCDEFfGILMNPTUXZ< /^\pC\pL\pM\pN\pP\pS\pZ\s+/8W >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} - 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{09} + 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{09}\x{0b} /^>\pZ+/8W >\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b} @@ -1338,15 +1332,15 @@ No match /^[[:graph:]]*/8W A\x{a1}\x{a0} - 0: A + 0: A\x{a1} /^[[:print:]]*/8W A z\x{a0}\x{a1} - 0: A z + 0: A z\x{a0}\x{a1} /^[[:punct:]]*/8W .+\x{a1}\x{a0} - 0: .+ + 0: .+\x{a1} /\p{Zs}*?\R/ ** Failers @@ -1548,6 +1542,19 @@ No match 0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X 0+ +/\X*Z/8Y + A\x{300} +No match + +/\X*(.)/8Y + A\x{1111}\x{ae4c}\x{1169} + 0: A\x{1111} + 1: \x{1111} + +/\X?abc/8Y +\xff\x7f\x00\x00\x03\x00\x41\xcc\x80\x41\x{300}\x61\x62\x63\x00\>06\? + 0: A\x{300}abc + /-- --/ /\x{1e9e}+/8i @@ -2134,4 +2141,320 @@ No match \x{0053}\x{0073}\x{017f} 0: Ss\x{17f} +/^\p{Any}*\d{4}/8 + 1234 + 0: 1234 + 123 +No match + +/^\X*\w{4}/8 + 1234 + 0: 1234 + 123 +No match + +/^A\s+Z/8W + A\x{2005}Z + 0: A\x{2005}Z + A\x{85}\x{180e}\x{2005}Z + 0: A\x{85}\x{180e}\x{2005}Z + +/^A[\s]+Z/8W + A\x{2005}Z + 0: A\x{2005}Z + A\x{85}\x{180e}\x{2005}Z + 0: A\x{85}\x{180e}\x{2005}Z + +/^[[:graph:]]+$/8W + Letter:ABC + 0: Letter:ABC + Mark:\x{300}\x{1d172}\x{1d17b} + 0: Mark:\x{300}\x{1d172}\x{1d17b} + Number:9\x{660} + 0: Number:9\x{660} + Punctuation:\x{66a},; + 0: Punctuation:\x{66a},; + Symbol:\x{6de}<>\x{fffc} + 0: Symbol:\x{6de}<>\x{fffc} + Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f} + 0: Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f} + \x{200b}\x{200c}\x{200d}\x{200e}\x{200f} + 0: \x{200b}\x{200c}\x{200d}\x{200e}\x{200f} + \x{202a}\x{202b}\x{202c}\x{202d}\x{202e} + 0: \x{202a}\x{202b}\x{202c}\x{202d}\x{202e} + \x{2060}\x{2061}\x{2062}\x{2063}\x{2064} + 0: \x{2060}\x{2061}\x{2062}\x{2063}\x{2064} + \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f} + 0: \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f} + \x{feff} + 0: \x{feff} + \x{fff9}\x{fffa}\x{fffb} + 0: \x{fff9}\x{fffa}\x{fffb} + \x{110bd} + 0: \x{110bd} + \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a} + 0: \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a} + \x{e0001} + 0: \x{e0001} + \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f} + 0: \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f} + ** Failers +No match + \x{09} +No match + \x{0a} +No match + \x{1D} +No match + \x{20} +No match + \x{85} +No match + \x{a0} +No match + \x{61c} +No match + \x{1680} +No match + \x{180e} +No match + \x{2028} +No match + \x{2029} +No match + \x{202f} +No match + \x{2065} +No match + \x{2066} +No match + \x{2067} +No match + \x{2068} +No match + \x{2069} +No match + \x{3000} +No match + \x{e0002} +No match + \x{e001f} +No match + \x{e0080} +No match + +/^[[:print:]]+$/8W + Space: \x{a0} + 0: Space: \x{a0} + \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005} + 0: \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005} + \x{2006}\x{2007}\x{2008}\x{2009}\x{200a} + 0: \x{2006}\x{2007}\x{2008}\x{2009}\x{200a} + \x{202f}\x{205f} + 0: \x{202f}\x{205f} + \x{3000} + 0: \x{3000} + Letter:ABC + 0: Letter:ABC + Mark:\x{300}\x{1d172}\x{1d17b} + 0: Mark:\x{300}\x{1d172}\x{1d17b} + Number:9\x{660} + 0: Number:9\x{660} + Punctuation:\x{66a},; + 0: Punctuation:\x{66a},; + Symbol:\x{6de}<>\x{fffc} + 0: Symbol:\x{6de}<>\x{fffc} + Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f} + 0: Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f} + \x{180e} + 0: \x{180e} + \x{200b}\x{200c}\x{200d}\x{200e}\x{200f} + 0: \x{200b}\x{200c}\x{200d}\x{200e}\x{200f} + \x{202a}\x{202b}\x{202c}\x{202d}\x{202e} + 0: \x{202a}\x{202b}\x{202c}\x{202d}\x{202e} + \x{202f} + 0: \x{202f} + \x{2060}\x{2061}\x{2062}\x{2063}\x{2064} + 0: \x{2060}\x{2061}\x{2062}\x{2063}\x{2064} + \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f} + 0: \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f} + \x{feff} + 0: \x{feff} + \x{fff9}\x{fffa}\x{fffb} + 0: \x{fff9}\x{fffa}\x{fffb} + \x{110bd} + 0: \x{110bd} + \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a} + 0: \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a} + \x{e0001} + 0: \x{e0001} + \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f} + 0: \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f} + ** Failers + 0: ** Failers + \x{09} +No match + \x{1D} +No match + \x{85} +No match + \x{61c} +No match + \x{2028} +No match + \x{2029} +No match + \x{2065} +No match + \x{2066} +No match + \x{2067} +No match + \x{2068} +No match + \x{2069} +No match + \x{e0002} +No match + \x{e001f} +No match + \x{e0080} +No match + +/^[[:punct:]]+$/8W + \$+<=>^`|~ + 0: $+<=>^`|~ + !\"#%&'()*,-./:;?@[\\]_{} + 0: !"#%&'()*,-./:;?@[\]_{} + \x{a1}\x{a7} + 0: \x{a1}\x{a7} + \x{37e} + 0: \x{37e} + ** Failers +No match + abcde +No match + +/^[[:^graph:]]+$/8W + \x{09}\x{0a}\x{1D}\x{20}\x{85}\x{a0}\x{61c}\x{1680}\x{180e} + 0: \x{09}\x{0a}\x{1d} \x{85}\x{a0}\x{61c}\x{1680}\x{180e} + \x{2028}\x{2029}\x{202f}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069} + 0: \x{2028}\x{2029}\x{202f}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069} + \x{3000}\x{e0002}\x{e001f}\x{e0080} + 0: \x{3000}\x{e0002}\x{e001f}\x{e0080} + ** Failers +No match + Letter:ABC +No match + Mark:\x{300}\x{1d172}\x{1d17b} +No match + Number:9\x{660} +No match + Punctuation:\x{66a},; +No match + Symbol:\x{6de}<>\x{fffc} +No match + Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f} +No match + \x{200b}\x{200c}\x{200d}\x{200e}\x{200f} +No match + \x{202a}\x{202b}\x{202c}\x{202d}\x{202e} +No match + \x{2060}\x{2061}\x{2062}\x{2063}\x{2064} +No match + \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f} +No match + \x{feff} +No match + \x{fff9}\x{fffa}\x{fffb} +No match + \x{110bd} +No match + \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a} +No match + \x{e0001} +No match + \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f} +No match + +/^[[:^print:]]+$/8W + \x{09}\x{1D}\x{85}\x{61c}\x{2028}\x{2029}\x{2065}\x{2066}\x{2067} + 0: \x{09}\x{1d}\x{85}\x{61c}\x{2028}\x{2029}\x{2065}\x{2066}\x{2067} + \x{2068}\x{2069}\x{e0002}\x{e001f}\x{e0080} + 0: \x{2068}\x{2069}\x{e0002}\x{e001f}\x{e0080} + ** Failers +No match + Space: \x{a0} +No match + \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005} +No match + \x{2006}\x{2007}\x{2008}\x{2009}\x{200a} +No match + \x{202f}\x{205f} +No match + \x{3000} +No match + Letter:ABC +No match + Mark:\x{300}\x{1d172}\x{1d17b} +No match + Number:9\x{660} +No match + Punctuation:\x{66a},; +No match + Symbol:\x{6de}<>\x{fffc} +No match + Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f} +No match + \x{180e} +No match + \x{200b}\x{200c}\x{200d}\x{200e}\x{200f} +No match + \x{202a}\x{202b}\x{202c}\x{202d}\x{202e} +No match + \x{202f} +No match + \x{2060}\x{2061}\x{2062}\x{2063}\x{2064} +No match + \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f} +No match + \x{feff} +No match + \x{fff9}\x{fffa}\x{fffb} +No match + \x{110bd} +No match + \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a} +No match + \x{e0001} +No match + \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f} +No match + +/^[[:^punct:]]+$/8W + abcde + 0: abcde + ** Failers +No match + \$+<=>^`|~ +No match + !\"#%&'()*,-./:;?@[\\]_{} +No match + \x{a1}\x{a7} +No match + \x{37e} +No match + +/[RST]+/8iW + Ss\x{17f} + 0: Ss\x{17f} + +/[R-T]+/8iW + Ss\x{17f} + 0: Ss\x{17f} + +/[q-u]+/8iW + Ss\x{17f} + 0: Ss\x{17f} + /-- End of testinput6 --/ diff --git a/tools/pcre/testdata/testoutput7 b/tools/pcre/testdata/testoutput7 index 4f8b7b9b..c64e0499 100644 --- a/tools/pcre/testdata/testoutput7 +++ b/tools/pcre/testdata/testoutput7 @@ -78,7 +78,7 @@ No need char /[\p{Nd}+-]+/8DZ ------------------------------------------------------------------ Bra - [+\-\p{Nd}]+ + [+\-\p{Nd}]++ Ket End ------------------------------------------------------------------ @@ -124,7 +124,7 @@ No match /[z-\x{100}]/8iDZ ------------------------------------------------------------------ Bra - [Z\x{39c}\x{3bc}\x{1e9e}\x{178}z-\x{101}] + [Zz-\xff\x{39c}\x{3bc}\x{212b}\x{1e9e}\x{212b}\x{178}\x{100}-\x{101}] Ket End ------------------------------------------------------------------ @@ -162,7 +162,7 @@ No match /[z-\x{100}]/8DZi ------------------------------------------------------------------ Bra - [Z\x{39c}\x{3bc}\x{1e9e}\x{178}z-\x{101}] + [Zz-\xff\x{39c}\x{3bc}\x{212b}\x{1e9e}\x{212b}\x{178}\x{100}-\x{101}] Ket End ------------------------------------------------------------------ @@ -270,6 +270,20 @@ No need char End ------------------------------------------------------------------ +/^\p{Cf}/8 + \x{180e} + 0: \x{180e} + \x{061c} + 0: \x{61c} + \x{2066} + 0: \x{2066} + \x{2067} + 0: \x{2067} + \x{2068} + 0: \x{2068} + \x{2069} + 0: \x{2069} + /^\p{Cs}/8 \?\x{dfff} 0: \x{dfff} @@ -278,6 +292,22 @@ No match \x{09f} No match +/^\p{Mn}/8 + \x{1a1b} + 0: \x{1a1b} + +/^\p{Pe}/8 + \x{2309} + 0: \x{2309} + \x{230b} + 0: \x{230b} + +/^\p{Ps}/8 + \x{2308} + 0: \x{2308} + \x{230a} + 0: \x{230a} + /^\p{Sc}+/8 $\x{a2}\x{a3}\x{a4}\x{a5}\x{a6} 0: $\x{a2}\x{a3}\x{a4}\x{a5} @@ -297,8 +327,6 @@ No match 0: \x{a0} \x{1680} 0: \x{1680} - \x{180e} - 0: \x{180e} \x{2000} 0: \x{2000} \x{2001} @@ -310,8 +338,9 @@ No match \x{200d} No match -/-- These four are here rather than in test 6 because Perl has problems with - the negative versions of the properties. --/ +/-- These are here rather than in test 6 because Perl has problems with + the negative versions of the properties and behaves has changed how + it behaves for caseless matching. --/ /\p{^Lu}/8i 1234 @@ -351,6 +380,16 @@ No match \x{1d00} No match +/\p{Lu}/8i + A + 0: A + aZ + 0: Z + ** Failers + 0: F + abc +No match + /[\x{c0}\x{391}]/8i \x{c0} 0: \x{c0} @@ -501,7 +540,7 @@ No match /^>\p{Xsp}+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xsp}+?/8 >\x{1680}\x{2028}\x{0b} @@ -509,11 +548,11 @@ No match /^>\p{Xsp}*/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xsp}{2,9}/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xsp}{2,9}?/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} @@ -525,7 +564,7 @@ No match /^>[\p{Xsp}]+/8 > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} /^>\p{Xps}/8 >\x{1680}\x{2028}\x{0b} @@ -820,7 +859,7 @@ No match /[[:graph:]]/WBZ ------------------------------------------------------------------ Bra - [!-~] + [[:graph:]] Ket End ------------------------------------------------------------------ @@ -828,7 +867,7 @@ No match /[[:print:]]/WBZ ------------------------------------------------------------------ Bra - [ -~] + [[:print:]] Ket End ------------------------------------------------------------------ @@ -836,7 +875,7 @@ No match /[[:punct:]]/WBZ ------------------------------------------------------------------ Bra - [!-/:-@[-`{-~] + [[:punct:]] Ket End ------------------------------------------------------------------ @@ -910,7 +949,7 @@ No match /[[:^alpha:][:^cntrl:]]+/8WBZ ------------------------------------------------------------------ Bra - [ -~\x80-\xff\P{L}]+ + [ -~\x80-\xff\P{L}]++ Ket End ------------------------------------------------------------------ @@ -922,7 +961,7 @@ No match /[[:^cntrl:][:^alpha:]]+/8WBZ ------------------------------------------------------------------ Bra - [ -~\x80-\xff\P{L}]+ + [ -~\x80-\xff\P{L}]++ Ket End ------------------------------------------------------------------ @@ -934,7 +973,7 @@ No match /[[:alpha:]]+/8WBZ ------------------------------------------------------------------ Bra - [\p{L}]+ + [\p{L}]++ Ket End ------------------------------------------------------------------ @@ -944,7 +983,7 @@ No match /[[:^alpha:]\S]+/8WBZ ------------------------------------------------------------------ Bra - [\P{L}\P{Xsp}]+ + [\P{L}\P{Xsp}]++ Ket End ------------------------------------------------------------------ @@ -956,7 +995,7 @@ No match /[^\d]+/8WBZ ------------------------------------------------------------------ Bra - [^\p{Nd}]+ + [^\p{Nd}]++ Ket End ------------------------------------------------------------------ @@ -1070,8 +1109,8 @@ No match prop Nd B+ prop N *+ - B+ - prop Nd * + B++ + prop Nd *+ Ket End ------------------------------------------------------------------ @@ -1347,7 +1386,7 @@ Need char = 'B' (caseless) /[\x{3a3}]+/8iBZ ------------------------------------------------------------------ Bra - clist 03a3 03c2 03c3 + + clist 03a3 03c2 03c3 ++ Ket End ------------------------------------------------------------------ @@ -1355,7 +1394,7 @@ Need char = 'B' (caseless) /[^\x{3a3}]+/8iBZ ------------------------------------------------------------------ Bra - not clist 03a3 03c2 03c3 + + not clist 03a3 03c2 03c3 ++ Ket End ------------------------------------------------------------------ @@ -1469,5 +1508,783 @@ No match /is{2}t/8i iskt No match + +/-- This property is a PCRE special --/ + +/^\p{Xuc}/8 + $abc + 0: $ + @abc + 0: @ + `abc + 0: ` + \x{1234}abc + 0: \x{1234} + ** Failers +No match + abc +No match + +/^\p{Xuc}+/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234}\x{e000} + ** Failers +No match + \x{9f} +No match + +/^\p{Xuc}+?/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $ + ** Failers +No match + \x{9f} +No match + +/^\p{Xuc}+?\*/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234}\x{e000}* + ** Failers +No match + \x{9f} +No match + +/^\p{Xuc}++/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234}\x{e000} + ** Failers +No match + \x{9f} +No match + +/^\p{Xuc}{3,5}/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234} + ** Failers +No match + \x{9f} +No match + +/^\p{Xuc}{3,5}?/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@` + ** Failers +No match + \x{9f} +No match + +/^[\p{Xuc}]/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $ + ** Failers +No match + \x{9f} +No match + +/^[\p{Xuc}]+/8 + $@`\x{a0}\x{1234}\x{e000}** + 0: $@`\x{a0}\x{1234}\x{e000} + ** Failers +No match + \x{9f} +No match + +/^\P{Xuc}/8 + abc + 0: a + ** Failers + 0: * + $abc +No match + @abc +No match + `abc +No match + \x{1234}abc +No match + +/^[\P{Xuc}]/8 + abc + 0: a + ** Failers + 0: * + $abc +No match + @abc +No match + `abc +No match + \x{1234}abc +No match + +/-- Some auto-possessification tests --/ + +/\pN+\z/BZ +------------------------------------------------------------------ + Bra + prop N ++ + \z + Ket + End +------------------------------------------------------------------ + +/\PN+\z/BZ +------------------------------------------------------------------ + Bra + notprop N ++ + \z + Ket + End +------------------------------------------------------------------ + +/\pN+/BZ +------------------------------------------------------------------ + Bra + prop N ++ + Ket + End +------------------------------------------------------------------ + +/\PN+/BZ +------------------------------------------------------------------ + Bra + notprop N ++ + Ket + End +------------------------------------------------------------------ + +/\p{Any}+\p{Any} \p{Any}+\P{Any} \p{Any}+\p{L&} \p{Any}+\p{L} \p{Any}+\p{Lu} \p{Any}+\p{Han} \p{Any}+\p{Xan} \p{Any}+\p{Xsp} \p{Any}+\p{Xps} \p{Xwd}+\p{Any} \p{Any}+\p{Xuc}/BWZx +------------------------------------------------------------------ + Bra + prop Any + + prop Any + prop Any + + notprop Any + prop Any + + prop L& + prop Any + + prop L + prop Any + + prop Lu + prop Any + + prop Han + prop Any + + prop Xan + prop Any + + prop Xsp + prop Any + + prop Xps + prop Xwd + + prop Any + prop Any + + prop Xuc + Ket + End +------------------------------------------------------------------ + +/\p{L&}+\p{Any} \p{L&}+\p{L&} \P{L&}+\p{L&} \p{L&}+\p{L} \p{L&}+\p{Lu} \p{L&}+\p{Han} \p{L&}+\p{Xan} \p{L&}+\P{Xan} \p{L&}+\p{Xsp} \p{L&}+\p{Xps} \p{Xwd}+\p{L&} \p{L&}+\p{Xuc}/BWZx +------------------------------------------------------------------ + Bra + prop L& + + prop Any + prop L& + + prop L& + notprop L& ++ + prop L& + prop L& + + prop L + prop L& + + prop Lu + prop L& + + prop Han + prop L& + + prop Xan + prop L& ++ + notprop Xan + prop L& ++ + prop Xsp + prop L& ++ + prop Xps + prop Xwd + + prop L& + prop L& + + prop Xuc + Ket + End +------------------------------------------------------------------ + +/\p{N}+\p{Any} \p{N}+\p{L&} \p{N}+\p{L} \p{N}+\P{L} \p{N}+\P{N} \p{N}+\p{Lu} \p{N}+\p{Han} \p{N}+\p{Xan} \p{N}+\p{Xsp} \p{N}+\p{Xps} \p{Xwd}+\p{N} \p{N}+\p{Xuc}/BWZx +------------------------------------------------------------------ + Bra + prop N + + prop Any + prop N + + prop L& + prop N ++ + prop L + prop N + + notprop L + prop N ++ + notprop N + prop N ++ + prop Lu + prop N + + prop Han + prop N + + prop Xan + prop N ++ + prop Xsp + prop N ++ + prop Xps + prop Xwd + + prop N + prop N + + prop Xuc + Ket + End +------------------------------------------------------------------ + +/\p{Lu}+\p{Any} \p{Lu}+\p{L&} \p{Lu}+\p{L} \p{Lu}+\p{Lu} \P{Lu}+\p{Lu} \p{Lu}+\p{Nd} \p{Lu}+\P{Nd} \p{Lu}+\p{Han} \p{Lu}+\p{Xan} \p{Lu}+\p{Xsp} \p{Lu}+\p{Xps} \p{Xwd}+\p{Lu} \p{Lu}+\p{Xuc}/BWZx +------------------------------------------------------------------ + Bra + prop Lu + + prop Any + prop Lu + + prop L& + prop Lu + + prop L + prop Lu + + prop Lu + notprop Lu ++ + prop Lu + prop Lu ++ + prop Nd + prop Lu + + notprop Nd + prop Lu + + prop Han + prop Lu + + prop Xan + prop Lu ++ + prop Xsp + prop Lu ++ + prop Xps + prop Xwd + + prop Lu + prop Lu + + prop Xuc + Ket + End +------------------------------------------------------------------ + +/\p{Han}+\p{Lu} \p{Han}+\p{L&} \p{Han}+\p{L} \p{Han}+\p{Lu} \p{Han}+\p{Arabic} \p{Arabic}+\p{Arabic} \p{Han}+\p{Xan} \p{Han}+\p{Xsp} \p{Han}+\p{Xps} \p{Xwd}+\p{Han} \p{Han}+\p{Xuc}/BWZx +------------------------------------------------------------------ + Bra + prop Han + + prop Lu + prop Han + + prop L& + prop Han + + prop L + prop Han + + prop Lu + prop Han ++ + prop Arabic + prop Arabic + + prop Arabic + prop Han + + prop Xan + prop Han + + prop Xsp + prop Han + + prop Xps + prop Xwd + + prop Han + prop Han + + prop Xuc + Ket + End +------------------------------------------------------------------ + +/\p{Xan}+\p{Any} \p{Xan}+\p{L&} \P{Xan}+\p{L&} \p{Xan}+\p{L} \p{Xan}+\p{Lu} \p{Xan}+\p{Han} \p{Xan}+\p{Xan} \p{Xan}+\P{Xan} \p{Xan}+\p{Xsp} \p{Xan}+\p{Xps} \p{Xwd}+\p{Xan} \p{Xan}+\p{Xuc}/BWZx +------------------------------------------------------------------ + Bra + prop Xan + + prop Any + prop Xan + + prop L& + notprop Xan ++ + prop L& + prop Xan + + prop L + prop Xan + + prop Lu + prop Xan + + prop Han + prop Xan + + prop Xan + prop Xan ++ + notprop Xan + prop Xan ++ + prop Xsp + prop Xan ++ + prop Xps + prop Xwd + + prop Xan + prop Xan + + prop Xuc + Ket + End +------------------------------------------------------------------ + +/\p{Xsp}+\p{Any} \p{Xsp}+\p{L&} \p{Xsp}+\p{L} \p{Xsp}+\p{Lu} \p{Xsp}+\p{Han} \p{Xsp}+\p{Xan} \p{Xsp}+\p{Xsp} \P{Xsp}+\p{Xsp} \p{Xsp}+\p{Xps} \p{Xwd}+\p{Xsp} \p{Xsp}+\p{Xuc}/BWZx +------------------------------------------------------------------ + Bra + prop Xsp + + prop Any + prop Xsp ++ + prop L& + prop Xsp ++ + prop L + prop Xsp ++ + prop Lu + prop Xsp + + prop Han + prop Xsp ++ + prop Xan + prop Xsp + + prop Xsp + notprop Xsp ++ + prop Xsp + prop Xsp + + prop Xps + prop Xwd ++ + prop Xsp + prop Xsp + + prop Xuc + Ket + End +------------------------------------------------------------------ + +/\p{Xwd}+\p{Any} \p{Xwd}+\p{L&} \p{Xwd}+\p{L} \p{Xwd}+\p{Lu} \p{Xwd}+\p{Han} \p{Xwd}+\p{Xan} \p{Xwd}+\p{Xsp} \p{Xwd}+\p{Xps} \p{Xwd}+\p{Xwd} \p{Xwd}+\P{Xwd} \p{Xwd}+\p{Xuc}/BWZx +------------------------------------------------------------------ + Bra + prop Xwd + + prop Any + prop Xwd + + prop L& + prop Xwd + + prop L + prop Xwd + + prop Lu + prop Xwd + + prop Han + prop Xwd + + prop Xan + prop Xwd ++ + prop Xsp + prop Xwd ++ + prop Xps + prop Xwd + + prop Xwd + prop Xwd ++ + notprop Xwd + prop Xwd + + prop Xuc + Ket + End +------------------------------------------------------------------ + +/\p{Xuc}+\p{Any} \p{Xuc}+\p{L&} \p{Xuc}+\p{L} \p{Xuc}+\p{Lu} \p{Xuc}+\p{Han} \p{Xuc}+\p{Xan} \p{Xuc}+\p{Xsp} \p{Xuc}+\p{Xps} \p{Xwd}+\p{Xuc} \p{Xuc}+\p{Xuc} \p{Xuc}+\P{Xuc}/BWZx +------------------------------------------------------------------ + Bra + prop Xuc + + prop Any + prop Xuc + + prop L& + prop Xuc + + prop L + prop Xuc + + prop Lu + prop Xuc + + prop Han + prop Xuc + + prop Xan + prop Xuc + + prop Xsp + prop Xuc + + prop Xps + prop Xwd + + prop Xuc + prop Xuc + + prop Xuc + prop Xuc ++ + notprop Xuc + Ket + End +------------------------------------------------------------------ + +/\p{N}+\p{Ll} \p{N}+\p{Nd} \p{N}+\P{Nd}/BWZx +------------------------------------------------------------------ + Bra + prop N ++ + prop Ll + prop N + + prop Nd + prop N + + notprop Nd + Ket + End +------------------------------------------------------------------ + +/\p{Xan}+\p{L} \p{Xan}+\p{N} \p{Xan}+\p{C} \p{Xan}+\P{L} \P{Xan}+\p{N} \p{Xan}+\P{C}/BWZx +------------------------------------------------------------------ + Bra + prop Xan + + prop L + prop Xan + + prop N + prop Xan ++ + prop C + prop Xan + + notprop L + notprop Xan ++ + prop N + prop Xan + + notprop C + Ket + End +------------------------------------------------------------------ + +/\p{L}+\p{Xan} \p{N}+\p{Xan} \p{C}+\p{Xan} \P{L}+\p{Xan} \p{N}+\p{Xan} \P{C}+\p{Xan} \p{L}+\P{Xan}/BWZx +------------------------------------------------------------------ + Bra + prop L + + prop Xan + prop N + + prop Xan + prop C ++ + prop Xan + notprop L + + prop Xan + prop N + + prop Xan + notprop C + + prop Xan + prop L ++ + notprop Xan + Ket + End +------------------------------------------------------------------ + +/\p{Xan}+\p{Lu} \p{Xan}+\p{Nd} \p{Xan}+\p{Cc} \p{Xan}+\P{Ll} \P{Xan}+\p{No} \p{Xan}+\P{Cf}/BWZx +------------------------------------------------------------------ + Bra + prop Xan + + prop Lu + prop Xan + + prop Nd + prop Xan ++ + prop Cc + prop Xan + + notprop Ll + notprop Xan ++ + prop No + prop Xan + + notprop Cf + Ket + End +------------------------------------------------------------------ + +/\p{Lu}+\p{Xan} \p{Nd}+\p{Xan} \p{Cs}+\p{Xan} \P{Lt}+\p{Xan} \p{Nl}+\p{Xan} \P{Cc}+\p{Xan} \p{Lt}+\P{Xan}/BWZx +------------------------------------------------------------------ + Bra + prop Lu + + prop Xan + prop Nd + + prop Xan + prop Cs ++ + prop Xan + notprop Lt + + prop Xan + prop Nl + + prop Xan + notprop Cc + + prop Xan + prop Lt ++ + notprop Xan + Ket + End +------------------------------------------------------------------ + +/\w+\p{P} \w+\p{Po} \w+\s \p{Xan}+\s \s+\p{Xan} \s+\w/BWZx +------------------------------------------------------------------ + Bra + prop Xwd + + prop P + prop Xwd + + prop Po + prop Xwd ++ + prop Xsp + prop Xan ++ + prop Xsp + prop Xsp ++ + prop Xan + prop Xsp ++ + prop Xwd + Ket + End +------------------------------------------------------------------ + +/\w+\P{P} \W+\p{Po} \w+\S \P{Xan}+\s \s+\P{Xan} \s+\W/BWZx +------------------------------------------------------------------ + Bra + prop Xwd + + notprop P + notprop Xwd + + prop Po + prop Xwd + + notprop Xsp + notprop Xan + + prop Xsp + prop Xsp + + notprop Xan + prop Xsp + + notprop Xwd + Ket + End +------------------------------------------------------------------ + +/\w+\p{Po} \w+\p{Pc} \W+\p{Po} \W+\p{Pc} \w+\P{Po} \w+\P{Pc}/BWZx +------------------------------------------------------------------ + Bra + prop Xwd + + prop Po + prop Xwd ++ + prop Pc + notprop Xwd + + prop Po + notprop Xwd + + prop Pc + prop Xwd + + notprop Po + prop Xwd + + notprop Pc + Ket + End +------------------------------------------------------------------ + +/\p{Nl}+\p{Xan} \P{Nl}+\p{Xan} \p{Nl}+\P{Xan} \P{Nl}+\P{Xan}/BWZx +------------------------------------------------------------------ + Bra + prop Nl + + prop Xan + notprop Nl + + prop Xan + prop Nl ++ + notprop Xan + notprop Nl + + notprop Xan + Ket + End +------------------------------------------------------------------ + +/\p{Xan}+\p{Nl} \P{Xan}+\p{Nl} \p{Xan}+\P{Nl} \P{Xan}+\P{Nl}/BWZx +------------------------------------------------------------------ + Bra + prop Xan + + prop Nl + notprop Xan ++ + prop Nl + prop Xan + + notprop Nl + notprop Xan + + notprop Nl + Ket + End +------------------------------------------------------------------ + +/\p{Xan}+\p{Nd} \P{Xan}+\p{Nd} \p{Xan}+\P{Nd} \P{Xan}+\P{Nd}/BWZx +------------------------------------------------------------------ + Bra + prop Xan + + prop Nd + notprop Xan ++ + prop Nd + prop Xan + + notprop Nd + notprop Xan + + notprop Nd + Ket + End +------------------------------------------------------------------ + +/-- End auto-possessification tests --/ + +/\w+/8CWBZ +------------------------------------------------------------------ + Bra + Callout 255 0 3 + prop Xwd ++ + Callout 255 3 0 + Ket + End +------------------------------------------------------------------ + abcd +--->abcd + +0 ^ \w+ + +3 ^ ^ + 0: abcd + +/[\p{N}]?+/BZO +------------------------------------------------------------------ + Bra + [\p{N}]?+ + Ket + End +------------------------------------------------------------------ + +/[\p{L}ab]{2,3}+/BZO +------------------------------------------------------------------ + Bra + [ab\p{L}]{2,3}+ + Ket + End +------------------------------------------------------------------ + +/\D+\X \d+\X \S+\X \s+\X \W+\X \w+\X \C+\X \R+\X \H+\X \h+\X \V+\X \v+\X a+\X \n+\X .+\X/BZx +------------------------------------------------------------------ + Bra + \D+ + extuni + \d+ + extuni + \S+ + extuni + \s+ + extuni + \W+ + extuni + \w+ + extuni + AllAny+ + extuni + \R+ + extuni + \H+ + extuni + \h+ + extuni + \V+ + extuni + \v+ + extuni + a+ + extuni + \x0a+ + extuni + Any+ + extuni + Ket + End +------------------------------------------------------------------ + +/.+\X/BZxs +------------------------------------------------------------------ + Bra + AllAny+ + extuni + Ket + End +------------------------------------------------------------------ + +/\X+$/BZxm +------------------------------------------------------------------ + Bra + extuni+ + /m $ + Ket + End +------------------------------------------------------------------ + +/\X+\D \X+\d \X+\S \X+\s \X+\W \X+\w \X+. \X+\C \X+\R \X+\H \X+\h \X+\V \X+\v \X+\X \X+\Z \X+\z \X+$/BZx +------------------------------------------------------------------ + Bra + extuni+ + \D + extuni+ + \d + extuni+ + \S + extuni+ + \s + extuni+ + \W + extuni+ + \w + extuni+ + Any + extuni+ + AllAny + extuni+ + \R + extuni+ + \H + extuni+ + \h + extuni+ + \V + extuni+ + \v + extuni+ + extuni + extuni+ + \Z + extuni++ + \z + extuni+ + $ + Ket + End +------------------------------------------------------------------ + +/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/8WBZ +------------------------------------------------------------------ + Bra + prop Nd ++ + prop Xsp {0,5}+ + = + prop Xsp *+ + notprop Xsp ? + = + prop Xwd {0,4}+ + notprop Xwd *+ + Ket + End +------------------------------------------------------------------ + +/[RST]+/8iWBZ +------------------------------------------------------------------ + Bra + [R-Tr-t\x{17f}]++ + Ket + End +------------------------------------------------------------------ + +/[R-T]+/8iWBZ +------------------------------------------------------------------ + Bra + [R-Tr-t\x{17f}]++ + Ket + End +------------------------------------------------------------------ + +/[Q-U]+/8iWBZ +------------------------------------------------------------------ + Bra + [Q-Uq-u\x{17f}]++ + Ket + End +------------------------------------------------------------------ /-- End of testinput7 --/ diff --git a/tools/pcre/testdata/testoutput8 b/tools/pcre/testdata/testoutput8 index 73e0eae8..3861ea41 100644 --- a/tools/pcre/testdata/testoutput8 +++ b/tools/pcre/testdata/testoutput8 @@ -1,5 +1,8 @@ -/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). - The -dfa flag must be used with pcretest when running it. --/ +/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(), + excluding UTF and Unicode property support. The -dfa flag must be used with + pcretest when running it. --/ + +< forbid 8W /abc/ abc @@ -25,7 +28,7 @@ No match ab No match -/a*/ +/a*/O a 0: a 1: @@ -49,7 +52,7 @@ No match 16: a 17: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -341,7 +344,7 @@ No match axyzq No match -/[^a]+/ +/[^a]+/O bac 0: b bcdefax @@ -359,7 +362,7 @@ No match aaaaa No match -/[^a]*/ +/[^a]*/O bac 0: b 1: @@ -380,7 +383,7 @@ No match aaaaa 0: -/[^a]{3,5}/ +/[^a]{3,5}/O xyz 0: xyz awxyza @@ -408,29 +411,18 @@ No match /\d*/ 1234b567 0: 1234 - 1: 123 - 2: 12 - 3: 1 - 4: xyz 0: /\D*/ a1234b567 0: a - 1: xyz 0: xyz - 1: xy - 2: x - 3: /\d+/ ab1234c56 0: 1234 - 1: 123 - 2: 12 - 3: 1 *** Failers No match xyz @@ -439,19 +431,8 @@ No match /\D+/ ab123c56 0: ab - 1: a *** Failers 0: *** Failers - 1: *** Failer - 2: *** Faile - 3: *** Fail - 4: *** Fai - 5: *** Fa - 6: *** F - 7: *** - 8: *** - 9: ** -10: * 789 No match @@ -478,9 +459,6 @@ No match /a+/ aaaa 0: aaaa - 1: aaa - 2: aa - 3: a /^.*xyz/ xyz @@ -886,9 +864,6 @@ No match 0: aaabcd 0: aaa - 1: aa - 2: a - 3: xyz 0: xyz 1: @@ -985,7 +960,7 @@ Partial match: abc xyzfo\P No match foob\P\>2 -Partial match: foob +Partial match at offset 3: foob foobar...\R\P\>4 0: ar xyzfo\P @@ -1577,18 +1552,6 @@ No match /^[.^$|()*+?{,}]+/ .^\$(*+)|{?,?} 0: .^$(*+)|{?,?} - 1: .^$(*+)|{?,? - 2: .^$(*+)|{?, - 3: .^$(*+)|{? - 4: .^$(*+)|{ - 5: .^$(*+)| - 6: .^$(*+) - 7: .^$(*+ - 8: .^$(* - 9: .^$( -10: .^$ -11: .^ -12: . /^a*\w/ z @@ -1744,38 +1707,16 @@ No match /foo(?!bar)(.*)/ foobar is foolish see? 0: foolish see? - 1: foolish see - 2: foolish se - 3: foolish s - 4: foolish - 5: foolish - 6: foolis - 7: fooli - 8: fool - 9: foo /(?:(?!foo)...|^.{0,2})bar(.*)/ foobar crowbar etc 0: rowbar etc - 1: rowbar et - 2: rowbar e - 3: rowbar - 4: rowbar barrel 0: barrel - 1: barre - 2: barr - 3: bar 2barrel 0: 2barrel - 1: 2barre - 2: 2barr - 3: 2bar A barrel 0: A barrel - 1: A barre - 2: A barr - 3: A bar /^(\D*)(?=\d)(?!123)/ abc456 @@ -1820,7 +1761,7 @@ No match the abc No match -/^[ab]{1,3}(ab*|b)/ +/^[ab]{1,3}(ab*|b)/O aabbbbb 0: aabbbbb 1: aabbbb @@ -1829,7 +1770,7 @@ No match 4: aab 5: aa -/^[ab]{1,3}?(ab*|b)/ +/^[ab]{1,3}?(ab*|b)/O aabbbbb 0: aabbbbb 1: aabbbb @@ -1838,7 +1779,7 @@ No match 4: aab 5: aa -/^[ab]{1,3}?(ab*?|b)/ +/^[ab]{1,3}?(ab*?|b)/O aabbbbb 0: aabbbbb 1: aabbbb @@ -1847,7 +1788,7 @@ No match 4: aab 5: aa -/^[ab]{1,3}(ab*?|b)/ +/^[ab]{1,3}(ab*?|b)/O aabbbbb 0: aabbbbb 1: aabbbb @@ -2705,10 +2646,6 @@ No match /\0*/ \0\0\0\0 0: \x00\x00\x00\x00 - 1: \x00\x00\x00 - 2: \x00\x00 - 3: \x00 - 4: /A\x0{2,3}Z/ The A\x0\x0Z @@ -2760,56 +2697,14 @@ No match /([^.]*)\.([^:]*):[T ]+(.*)/ track1.title:TBlah blah blah 0: track1.title:TBlah blah blah - 1: track1.title:TBlah blah bla - 2: track1.title:TBlah blah bl - 3: track1.title:TBlah blah b - 4: track1.title:TBlah blah - 5: track1.title:TBlah blah - 6: track1.title:TBlah bla - 7: track1.title:TBlah bl - 8: track1.title:TBlah b - 9: track1.title:TBlah -10: track1.title:TBlah -11: track1.title:TBla -12: track1.title:TBl -13: track1.title:TB -14: track1.title:T /([^.]*)\.([^:]*):[T ]+(.*)/i track1.title:TBlah blah blah 0: track1.title:TBlah blah blah - 1: track1.title:TBlah blah bla - 2: track1.title:TBlah blah bl - 3: track1.title:TBlah blah b - 4: track1.title:TBlah blah - 5: track1.title:TBlah blah - 6: track1.title:TBlah bla - 7: track1.title:TBlah bl - 8: track1.title:TBlah b - 9: track1.title:TBlah -10: track1.title:TBlah -11: track1.title:TBla -12: track1.title:TBl -13: track1.title:TB -14: track1.title:T /([^.]*)\.([^:]*):[t ]+(.*)/i track1.title:TBlah blah blah 0: track1.title:TBlah blah blah - 1: track1.title:TBlah blah bla - 2: track1.title:TBlah blah bl - 3: track1.title:TBlah blah b - 4: track1.title:TBlah blah - 5: track1.title:TBlah blah - 6: track1.title:TBlah bla - 7: track1.title:TBlah bl - 8: track1.title:TBlah b - 9: track1.title:TBlah -10: track1.title:TBlah -11: track1.title:TBla -12: track1.title:TBl -13: track1.title:TB -14: track1.title:T /^[W-c]+$/ WXY_^abc @@ -2882,13 +2777,10 @@ No match 0: b c::b 0: :: - 1: : /[-az]+/ az- 0: az- - 1: az - 2: a *** Failers 0: a b @@ -2897,8 +2789,6 @@ No match /[az-]+/ za- 0: za- - 1: za - 2: z *** Failers 0: a b @@ -2907,8 +2797,6 @@ No match /[a\-z]+/ a-z 0: a-z - 1: a- - 2: a *** Failers 0: a b @@ -2917,20 +2805,10 @@ No match /[a-z]+/ abcdxyz 0: abcdxyz - 1: abcdxy - 2: abcdx - 3: abcd - 4: abc - 5: ab - 6: a /[\d-]+/ 12-34 0: 12-34 - 1: 12-3 - 2: 12- - 3: 12 - 4: 1 *** Failers No match aaa @@ -2939,11 +2817,6 @@ No match /[\d-z]+/ 12-34z 0: 12-34z - 1: 12-34 - 2: 12-3 - 3: 12- - 4: 12 - 5: 1 *** Failers No match aaa @@ -3027,18 +2900,22 @@ No match abc\100\60 0: abc@0 -/abc\81/ - abc\081 - 0: abc\x0081 - abc\0\x38\x31 - 0: abc\x0081 - -/abc\91/ - abc\091 - 0: abc\x0091 - abc\0\x39\x31 - 0: abc\x0091 - +/^A\8B\9C$/ + A8B9C + 0: A8B9C + *** Failers +No match + A\08B\09C +No match + +/^[A\8B\9C]+$/ + A8B9C + 0: A8B9C + *** Failers +No match + A8B9C\x00 +No match + /(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ abcdefghijk\12S 0: abcdefghijk\x0aS @@ -3077,16 +2954,13 @@ No match 1: baNOTccc 2: baNOTcc 3: baNOTc - 4: baNOT baNOTcccd 0: baNOTccc 1: baNOTcc 2: baNOTc - 3: baNOT baNOTccd 0: baNOTcc 1: baNOTc - 2: baNOT bacccd 0: baccc *** Failers @@ -3096,7 +2970,6 @@ No match 3: *** Fail 4: *** Fai 5: *** Fa - 6: *** F anything No match b\bc @@ -3115,23 +2988,14 @@ No match /[^a]+/ AAAaAbc 0: AAA - 1: AA - 2: A /[^a]+/i AAAaAbc 0: bc - 1: b /[^a]+/ bbb\nccc 0: bbb\x0accc - 1: bbb\x0acc - 2: bbb\x0ac - 3: bbb\x0a - 4: bbb - 5: bb - 6: b /[^k]$/ abc @@ -3208,20 +3072,8 @@ No match /(\.\d\d[1-9]?)\d+/ 1.230003938 0: .230003938 - 1: .23000393 - 2: .2300039 - 3: .230003 - 4: .23000 - 5: .2300 - 6: .230 1.875000282 0: .875000282 - 1: .87500028 - 2: .8750002 - 3: .875000 - 4: .87500 - 5: .8750 - 6: .875 1.235 0: .235 @@ -3243,10 +3095,6 @@ No match /\b(foo)\s+(\w+)/i Food is on the foo table 0: foo table - 1: foo tabl - 2: foo tab - 3: foo ta - 4: foo t /foo(.*)bar/ The food is under the bar in the barn. @@ -3258,9 +3106,9 @@ No match 0: food is under the bar in the bar 1: food is under the bar -/(.*)(\d*)/ +/(.*)(\d*)/O I have 2 numbers: 53147 -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: I have 2 numbers: 53147 1: I have 2 numbers: 5314 2: I have 2 numbers: 531 @@ -3287,15 +3135,11 @@ Matched, but too many subsidiary matches /(.*)(\d+)/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 - 1: I have 2 numbers: 5314 - 2: I have 2 numbers: 531 - 3: I have 2 numbers: 53 - 4: I have 2 numbers: 5 - 5: I have 2 + 1: I have 2 -/(.*?)(\d*)/ +/(.*?)(\d*)/O I have 2 numbers: 53147 -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: I have 2 numbers: 53147 1: I have 2 numbers: 5314 2: I have 2 numbers: 531 @@ -3322,11 +3166,7 @@ Matched, but too many subsidiary matches /(.*?)(\d+)/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 - 1: I have 2 numbers: 5314 - 2: I have 2 numbers: 531 - 3: I have 2 numbers: 53 - 4: I have 2 numbers: 5 - 5: I have 2 + 1: I have 2 /(.*)(\d+)$/ I have 2 numbers: 53147 @@ -3738,13 +3578,8 @@ No match 0: a ab 0: ab - 1: a abbbb 0: abbbb - 1: abbb - 2: abb - 3: ab - 4: a *** Failers 0: a bbbbb @@ -3930,19 +3765,8 @@ No match /(?>(\.\d\d[1-9]?))\d+/ 1.230003938 0: .230003938 - 1: .23000393 - 2: .2300039 - 3: .230003 - 4: .23000 - 5: .2300 - 6: .230 1.875000282 0: .875000282 - 1: .87500028 - 2: .8750002 - 3: .875000 - 4: .87500 - 5: .8750 *** Failers No match 1.235 @@ -4561,7 +4385,6 @@ No match /.{3,4}/ abbbbc 0: abbb - 1: abb /ab{0,}bc/ abbbbc @@ -4929,9 +4752,6 @@ No match /[^ab]*/ cde 0: cde - 1: cd - 2: c - 3: /abc/ *** Failers @@ -4966,7 +4786,6 @@ No match /ab*/ xabyabbbz 0: ab - 1: a xayabbbz 0: a @@ -4995,8 +4814,7 @@ No match /a([bc]*)c*/ abc 0: abc - 1: ab - 2: a + 1: a /a([bc]*)(c*d)/ abcd @@ -5033,10 +4851,6 @@ No match /[a-zA-Z_][a-zA-Z0-9_]*/ alpha 0: alpha - 1: alph - 2: alp - 3: al - 4: a /^a(bc+|b[eh])g|.h$/ abh @@ -5079,8 +4893,6 @@ No match /(.*)c(.*)/ abcde 0: abcde - 1: abcd - 2: abc /\((.*), (.*)\)/ (a, b) @@ -5395,9 +5207,6 @@ No match /[^ab]*/i CDE 0: CDE - 1: CD - 2: C - 3: /abc/i @@ -5427,7 +5236,6 @@ No match /ab*/i XABYABBBZ 0: AB - 1: A XAYABBBZ 0: A @@ -5458,8 +5266,7 @@ No match /a([bc]*)c*/i ABC 0: ABC - 1: AB - 2: A + 1: A /a([bc]*)(c*d)/i ABCD @@ -5490,10 +5297,6 @@ No match /[a-zA-Z_][a-zA-Z0-9_]*/i ALPHA 0: ALPHA - 1: ALPH - 2: ALP - 3: AL - 4: A /^a(bc+|b[eh])g|.h$/i ABH @@ -5546,8 +5349,6 @@ No match /(.*)c(.*)/i ABCDE 0: ABCDE - 1: ABCD - 2: ABC /\((.*), (.*)\)/i (A, B) @@ -6052,17 +5853,14 @@ No match /([[:]+)/ a:[b]: 0: :[ - 1: : /([[=]+)/ a=[b]= 0: =[ - 1: = /([[.]+)/ a.[b]. 0: .[ - 1: . /((?>a+)b)/ aaab @@ -6196,26 +5994,12 @@ No match /a*/g abbab 0: a - 1: 0: 0: 0: a - 1: 0: 0: -/^[a-\d]/ - abcde - 0: a - -things - 0: - - 0digit - 0: 0 - *** Failers -No match - bcdef -No match - /^[\d-a]/ abcde 0: a @@ -6231,36 +6015,22 @@ No match /[[:space:]]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09\x0a\x0c\x0d\x0b - 1: \x09\x0a\x0c\x0d - 2: \x09\x0a\x0c - 3: \x09\x0a - 4: \x09 - 5: /[[:blank:]]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09 - 1: /[\s]+/ > \x09\x0a\x0c\x0d\x0b< - 0: \x09\x0a\x0c\x0d - 1: \x09\x0a\x0c - 2: \x09\x0a - 3: \x09 - 4: + 0: \x09\x0a\x0c\x0d\x0b /\s+/ > \x09\x0a\x0c\x0d\x0b< - 0: \x09\x0a\x0c\x0d - 1: \x09\x0a\x0c - 2: \x09\x0a - 3: \x09 - 4: + 0: \x09\x0a\x0c\x0d\x0b /a b/x ab -No match + 0: ab /(?!\A)x/m a\nxb\n @@ -6563,8 +6333,6 @@ Partial match: 123 /Content-Type\x3A[^\r\n]{6,}/ Content-Type:xxxxxyyy 0: Content-Type:xxxxxyyy - 1: Content-Type:xxxxxyy - 2: Content-Type:xxxxxy /Content-Type\x3A[^\r\n]{6,}z/ Content-Type:xxxxxyyyz @@ -6661,66 +6429,22 @@ No match /.*/ 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 @@ -7033,10 +6757,8 @@ No match /\H*\h+\V?\v{3,4}/ \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a 0: \x09 \xa0X\x0a\x0b\x0c\x0d - 1: \x09 \xa0X\x0a\x0b\x0c \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a 0: \x09 \xa0\x0a\x0b\x0c\x0d - 1: \x09 \xa0\x0a\x0b\x0c \x09\x20\xa0\x0a\x0b\x0c 0: \x09 \xa0\x0a\x0b\x0c ** Failers @@ -7047,7 +6769,6 @@ No match /\H{3,4}/ XY ABCDE 0: ABCD - 1: ABC XY PQR ST 0: PQR @@ -7466,17 +7187,17 @@ Error -16 (item unsupported for DFA matching) xyzabc123pqr 0: 123 xyzabc12\P -Partial match: abc12 +Partial match at offset 6: abc12 xyzabc12\P\P -Partial match: abc12 +Partial match at offset 6: abc12 /\babc\b/ +++abc+++ 0: abc +++ab\P -Partial match: +ab +Partial match at offset 3: +ab +++ab\P\P -Partial match: +ab +Partial match at offset 3: +ab /(?=C)/g+ ABCDECBA @@ -7511,7 +7232,7 @@ No options No first char No need char Subject length lower bound = 3 -Starting byte set: a d x +Starting chars: a d x terhjk;abcdaadsfe 0: abc the quick xyz brown fox @@ -7531,15 +7252,11 @@ No match xxxxabcd\P 0: abcd 0+ - 1: abc xxxxabcd\P\P Partial match: abcd dddxxx\R 0: ddd 0+ xxx - 1: dd - 2: d - 3: xxxxabcd\P\P Partial match: abcd xxx\R @@ -7549,27 +7266,22 @@ Partial match: abcd /abcd*/i xxxxabcd\P 0: abcd - 1: abc xxxxabcd\P\P Partial match: abcd XXXXABCD\P 0: ABCD - 1: ABC XXXXABCD\P\P Partial match: ABCD /abc\d*/ xxxxabc1\P 0: abc1 - 1: abc xxxxabc1\P\P Partial match: abc1 /abc[de]*/ xxxxabcde\P 0: abcde - 1: abcd - 2: abc xxxxabcde\P\P Partial match: abcde @@ -7625,7 +7337,7 @@ Error -16 (item unsupported for DFA matching) /(?<=abc)def/ abc\P\P -Partial match: abc +Partial match at offset 3: abc /abc$/ abc @@ -7684,11 +7396,8 @@ Partial match: abc /.+/ abc\>0 0: abc - 1: ab - 2: a abc\>1 0: bc - 1: b abc\>2 0: c abc\>3 @@ -7811,10 +7520,6 @@ No match /^(?!a){0}\w+/ aaaaa 0: aaaaa - 1: aaaa - 2: aaa - 3: aa - 4: a /(?<=(abc))?xyz/ abcxyz @@ -7846,9 +7551,9 @@ Error -17 (backreference condition or recursion test not supported for DFA match aaaabcde Error -26 (nested recursion at the same subject position) -/(a+)/ +/(a+)/O \O6aaaa -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: aaaa 1: aaa 2: aa @@ -7971,7 +7676,6 @@ Partial match: \x0d Partial match: \x0d\x0d \r\r\r\P 0: \x0d\x0d\x0d - 1: \x0d\x0d \r\r\r\P\P Partial match: \x0d\x0d\x0d @@ -8016,4 +7720,61 @@ Error -30 (invalid data in workspace for DFA restart) 0: xx\xa0xxxxxabcd 1: xx\xa0xxxxxabc +/abcd/ + abcd\O0 +Matched, but offsets vector is too small to show all matches + +/-- These tests show up auto-possessification --/ + +/[ab]*/ + aaaa + 0: aaaa + +/[ab]*?/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + 4: + +/[ab]?/ + aaaa + 0: a + +/[ab]??/ + aaaa + 0: a + 1: + +/[ab]+/ + aaaa + 0: aaaa + +/[ab]+?/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/[ab]{2,3}/ + aaaa + 0: aaa + +/[ab]{2,3}?/ + aaaa + 0: aaa + 1: aa + +/[ab]{2,}/ + aaaa + 0: aaaa + +/[ab]{2,}?/ + aaaa + 0: aaaa + 1: aaa + 2: aa + /-- End of testinput8 --/ diff --git a/tools/pcre/testdata/testoutput9 b/tools/pcre/testdata/testoutput9 index 95cd618d..efbbf180 100644 --- a/tools/pcre/testdata/testoutput9 +++ b/tools/pcre/testdata/testoutput9 @@ -1,6 +1,8 @@ /-- This set of tests checks UTF-8 support with the DFA matching functionality - of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running - it. --/ + of pcre_dfa_exec(), excluding Unicode property support. The -dfa flag must + be used with pcretest when running it. --/ + +< forbid W /\x{100}ab/8 \x{100}ab @@ -313,13 +315,9 @@ No match /[^a]+/8g bcd 0: bcd - 1: bc - 2: b \x{100}aY\x{256}Z 0: \x{100} 0: Y\x{256}Z - 1: Y\x{256} - 2: Y /^[^a]{2}/8 \x{100}bc @@ -328,8 +326,6 @@ No match /^[^a]{2,}/8 \x{100}bcAa 0: \x{100}bcA - 1: \x{100}bc - 2: \x{100}b /^[^a]{2,}?/8 \x{100}bca @@ -339,13 +335,9 @@ No match /[^a]+/8ig bcd 0: bcd - 1: bc - 2: b \x{100}aY\x{256}Z 0: \x{100} 0: Y\x{256}Z - 1: Y\x{256} - 2: Y /^[^a]{2}/8i \x{100}bc @@ -354,7 +346,6 @@ No match /^[^a]{2,}/8i \x{100}bcAa 0: \x{100}bc - 1: \x{100}b /^[^a]{2,}?/8i \x{100}bca @@ -370,28 +361,18 @@ No match 0: \x{100}\x{100} 0: \x{100} - 1: /\x{100}{0,3}/8 \x{100}\x{100} 0: \x{100}\x{100} - 1: \x{100} - 2: \x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100} - 1: \x{100}\x{100} - 2: \x{100} - 3: /\x{100}*/8 abce 0: \x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100}\x{100} - 1: \x{100}\x{100}\x{100} - 2: \x{100}\x{100} - 3: \x{100} - 4: /\x{100}{1,1}/8 abcd\x{100}\x{100}\x{100}\x{100} @@ -400,15 +381,10 @@ No match /\x{100}{1,3}/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100} - 1: \x{100}\x{100} - 2: \x{100} /\x{100}+/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100}\x{100} - 1: \x{100}\x{100}\x{100} - 2: \x{100}\x{100} - 3: \x{100} /\x{100}{3}/8 abcd\x{100}\x{100}\x{100}XX @@ -417,10 +393,8 @@ No match /\x{100}{3,5}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100}\x{100}\x{100} - 1: \x{100}\x{100}\x{100}\x{100} - 2: \x{100}\x{100}\x{100} -/\x{100}{3,}/8 +/\x{100}{3,}/8O abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100} @@ -432,9 +406,9 @@ No match Xyyya\x{100}\x{100}bXzzz 0: X -/\D*/8 +/\D*/8O aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -458,9 +432,9 @@ Matched, but too many subsidiary matches 20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/\D*/8 +/\D*/8O \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -Matched, but too many subsidiary matches +Matched, but offsets vector is too small to show all matches 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 2: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} @@ -507,33 +481,18 @@ Matched, but too many subsidiary matches /\D+/8 12abcd34 0: abcd - 1: abc - 2: ab - 3: a *** Failers 0: *** Failers - 1: *** Failer - 2: *** Faile - 3: *** Fail - 4: *** Fai - 5: *** Fa - 6: *** F - 7: *** - 8: *** - 9: ** -10: * 1234 No match /\D{2,3}/8 12abcd34 0: abc - 1: ab 12ab34 0: ab *** Failers 0: *** - 1: ** 1234 No match 12a34 @@ -556,7 +515,6 @@ No match /\d+/8 12abcd34 0: 12 - 1: 1 *** Failers No match @@ -565,7 +523,6 @@ No match 0: 12 1234abcd 0: 123 - 1: 12 *** Failers No match 1.4 @@ -585,30 +542,18 @@ No match /\S+/8 12abcd34 0: 12abcd34 - 1: 12abcd3 - 2: 12abcd - 3: 12abc - 4: 12ab - 5: 12a - 6: 12 - 7: 1 *** Failers 0: *** - 1: ** - 2: * \ \ No match /\S{2,3}/8 12abcd34 0: 12a - 1: 12 1234abcd 0: 123 - 1: 12 *** Failers 0: *** - 1: ** \ \ No match @@ -654,15 +599,8 @@ No match /\w+/8 12 34 0: 12 - 1: 1 *** Failers 0: Failers - 1: Failer - 2: Faile - 3: Fail - 4: Fai - 5: Fa - 6: F +++=*! No match @@ -671,10 +609,8 @@ No match 0: ab abcd ce 0: abc - 1: ab *** Failers 0: Fai - 1: Fa a.b.c No match @@ -693,26 +629,18 @@ No match /\W+/8 12====34 0: ==== - 1: === - 2: == - 3: = *** Failers 0: *** - 1: *** - 2: ** - 3: * abcd No match /\W{2,3}/8 ab====cd 0: === - 1: == ab==cd 0: == *** Failers 0: *** - 1: ** a.b.c No match @@ -825,8 +753,6 @@ No match 0: \x{200} ab\x{200}\x{100}\x{200}\x{100}cd 0: \x{200}\x{100}\x{200} - 1: \x{200}\x{100} - 2: \x{200} *** Failers No match @@ -849,8 +775,6 @@ No match 0: \x{200} ab\x{200}\x{100}\x{200}\x{100}cd 0: \x{200}\x{100}\x{200} - 1: \x{200}\x{100} - 2: \x{200} *** Failers No match @@ -1126,21 +1050,21 @@ No match a\r No match -/\h+\V?\v{3,4}/8 +/\h+\V?\v{3,4}/8O \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} 1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c} -/\V?\v{3,4}/8 +/\V?\v{3,4}/8O \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a 0: X\x{0a}\x{0b}\x{0c}\x{0d} 1: X\x{0a}\x{0b}\x{0c} -/\h+\V?\v{3,4}/8 +/\h+\V?\v{3,4}/8O >\x09\x20\x{a0}X\x0a\x0a\x0a< 0: \x{09} \x{a0}X\x{0a}\x{0a}\x{0a} -/\V?\v{3,4}/8 +/\V?\v{3,4}/8O >\x09\x20\x{a0}X\x0a\x0a\x0a< 0: X\x{0a}\x{0a}\x{0a} @@ -1154,7 +1078,7 @@ No match \x{a0} X\x0a No match -/\H*\h+\V?\v{3,4}/8 +/\H*\h+\V?\v{3,4}/8O \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} 1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c} @@ -1178,7 +1102,7 @@ No match \x{2009} X\x0a No match -/\H*\h+\V?\v{3,4}/8 +/\H*\h+\V?\v{3,4}/8O \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a 0: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}\x{0d} 1: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c} @@ -1279,34 +1203,28 @@ No match /abcd*/8 xxxxabcd\P 0: abcd - 1: abc xxxxabcd\P\P Partial match: abcd /abcd*/i8 xxxxabcd\P 0: abcd - 1: abc xxxxabcd\P\P Partial match: abcd XXXXABCD\P 0: ABCD - 1: ABC XXXXABCD\P\P Partial match: ABCD /abc\d*/8 xxxxabc1\P 0: abc1 - 1: abc xxxxabc1\P\P Partial match: abc1 /abc[de]*/8 xxxxabcde\P 0: abcde - 1: abcd - 2: abc xxxxabcde\P\P Partial match: abcde @@ -1340,7 +1258,6 @@ Partial match: \x{0d} Partial match: \x{0d}\x{0d} \r\r\r\P 0: \x{0d}\x{0d}\x{0d} - 1: \x{0d}\x{0d} \r\r\r\P\P Partial match: \x{0d}\x{0d}\x{0d} @@ -1366,6 +1283,5 @@ Partial match: \x{0d}\x{0d}\x{0d} /[^\x{100}]+/8 \x{100}\x{101}X 0: \x{101}X - 1: \x{101} /-- End of testinput9 --/ diff --git a/tools/pcre/testdata/wintestoutput3 b/tools/pcre/testdata/wintestoutput3 index 00880070..456ad196 100644 --- a/tools/pcre/testdata/wintestoutput3 +++ b/tools/pcre/testdata/wintestoutput3 @@ -84,7 +84,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P +Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z /\w/ISLfrench @@ -93,7 +93,7 @@ No options No first char No need char Subject length lower bound = 1 -Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P +Starting chars: 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 ƒ Š Œ Ž š œ ž Ÿ ª ² ³ µ ¹ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý diff --git a/tools/pcre/ucp.h b/tools/pcre/ucp.h index 21039106..d8b34bfc 100644 --- a/tools/pcre/ucp.h +++ b/tools/pcre/ucp.h @@ -11,7 +11,10 @@ should always be at the end of each enum, for backwards compatibility. IMPORTANT: Note also that the specific numeric values of the enums have to be the same as the values that are generated by the maint/MultiStage2.py script, -where the equivalent property descriptive names are listed in vectors. */ +where the equivalent property descriptive names are listed in vectors. + +ALSO: The specific values of the first two enums are assumed for the table +called catposstab in pcre_compile.c. */ /* These are the general character categories. */ From 0714354f522163cb7e536389fc13a2da04ff768d Mon Sep 17 00:00:00 2001 From: Arkshine Date: Sat, 5 Jul 2014 20:33:58 +0200 Subject: [PATCH 06/18] Regex: Update compiled libraries and pcre.h to v8.35. --- dlls/regex/lib_darwin/libpcre.a | Bin 423288 -> 522712 bytes dlls/regex/lib_linux/libpcre.a | Bin 317868 -> 504594 bytes dlls/regex/lib_win/pcre.lib | Bin 419730 -> 454662 bytes dlls/regex/pcre.h | 698 +++++++++++++++++--------------- 4 files changed, 361 insertions(+), 337 deletions(-) diff --git a/dlls/regex/lib_darwin/libpcre.a b/dlls/regex/lib_darwin/libpcre.a index ac0167bb5aa5856a9200337b59a701e2467893d6..33b63dfc8a0c83477743cd3f8000e6ab5e01f371 100644 GIT binary patch literal 522712 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Ì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 QOqgB1sEmEHTT00P15Dn+{{R30 literal 423288 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

    wiO&I02UCS8suV@=SucuUTwBJdi`KHfK)!f= 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�mVDKi5{}~@Zhcx{(*xKr*6I&$drL&u5`1!H`%;Sr0L|Ww66z}FntPTv^ zFpRvJd*fj+tU&CL67j2BjH_;?K(#lU7>b|2APO8p9H08(|<=Zk@qJ!`4iUT#Bv& zk|27C`DDba{%<=CnBtUNdMqj}xQ5RrLGigfoXUeotj!dVJm^cVug3=UhTX%cygKL` z8g@@W|FmHz$F$|pu*Djx_}tM_v1dUBGfU>>j%~JJ#`8Y_4eUYZy*j{oGF^iY-^A6s@E{ z;aQRj)xgZx`8p?b2|HBbFF`N5$0J6WHTA@n-w^GXyVd0wJHunC|@gAN4NX8akon#$~7kc=Bl~A?f;l0{IjFVOIHQKS$=p9-@8kI`>%)v1%1imSq^E3y?MiO42|v`0L1mfA3C|)R2Kh#(>}ei5+0J)D%a0V= zIOVq>I_y+6>51sqwJ#@;k|D$R;2T48j0`nHt~_vTr*5sB^5^NZs7q(IyKo#mCj$>n zM;JlAE zru}@Ja!T_&y3yV0j{BTPnHa)M z3~;*X-V(tK0ztt68Fqd!-cToU>i`;bNp`GP3-=OOwS0hFEG~KYC(N3}!qQZY6*9=5 zr+-%-<5cd5ZVzpBnDJ-M^@uE-?v(r<0k5p+E5DH|G%gxuBINCnPWXh&1U1_+FqaI4 z(ALJ{tGEd+=s&`<=$pV+koj3`-Tt)DsVssD#_=W1)Qr+L`4bVf zym-%GykAb`TlA&0w0uA&93zx)TbdGTLR$w!mpe-y5Ubr;Qf!R%&-|c6I?16U(TEDk zXY6%(P-);*=hk4(ioDN%OK}qRS zA(kL2d6Uam#NFS47j>BLg{IQAp=vsUQED}5q)o3zYZr>UFJtRA*pb>U!B`&!W0NN) z7IS6K6U(oWRS2o9{F)Pa5|%3O^GNaTW=KG|$9M;+tPAmymq!`T^2ehzMgACpeRz~h zi!SR5e9xIxF40yYi`_iA@N48+2a-6ULR@ed9ay|7LF--a6Z-2LaS3DS7kwQ;Be`qa z>v$>L#a%w^y+^815K>J(FCzB`^=RaC{<6{u^*|GsrPOs(-zKjxekbdLP!!|PiP6VnZopsZXyi*ls;$)^>i-r@rYmup&cS1VqH|>F?SnHXd)u~HFKAfkXj^B@J|rL z^P(4iIPq||WgY#5eNxL^U(SplKV@>(IeCE*hEy$@CGC_RO{kYfz2J^&Gas`gv0>|p zL8o&my)Hc=e-lqc+KA+hT^)dRB-)EO zmax1j?-MHCo#~YHd=o)5!wH`!@Gh+GbASN58b#U!zp=Z-X}l z!3HP;Rkm+!MjhuJjXt8PO0W@fS!@?6U2Kq=b8jL{|A?$a z3PhJp-xm`+!aF)+LF~hg!Sm-llgArc?p07;#^XlOYxq8dtm$sbYP!;2gHj*-0%kK9 z*JOHKt#%VGb!Add;i|*U9w5&2HoDw-tP2a4k5$1(AGnnSwKVF}(pU&P=<>eg+8!zI z@ijV6qgsRS6*@C6E$#%qB!w zR^{*1y?wMhx3e`}LjR{q6+f%u?kEZn5d%kydI(pGrlDG*WbkIxTM%w$-H0BMi9hO>u=$wFJZ7O^)o?=2%*paAG8rm5L$N2rTRt~@ zm0&+viLBdtEjm9~$DWBPcio&;{IU484I3B!V_X?#z zPNTf+M5rT?ne;?t8^xn|_sbJ=c2?*7D#w%?+OQg~~*n^HDbiQ>X;txt7uN~gPLflhpACPcvf zy!$00;F1qgSpFk|T8o*R))4mi-7>l`ukoE2ceLpq9A~5QS2eBfbVaMEiFL{*b!6^Z zC0uJ`+*{H-J`<&2)&ykUt3Q90-yuaQEV)~(0GTFVca}sG z>vl3MaFvu9ZcjG=g!Sdm-HrQ**7YSUQSJx^W1>rvwwcI2PhsQaHI&myX*&NsJOed3 zPUP?*lBj_-6x)x{SH;ZV(<_GQf)?1Wt(?kXLQ{WIFfV{Q!Zn4NRryib)BfP ziPdncL!0ib-i`YpDvhe%+{Dk~KveVH&-t1{s`V$bt^;e2 zKHYnW_VA8O8r_59Osri>REA9fVDBWjZb`Tr#oW%T-nb*$OK zzOuBn;y$xzA?-c^jmnAqmmIO)Q_zD^(*oZ7A9NjkblChbGOhVKe=x+v((cJe!&;!VXM200^525D@2heD0>39W^aODC z=IfqgNE3OGGQA}$Gg}vTZj6dE!$dd6M36pLSG0e*JM$e1F#8f>FNxrZT{MMxNOZ`| zo5q2sNTJwE#k^s%6}JJkd+MpXo7%BQg;sb2SU!2xzpc|1EIVx_y=(}@lR-}y)oM&z zim+O}djpj!Y0b2>3;OejZY|6mf8L@exlo9*Lf)^uiU1Sj`XB1}G%Hz(3te2tZtVx(rD;_Z`Gw|XY- z|LV<+o33>K#2R1(9$aP}&vKV1v{JTm ze1EUxYr@X9!Wvpl$dX4r>bAMHZESyW5wuxsa4MULSLjtI@*yM^8ZDptFaF*YVICROa<2_hY#UFg#;N4 zuj!P`B4}d1Hd=nG+~~K)gscmF?cZARmgup;7d`49Nl6x;_)<*d@(_sj zabnO_o(iviC_!-P!rEh`e+AEZCb6jHg>N|F+Zp&m=bEV>cba3y3g2u1A6g=^UPj?n zFERiufqhQo3~W2T3M!+@nbiXs+#p7O9&LIbP0{dA_*hA(_S{}bFUn!wf1}?LCkgy} zY7aN~y~et!$(mWXJ!m|H>!5$4vv)EW(RJf%;NdxMBGfH%>N3y{r(_{@Z7V5P{D*VZ z2eae|P)YZ$2tKlBQ~QafL0P%R&9IFRPSZC_yuP`e`q)>q#K;%3S`xcNq>ON=Ct{Wu z5o4RqdWi}f7EdzAj$GxLCf}S;L!K9HH@*iE%EQW34HiiRN3qrE$}>?hZB$h@UN0t_?)4jc(z| zwf)FbBiDBF;5GDaDyzT>WJNA=F-egqY;kH*y~!LDvGPQONw$2Sne7uR0&&@LkvIjd z9M*x@t25fYdL`j)rU5V(C<#P{?_c z1-VHARLYzBE`6OMA^x+*Fz`@b3Ijh|W4Kh(7Jlf=y6$g=7meZ#ye_{QGK8(D}*pA%wrXRw$Dxn16`e5aG3>Xfya2fq|;rll74#hAleO-SUQr z5GTA5=<(q}%Zm+g^45XmOqLg)5w`T^+h6+}r}8R{l`7Vquuic?kw!AcXyzaRbIsWe zr*dWFEnU!bW`$wD&WAW9tARS%m<6;lDVgyDoDJF(TVX8sPASpB%}T&Su6JEmdiC8iYlgn)R>r|iSI8F)>zd;TM$TaH7+Qz zImcoB%S6TpE-F{rJ&8_9JB(~F5t|w`k0T`8*PqLVzSUw^%L=wVjU}5CwfVHKMd6#y zjEN+Zuf4rl^tD)1>!Ji<9NXxrF(r)qHLR1syl)ET)dSX)At|Ku*z2N2#i_z6x#BmeDb4NsBQ@CCHBCw!tb5% zX?Xb)=sRUYSynFG?UWSk61p8_R^w}Qyn9!fU* z=hr4Y5&`pJvDD84%XWl0Bu;Mg7;I?al^#27n=ge|yf$}{Hm`9<01l?vwNt?}(cYO} zd-JHGq4pk30~+{LpS0qEP--ilILfwS8ruz}=aO4-qiIF$-3Qf#U;_Uc9{$l^iNEv; znzD>j%XNbJt7({jaiqokmGA0fKF(tP$AiNB_VjTS$Nycb__g$}hyO;3P3E8WihtnX z@n2v?SKQh#5}~#p{-qxM|0no&Y9EnqNYMYPH2lY)Q|ZLul$^h#eka^yJK>&#=>%7J zKD{3*ymmZGRll|$LUn8;t%H-yj`gq2gMR0cZ!U$8Do*W{`&(JA8p~XmJ|3>K4T_2Y z&#p#BT1{sWWr{0QW)S4K%nz}NlM^bbOl#0U)Xm!CMpdwmVGkNifB|IA5R1ntd-y6U z=G!>mW8K?|i}$=d=`9u`KKy9{+6kd{Tw?r9^XPT~jcJH(p}H={l^Q%bRF@k(K2$d} zcy#&vp)_y$k3-h8`rR!5t@HMOMDPExrlRm$aRYafcP zck7r&E6&TyAyMh~;BsDD9w!`GUg6t>vrWE^dn-Dg%6oBb%q6H3I&JW|zU72j0)%wF z{8en5)8$S!gUhN4!GNS&5kNm=Luvl9gf6>`XJa3m?r~c%v0DBT*GD7RReO)FO4|G| z3Duddl!@0)x7HZ0?KBF#IH%~M2KTBhbHe*&8x!+6+tUJVlD4P)mhxnK+9W0i-JbS* zbXVEn%+r-O~>pMa?(+B5QEqONyr z?L_kN4`Or{DbuAMXB}krvo?vFc&qRPh-@DHfEfXz)ERPXowdi)PO(38Og^X3W&dtF zvS5Us1%&m*B(0hH9vLKa+#LOSDIJtBN2^%T_Ao_xLS2cQqq|r#Xb{&Cl|rxtu5XY~ za9wUQh(+cZk#-2>t&47C8_OPSN}){c(UyLN*ry$frL4@tx?r=y<(`fDnR+0=b13P> z>bMB0k)-)MVYdc;vVIRWRTJO-HTJ1U1t)w(e;Q$V8v8imLckhT>y)?gHRugn`%o;3 z`C`v-+d$a*fexdfGJ}8l=u9j%d%zy0Uz)_OP*l|Oo5n+O?q7UEHp2Y~zgA-XJZT`t z;zwG?QWIVogLcVHENr-giSatXI_zWJ+vM?;HmCH%SA_eo=*YLnB5(1`nndtWRx!^i zK+T9$5kp2PDsL%V5_#H27$dFTc{_P$<*j$NbuT=^7W)<6+16UZiZfH{es^g#LqOK+ zlI&n;BgNz9y9{&qAIK!@=G%o?Zp`6#u7oYD<>Jnu0LFby7BVz4oH+CUg(zkfdNgmFwkm@aY|gJqPEm@d|sp{3`u zp4PP5%_q0efeZ(3$BKmi;bzF6@H2L%F5{2cj3>0fRCsA1v?;TClet?V;Z8?vE=bT?(&c!n2h<$4XU^Cqi7n!;-l}6#0ZMx3aJ0*W-zUzF0Q~DU5 zAfpi#Ase53xK z1*V0uO3~~hJE4itf%A;8gQqr@77)-jbTU2#r{ol(P-P@>+^;aJ1(C@^d+UFUG>}AG z1F;ZQ0NEe}rM*G|XIA5>#5J@Ved9WlSZoW(CVfXT$qMxbNu;g2yyJ7=?QI5+?h}7n z<0NOmk%y4OIs^D@YPbnO@dgZONgf7JFaOIRcK6#%bRO0Mclh7I=#!~^6Cb=eEb`xnfvHk)6t6! ziRpczw0678+N#}`&lF*{O|Z(ih&bbTXw9@Liu6F%#8NjIsO#Z;X;A55{BK+j9e9YJ zKP~2#{S?ErK-WqvxH%z&_}nF<#-)&QMwW*P232Q8RyJ;MDj81CP40uE`J zQfi`WLtE0$kksIEfyV`P+vJ8k7OaA|7S9>&exs0$#mxxB+x;kfZbqedr$p&!nrprS zTRSVg)p7-TgWNIpZy@~*f-lY;Nv(G0fnZ#ZHhl3VW(tvpFOHE08@_nSG&sQ=%;NtG zuC^bY@X?G>|A(P!e-wDn-s-yZ|7uB5}n)&8JOD1a(`dE(e3bGqz>yF;+;G@y_1hGIzXd;SFe+k zhP5Zm#EYKPzjteU9kk0|$IsHg#^ZD?^1yhU2ABuW3VY1wj`NqiK8!@Y_{IwHKLjJ~GTy4e0g`aC^@c0xL zSBr#;OYQtUPIv)MmQ>FC6EShlti3Z$*e2$i*%i@s?j=W%;(_W|wFBzx{qj?}6BH~V1HKg

    Fa5#ba~4MxHT{`bi;9t=L$So*LI{u-xWOpE*Ig^A^(WyxEvAmn_lSf<(LIYX^f@06{3pRvo0 zK6~Df9NH8<4x*eVA1ragE#>iaiH+P!Q``(gFR{mkpBazR|IxJ!VR`Vj^kDx8Lx`Wi zsl0&8H?H=xWmo(VT$$jx9o}9T=cij?Of5l z(e=^S4|Fe=*~phAH3z<2Z8p zO++uW8J{y*Dkos$b+;Z9{|hM6|?sp%QqEeiTp<7l`m$^jG z9l@ifW}tHZjnu}kIFKVTy<`)1M+&vKFHD!_mA7e$bGB(=KW>gFdzSvUDPq$rcsVM+ zs_EKJe`pmoA*ZamwfW>B2M=rn+wR=;E2#V(_fz@^hB7GcT#$I)#xusfF#3^BcrV=7 z@Db^UPQhy>N2D)L-6rvO@?*z)7bj$P=B!Gu`@y?X2@Vta6zSfrNYfboFjhE09fV*C!jIGznPVVKQ&*aFpkq1kjNji!2{kCzwOI1A*48Od*P%|&uuA1sQ>yg zljWfO*H3=P$eAa76CRGjabEF}@;FEyBN7{Vo&;_m!bb0S&6GYc-M@{$#G{R%>AoTO zXW<}=Txl}&W^-zj>dh_1M}XIiJv4%Ows|)0bgv;#y)P>Xmo^G*@>g#%7wRVb#;ue5 z#@2^yx4hb2YJt!SxkK6Rfc-0^{a+~N5Sm?)+_!_COzqn~gz2-s(q|7MgS_W9O!vw8 zawMJlORsIgZo#~zvA~1Tz}?ZhcD;hA%`(WMJ?;)Tvpv{AxX~9Px|pbwX7msXgvR5+{mk2ereI zqpXMDfHGfnlPL06sNXc9$Rj+B;Ub6oIOoEt7jF^|&!$!Wy?D9fcugfnMNZ+6$?Qj> zW~Wllp_|P}lkPRjdF?+8&;DCjni^p^Iazm#**CrAe3&J=zWQ@EOgF7FgUdKlM2^Z3 z(%v&W<*xgi$Wf&wt@0VSq`7hH8Y;FP?MY3`d+(2iM9g_T-K#&76r1gx@Ne>w&_j&7 zCU~~Dt0(`xq>V{G=Oy#5=rPy9Iww#``gO2>MJ4o>%pT;Ki7~!p7A34L`c9^{iYMq- z^_q9@Bl_Nu`zZ3?Vt^(2@Tb%Lp1;0`=g_`{t9~TmtrBK4}1#G z6t(+V+hh`C^z1RSZuq8*&4XVzJcs;g<9ZKXQg2-ML4cWYeG=oEF=ZyV(vQvo%Vmih zL7~5h9{EeXha_pr%cUgJ#izVhMl@FK&y8$CzIaR!5`9Kgs^?kciE9iO%UR$+?513~ z6zWZMLg^c}phD2g%~|+$#7S>DPk)ekRfou`^2@jkDkw#C;fBDATfP*7FtenxHxfCOm-)@XD`cr;LWhiv=63w98RZx4 z=PoZB>pcBVX1@+HPR^htC6TO0VFO-eY2x>An3m@WnQOCSZ9p^vuEJq`vl zByT;#obe^I6T!af-hdQR4o&}e^oD>`v~U}!V4L5H-E#J%w`qd(g5oL?2Yq)lw# zQSm}iCL`Ec+HA%{{>r=Yov+q{QE8W2VX2s`g z9#nrW{ZA>8TbmjiXuTv8QAN>nszRL+r+hAzqfiAHG)Je^au~JHuU_gDEH%q#XqU-| zeK^mPH*#{IGW#7VpPCA|ymXGKWMNv41(E~*kx9=6XVS_+SCe*TTH0dLqA!6xWlO56 zPOZvq4JQ4dwDkQ<`riJ|?78cR_1C$n6K*e1{hx-wH3jtH@o71aOlpVYME1Xt+RR;# z#_5k|&-7ss5tti1PCR?9%PWS$*3i!f;L%Bqzz4l8{LUNTCMw@TMmtW|yVxp-_9^)L)kKZnRjVHQjEIG@8C4f~Pi#S(Z@u z-6{C=O!@~55ls4*glGpyFJ4W>Ea#M8)TXBsZMxRrcF;D?mkdAYr~HHLrxWNW#qrEv zhGXn)ThmP^9vnyfm6{OPqELG>E^R|pWSQ7sb&td`dcri~pxeHitzO!ePfq$p^xpp# zVqL8C=Pk8=jg>AJMXO)55rakjqIQ6PaUb>JzYEWGNpln}U*j zuq~5(u+|@I4Zz0nTMykvPn+gCkrs3u=a$?O=@G_wDMh2K2&GZ|n4jf|15c1$o)ER7 zh6F^YR$h)0asfKT)fqGAuJOry>D#uzda zwDtR|Qb+F_{imQpwwzw%Pr7v9+>f}z314z37}WUvI|{e)sR;t!38m0fO66FkUgKYF zY@dm%cUI>F|0TOl(J;73WK;H%#CVi4r5evtu6;z^AJ?6dDzTU}PpqVGlFt+Nco3Aeu7>u!)E*}D zW!xiv>j$*zpbry1{DAd1e{i}Gvip8^z(m)X-7Q7`?3xzrsYYtq{oa5L4oW*gkcU`^1^zi9&b}tNvAx) z)G>#jly^?XNIwDoaUvxo7Y!xlx{dNHGuZD}9oi)Kd_>nbbkherd!<(9R&(LU_$%E` zEYJ#FQTdF)3zu#OEV)xfNB`)jSAo^6jn?fE3^`aB%p>1yo zDOJ5rM#cf`yA&T*e;8cwHUp$6|L103FRu(9w>5c@Xhjpqb*^_sX7hS)-2&&%D0EriU9(k>?Ag><-=M>+mFlvL5cvtFWJE%G)%wb2sWW;(G_N;CC;M;>JYOqLu^%<=fb z%&?Pk&9MHZJXwBaBR3$+Le^46M4DBBKG{<*CQ6>mxhL0p8Oj3>LVXc8Iz3FtLlhYm z$3}y)7{@Do5MjUUja)uS?xoih#;ESnB5$p_7UTk6T%~pGx&^h`XpaX2cODX2DwmW= z)mSV(x9lm^DT1w>(i?hk?Yb|Ap08u=y%w>bOp<%=g(MSwr?xc-{7&f~=fauGNM)6h z@QXZRcb68mOD<-wq2Jb87Ne zb-o!9ahZsn@8zVa z&pqimi(ZjG89l7zYPN!do^(Cv1$0+Wn@mXG-SIHVeeU*( zxYpj-j98L`Bz#FT2jjANOg>m%FK8F~ezg2{7*)Z|SKL z&yKG8+>Dl^t3KDsqc8(I!7v-#%S8dQS_HCJI>FuYIqb_Fk?#3y%(W{#Qw@T>WQE5H zzxXnbn#yLGr&mUNv1;R6bcz@j6HXDj9sC5zApwtLzGYctK1ED3Mf48ncOX-ims;xb zQevsetRQ+zP2CxqD!+rqrW%+!#i@~NMEAhB=zcLE{qq&Js5i;!s;`~vwsz{ud6T?F z=2k7PmHD=grvlbpk0dI(%)RG%WyoxU_(j5yOBzvR;*^By+h&DJ^=+$rd&bU6_p=>H zl?{v(cR6F!-rh+WzELQ9?&(yK7IpW(=}6`%W*dB^p8$1S!-J30twqd?jH~dY2w;Wv2uQ9!s0Y>eOUR=m<-J;;`TyU4vnbXRzfj_$?$7% z)BMe4R%-9B7UO&tKuKm^J6dsUN1ac#T>;9z0@Xd zFOc5nhCxKx!Ils|b{sF^f|L?w9L*Rg-gBr^+JuK>F;*x={WLQBDig@$aDOo97w?(p zgg-P7xDnssA-T*?V+TU7_84*oPc7clG}xA%FP_R*_6_VDM}1aueMN61mmE8A$)_?e zYD1u$z26B}^%)#CfsDzOg%g!cdfm;TwuWh0D_^{mUW%8;rjdW&RZP&7ckPZYjmhES&0Sq0p&YBq_xof2ildQEO;&r!)$c#9YA z-=ArHDDLfp=e-Jahr3ds0V~Ou|N#b7bzB zq$u7K;X3=hbZ25DmcK;UIEu_VMAC~d<;4Ybn~byMPE%gFLU?73Q!2aH&~!Q$uvD<; zpUNu_Bh_)v$s!Y<*1WIE-NYO1jhI<;5AQ871I;i(@tz@0_^$iFwf@R`Ub)XJ=pCp1~T@ovK zA3mK~jHe~3GYf7^>&yeTGqoS@aaZq-Ba+_6LXQt@J0E3b+v@_;PMNNWOKayH6qsn| zQ9s|#?-m@OohVwfrlhv>f*XEqJ3qkyOPOKf!?`xColPdEwG##H2%jeNIuJ*tT>-}Nu+prXT@k?eei_McjPDeGt?`em zzt;M06Sp2b$U>%B@%|y#Fr_$&ll{Z8T`iIN$b?D64w__D81?2DgsD-5QE!^_Y*gV# z(7uf-%q8zu72W}9OpTXzNUgD)Ya1=zRO-1#`ZAB3)Ge8q>BTsH4W_PxCMNYch9*g= zhcr<3=#ZxFo}RiPOu8{UnX=zBYhp=dHfahq zeQ()NowAo&cO-KQMtSc{_uYByd(;VY#%re~P{Kmu2wTa4_eZE+~%|L6JW9ttrAbcI3uCLtIKpEM7Q~ z>$)&}8~6-y;fC@tXCb?%kQ?jnC%!G8889CpmhVnpO5)@peI;RU9jyins_0;P_8yP= z=bP649Q6u-K()@=NbDY{4Dc6GZrGgdJ+;uB`;$f}~oVpa$F;DUQMvWuRJt~hsKM<)^@6u-Pd z7qMskp2%c=`Sf<>7u(2AzZBCmXr#J1*P6V>&H0ic5cj=W@zJoa(>JZdvql9OGk+m@ydJF8w)-zofNB#E-QCN<_T4R#T+p&m1jjjGbZ1_yZ&V zSNf-KM=vmCxWB%P|HIt7fJarFkN;n#ZgsI79bidYrF3x}wnC?F{OKJUz&vu8Jf zkjV3Y{`=(QJ##s8dFP#X-g)PpnafxeQE3d(EUqzixr+&O)ut40H&;te>$hp=A)i6pCCRZxAXn zo4nC3vZ^bx3Fb(cQhVk|&*7!0S?vjh#d+I8kyA{HV!FuW4)uetzgDG_$PEH7&KFKt!m^5JFVkn!Bv|KVLGr>ug--Yi>8(KlPhlu z_QsEx?W}EJu68~~Ho&(1VD>NGHM_3;%Q6b4?#X#U(hUX!>!WXT985^AYo}aGDXU7$ zEA2CswD{y&rPP)$F{S@h=abDwy-X}mCNzvOZquO8CmReyU@1eCtLj|neUn{#b7OpU zV)D4P=s#nOeG%tEOGC;1@Iu2hm^kh5aUF5&v*#{GZAcTSmM~4=`@QSHq&+IB@|)OZFx`K01aebDukQ1m;^VUoes7fk;&W-cMU#Fc21UJ_5e!)dUht!?&D2{cKRwvO}X#6uY5`a~8=( z_t9)p;iUBC65)A9f}mzziZPWLRf?0*}P&^D2y$%g(-exQ_aKfTzDc zH{7Y}WB6lqzi$*Zb3x%4=Mc+W?+)Nu?`r#Uwx zO;M8zQ91yg6T1#moq@6$CdGMwI$qk$!x=e|cfEDV7;F$(n7Dg9V0gB~(3?V8x-lwQ zJ%Odrs^1bU+{D;$%|6w!anXK(m8Qlpc!}Vul!Ip@z6hu1+LH~U(`DIczWqOE#Ps5&dp!Qje2^Pz)cowY8&h)1re8xFSl1VUpcDk)sgeJyK z{0VwQK#`ww@@gnZY-ZZF_jBHiZTKc8}6zvkHI8JjDtk{6#F38I7kFa=e`vx z8ySF2HbNrubKYN0p|r7()Bkskm!D0a{TGWoma}D%LYV4w9QK%UQ6g5LiDB-I7{gwrK>aK0U=C+^EvBeb!gn5=$doZ~9le z^>`iwmA}cK#I5w@o+f@#=LAjs z@3HCge^4YJ$Uf-w=vq5+zta31`Tz&hkg>jL&hId)LF2xt#?#?^si*LXB8|~kt3I80 zpz=`E5N6BJ`3zQi%TQz%!lQF4Zd0nU3Ll4Es!Be``fko`Ua9WDwwI1zN)_Xz;sh0u zTQFCtzLpumrAweq4uynqYlF$iRwNr|0dAvUdmMvXB{$LgL`2X#Gq|~kr6zcd z;*tq_?c-Du5@WWzR~8loR{G7Jayg}l$=ChCdg_>mI3;z=0m_Qrdh{(}8;2pn;`J`>l9yPv zf%PPIEt9TV%(EI#KlA(xHRU^1eyxeH7tWGm8l6$XhLbmn4p#o$U`E#^!E`n_M}|wb zQg$|y@amRawrJEjzvxJ$q>`U3N$4>nemF-up8k^W#6m6^^DCr)b(P${n*dz^7J&N;9i;=WZVlF&Qr1!|G$T?{4Zded zqE-z)!P8%ZH;2`3j)x~5qz1p0fLhHFzC*kZN?VwK+%6^29c37=Ze>0>SY<9DQc`8k zlq8ay;}|^smHGLW+Ld|Rr{hlGSD#BjQe{|;{hfFpv@%3^)EG+8>+j>W-pWiMQc`7p zB}pV#rZ=Ac%5rsWLH1BDpft z@bp(^Ep+a!L6ru%E7@hKL@@9BwkgPp5V6ey`F$E7?s9 zw)gKQC$07^E18eCca9JC+Zb%?R0?{C!SE|6#l?Xg?4E+?^q`4 zQ^Ax77S6F+k zn+7q4-JQKy6`V^=qZ``qK}|64cJ|rTI(@4rA9wkk(jv~gn0K`A-sxLs;`U?lm?0v^ z84lS(J~V}keDQ0dGPI1Z z%A6#tGP{{S%E{k71Aiwg@A`r{dn5EZu~j||+74}N5!#z-m!84_`Lgtn{15F#2oZ%c&33*x zn~T1~4*vlp9GO8@*l8mW;(I(|afas?7p#)!bp3&lU0#)6I;dq@mT-eW# z!{?#VL*wx3xa?l0aLAxhfL|gG&-9o39I`kp9DXhAuy#X(!$N1uuOQY6P^5OhEIh7Z zczgii+iTOaNvb|P2EgO3e3abGSJqubJM_jCemw4Bj65_Ro9M)ql&J8?)Z<&E>O?$# zf{#~j8JiCakAE0@a6EqB$B)O^4W!3w{pER@r0T3$W^|g@U(j~9CH=k`;GAX%( ztlfx-lM*|!gipLdWEz$dB4cAkWljN#t}i;*U5hH7O+*Q<$#U%{T)h2xn8w@2sWq`a zalCyeVzf79`3#rAqKm1u@d$BY`(-@+gz$%J&3c}H^dRt;+{Jte)4)zQnhGE-SbGvJw>z${GZk8iXm3-By z-H{Z@_ZZv;Pg)_!wOc8bTUlNWIN_nPY*&)s0!b*a#<>sF7$N=~M1r^wU+;3rR&p|5 zew5XqFIx@rzU%BZbY8WQA#lP%xOoK|BK9J>dihy#Mkv=d#|GQ#rC+N{V_g6du?=2 zS67Se)y_JWHDtv;@2Fpp$b|b5Hr-Wr)7wQB@b0gT^o>#Ar>~+f=(Sn4DTi=L&Tsyb z;%^~mWx(6=7Zm?ha6oTMv>G!@qV*lq^KUQ!L>S-jV8N8wy@ z?-40X`J5w?%oU*{l1w$Ik!Jc&^Iya@CLE? z81*5Z{xK?Wh0N=XHP$0~J1jS#D-)++UM40*8CX2IJ7dE;?}WBLztS}RUm1gq{fzF7 z4Qc#W79SCGw+7uufS?x~nPmPm8_rsVis>T7SFe;sVKiF-J^X%pxr`C3wORaxwO&gI z|8S=E1*@x?I@gw{HdhPo&ng9=^DL(Os<#DI*Kec^>V!>+88#(DL`j*PF+wxjkvGOM z$V0S}GOD3=<4hg71~@B4|4<9f(v~cEz-UH#y2kiG6eP(2%$}_S4(6rm1aO>zyfl zi%m2~loWsKsVKUQqCHsX&n3{`d3#ZEkpumh>8NY7m@mxrMhrvJo&{@y&ArVyW^NmL zJ+D5^qNO~e6 zdN58&(*}~+#y}G6DDyF~m=q()4B-uX^t~W^luYT2d^jU~F^L1U`9| zR}Di-n!EfBFORfble35L^plp;L+g8ebcEfHZ0hiA1vAvUyTG#6$pXth z+&aN-%#E>zy?#=n|4{rrnLE1E$wYMEY^qDJYgYK&9Qdc2gKbuZpz+B-wr?_^Ck8G) zC60^FYUk)`gepDy^|2 z!SvG|Du2W?5izFG%Wxsyc6sE1#^O*WKh-@}8;;Y`YE`jtK)SLcD zyB(3PJ$J4t%!0-j=2Nh%D)g_$x6of)q;%98%*G&gxS5Vrt0e00IJZH}M+AvSF>tz! zAXpH8AIrN!%#_9>CWn?*Y21=PaSfuDJ@8xqu(T%Mq%(WJXf!sFnfCamBeddJ;BygVVYrwL5MaBF``?Q*rOt6aOLCD#5o7y8Rpu6SnsjAs5v zEVuo*gd$??`hvXc6_?e2V~%kV9&w^M6mgEDFiFT9h*vFSc26qwr=5lV_2!W1&a%h? z3c@@`Hc`xM2H%nw=9e-tl*^f5iHIlZ&8q|7m0U8lIEzEz@e?%|hcXAM@e6)MbZLEC z-+tG=I#iv?@|~pMY$<1W=Th|5tg=wbQmXyF?9n=`J6~7*RS-HXSCAWgOWxJ>>5&%y0J$Ua5DI!lrAbTGLqWM8>-ZNd z##n#+&Yv7^<2^g2R^$B^uUd^KTSxtzCGP^=-%P~#9125e$j^AUFrR#PfFZ4P$NA)? zPeqV3p3@W`QhQh%u;a8PiTDmRctq0FyHzkfRgE8;k6)Lm)9lbg%C6_m=Z8LsG|&Gx5zv}j)m)Hhc}>S=bAP<{Em7Vj!ixCzP|HwLQ60LT&$wGr6`8;iqc* zYPY=B~oWyH%s~pSX;+OinuvMoiZr zA@0RF&*R^U*G$DG5iR54@|rNb#-Cg%$z9q$mo!RmV{U$FJ6?-g#qSPjzYx4~rDJ5^ zEr}mq-}R6liPAaIKbfd&bXE>+q7B+1(AxY#60P!PibSO9$PryR2_5 z1pWc9S_mx1(~rPs&(VBWX4dRueN(H_gi!S1XIxVO`#QK@Y%R2Z1lF|vg1{l??nlo5 z8nW;EB(BYAB7fPDJ?^ApOKQ~?bw*iS8+44(2E{c)>hcO#GxQW(YvnE#pB|^a zMPyfd@F0T4u4>jvZ&ujh=Dp3SvYMZuFg(VmFx1LJS1GjCdHKk;z@wSyArf*K=k^X%pG30Nj*7$Azo2|}*N=Yu zgVCbqD`Bjj^KNJVQQ@1})dW2gN|boKzEnk1xV@rk850M~`7QW%Pt%#V@=>Zkn`Obs z%e;kFr8pG=x%W9zbYmjZz2gjB$B3TJu}+#=zx>hRbV*xJYfo1B=xOckl1~O6SS`r>ig})Fq*KN|IdXbZCIMoippGZ% zpO^01{pcGd#?d2n$Ga(`fgSG@=F(<=9P8kr4&RG~Ur7Phpp}7D&dE51r1vYyuTdnu zNQg_0X&b6Y=1Nxw?CK4a&OjaDa%BoS1gIcMhw$-V+{)djHAaU&Y6Of&rGp~y9psdkpiq)8to=$v_)M-)o1IUcv9J?Bi- zc6FFg8WK|(n4YZV?RW;0pfpM3P9?PUY+ND_Lx$YeB?out$u{#CWxSv*Q0$6wDX?5} z<~z|U%5fcmYA9BY)e3B5qo;Sq)z(MaCQQK3ITi7{cS^MH4AUvv`~=+}kFONH!|A`E z{_W^Ii2sH3k>l*}ZiCniW!T~3Hd35cv4MdSjb580JMDQf&}Y!{9n*ftlJ86BQxlGJ zYRhSD(h^g%yQm`}r)0`T2Xk!PqI)`%zI()G!z;6^O+sZ#satYoio{PU0})F(?9hyk zQj6na*Ld0?d*1PccxVqd$ECDHm-Aw@L@ODG+Ei`QvbuYitX***wNwX5R&(Mdb8dAg zoXW?&GkBo$-wPzerUyGOb#?r#%nWr_<}z|s=cPU>>Dl4u_Oo;5z35v8llHtY2|~6) z0buw^nk4c3)Q5I)e(Fi0+)6m*Rh^*Ypj8)p!eaI^sQc|U4XJ2caKT%D^Zy(pO zU4EO8k2XBv;MH!81=$!}l20*ObuptU7cD`-6s0dAmNYS;v-Bg*M=NesRR( znsNC@+3O(c8hLA(7)Cq2-;fI2$lXXBo#$GH8F^1lnvLM7g-AH7GRzPmvPtOmX39xZ zJG;-M?tAtZrl|pQ0)W5bqAw|auSPnPm=pC+{hlHd5zte%0h$Y^NbMB>Lmuv z!Vpo?i6&N79`~1lA=)8t>jNhxu$OkE7=3IhcrZk9(oa6~u4D1k?S`(6U!=-qE*P{B}vt zE%Db`A>8X*Qumwyc`#YP7d?Sa_|#1vQQ9ZGZcT{W0n zLdERxN!xf;lYnrhyhg+~axRN-j)hyvYkD@&IHr@mQV_rq@|y!ySjQzO*Rp-eHC={y;SWR2}2CG-2Gs3~(rW(tpn;MJhN zRZV*0gMRE9AqLUw#>EWhDq^#m>l&OU%&pWxnOEwySv}8UtNQg&ZPGkz3iEOy>-Sl8 zS0>P&9wn~jKhzB5k|#LnX|5e!HZGBX^1*{E6h_yZBk(+a2!VX4lpB5mu}cTi+Q^d_*=iEWRx|53iNxu{Cl_8u zY-!$q=|%9yajp00z<#znlqyJ~X+qT^f7ROk=Lum#L|O@zJaxVNWvb(D+%rOi$wV=V z7fWam#u?S6ubmNnQA{12Ph0bqnNk0j_maJLM|VcQF%}WrI||n**?X5AUdT(`-FLj7 zVYuCQqw2nUwtmW*vwsw|!<|V8LYCo^pcoSeR1MvZIYtdN$vxgE?U3;N8*>C6XGwxf0Nv= zC%Iq1ttFW7M@y;dTh3Ex&7*G_I;wRt%RPi9(b!bHYSGxOc=~DVYVuK1SY=z`2aPf* ze`b-FrXsE%nf}JxVGR?$vd6-N6bzeY&#S`eQ-m!1J8pl0UgqPjcX?bP`aU~f8paO3 zGwfhps|02}l7wSLsZJB%5$W`~|5EtXqR|F8nadFE@Y(3aqOaFnqz0$;RJ|^dMcI!dov?G&AuZuQ5v}2>iA*0h&HFZxMoo|}JZ>fGT%Z(V@o}t9Q3tkrAeM8y^96PS z$fc1L3Osrjz>Ef~D7ioV7jYi}F?nUFm#ku_!%3C`8HVIRjw zo9=S_-&BIKN7TrISZpSkW@4=;lnBS?asD>)5rT&>dVArf4AThTsl(Qq5+KxLN4}GB z$`gqiB9VOE(%0t5$1}--Dt4k*9RUPJB1a^d|1uLf`0%*)c}0CP8Fh!pSMjRFx}L_< z&nfPs>IY+oGi#@LdtGVXn3U#ar0E{_@3yX)^3-%d(2=( z&UX}eH=fQ>XbKvT&e7kwqSxvfUL%2e%eft7_(|hexQ~bcaQ|PtO3N4@FKp}@sbBN> zgggKR&K( zN`m{G@%JTqUx2rg47)2jac_2sUE^*sGs=uZEKE3KzA>o&rQ&`j9ZwbJfZD6(7A6tP zb(LhLlvW=Su^puQ>wSF_g>pO6TB%QbLQGv~|KB=~MI>Gf(2o+i!c)>wT$5;B-%(s* zUMxp(Z9)b&EIR3YU~U?RkYEW)GkbkqM{(Jq|0xtOG3OAo;%P({e(gWN>`z1x7QB9P zO?1PY{dBO|a;We)vNaqHecTW!L?X-U7mpBM3c3JKgEb{X<)mqQOvIHrq%3E$WfH|4 z6=u)fi)YP)W6EJ~QVGs$h^|RIvEk2BMI9QNo{jW#6Ul_8a{_YYTHZJUgA*I<2piEv z!jeQhKHPH@E(9sL|G{6V(o_ny6r~d>AMEsrxqM?Vi!x20kBgT&ec~||FinvX&&MSK zhSLk>(?*$j9L1Mt`Ba74qWkq~(!bEzJ8!w)>| zMRpI=3*+Tw;ubQZ1)byC>^(_DIn<}_h4|RO z)SAVn{pX`DH675`?qXyGRRA(vnMspCCn-=7h=?vPcP7)rj=(Zyc&<=mPPB^iw$~QC zJ+-x6ac$@PRo>@ur?yWoQ6^K*d)}GjFNB)M>YrWr#Lj<>_ zN+0Z>!cRGkwp4;=@C1a;;-Piv8xCc=!Rdmp3u{HBA0X9PT*+bG$nb+z-P)0}G~e4! zducu~Y&e>Acz^TNHSw>BB_g6Blc8gOPC&#Tae9dOtvCb`e^y%bLm^`1K@kD1N=>Ww zHml2)#l=TKXIVu|#z!^<(D*pj#mCKBTJ^}ePJGNeB4Xzb)F>`u8-79J%li@#d-YE~ z#C8*hAohA?lbC?mbRI)zYnY{Jj_E&JIt;tJW}^j;AS~5|zG17E*=# zrPA*}SeTLZN2?WV*A%JViN?{th#Qsvm_RFSsgKtQv&12^a)vU%PN0<}ZZxj3bQ0Rr zBzSsgPxD}IXis_)oh+tonoh9A)KW{$X2qIXC5!WQEWg&29IUZ>E~(Yn9r3Ew*eBuX zZ|pS6W7;U7%<~VsjYjSLCH?uU-3e_pbC0i$CW%AZXl}Z2>*F|!~cX?35Wt9BH zGQWY-qpO$2A!UABQF;PhCG((p!Ugm!TkmBx#sKw=bbNM@k?t~b*Hnd2A|qY#we^j1 zPK$jy=CFEWj#6nVEy-gPf%vYeQ+*19KSCphx_*N3HsH%0%s|wa#dkK~t6P3j^X=l< ze1p)DtzHiB2OH^O%88h5vt(K{TbyzSgUQI0?|{V5F;FET?c zM~q)AW@9orP3#8rmcthII(?teb*piD-QWdrNHe!261qPXoO#kre6AK( z{nb38$*MOI4|hs8hWxnnF?gL_G3>%lmHF&bUtHFQ@)%5~|W@>d&Moaf~!NnaZ6?NBG&p zbOPTb2s3!!Bq*3J6QH}94$8%z;Rl4&D*9fS-^a*!HJg+QFRJ|AmX6)h0Da=1*9>CC zo+M5!4Ps4l`GTgFYoHq+Zf+i;EH~)-~1Hvt*4Wo&-3KMyTdA5^*mtPM0 zX*<*IeNN?Xyf2k3{5jt7FF!qzFW2D}*CIx$w&C|WpGDU=eW_-2pE~!|8MQ!>-VKglOH>=2Yq=XbPJB)tUbx!cCu2YM9v;JDwsVND5?W;Rg7Cf+22x@U9 zmI~NiPr8eKyye<0idsUg7(-y1zPq@dcph8WW#N6jRyGVr|w@`rC$2tE|ug>st z@uB?Z#=N2Y0&N9$xI(~NpHOA?EO5%fZ_t32UCY%l0WJakJz91rjE_=tD3ka`Z!-OO zg6Uzhza!qm5-F`7ethcZiKubDmZJUQf&7H`jtK3CKckDkTD0WHmUieF z^}^oKLizr)|9GvXdTJLHpCX;FUMNyEF;tOqCH_)eas1`JMHUzE&)2|>Wu&+LOXDEi z)6MX2HL!@;V=X&;8D7p3oah16TCr>BuV)`@bTGRc)E0)g6>)rP1KS!ZxrNxLUAvCt zYHw@kf^U~c6+eia$Gh{!`!vMBRCu#wjKWW?WgB~93=*S3Hd1I?M>n@UQMA(6C+4;V zCzs5?nr3$`oq7>R!bTiqKt0+}z zUiOQdZuUD^Moy1z*xcxrBVkcqnQx9KDP@X1mt=g{ zYfVbEvG=p&wa@t(Zs)&!>uceD8=RsC<2`G=#N6+E+ySrU7|V3kmc-hkpn^ap{;pQi z`*C6%qmNhTU?VvWcPkc3X#x9*HFoG8;<~M(t79qyjzqs5xA*qyLoIck{<_s)r|@(n z0_PH4g=VZN`3JVs#M@x;c*#<0i;~CcTV%M}@BE78D>t@7CP>&)GX~b%WbB*Azp@wS z;}O|qhey1Ll77%Md+uOfLfqbDN3KzCvL@DxHxaW6*fgFmzTbGe2p6`)?JwhOa?-;B zD%zF=Ium?8;UC|?X9zxK6e;utMuu)B@UnPdf81_b;makkErI^rj*h#jh~)&l-$WtT%i<;Ty&0MSP&5iy|O#pOa1p1k6S@h~1D%M>$A8 z97;dby~yndd*lw&H@`?|<0ho-4CJ3Nue^%ash5Sewg~OvlE{Hyl6}5}>gx&n;GTL- zXb=3g3$J6!r=EdA%8ndM6fK|R;T=Eq=s5X)4>_7mDNS*kdwn+J>+Jdhx7r~VuHlvR zisHuAqz~eZ}r{1md|0}U{{$==bJ*pjEpwqjI8&@%*cEhpY zlL(55PRG+3g466=8;4u(T#NL^*SSgDqM8l9W6!++pLo4a$5r!BQ>ko8LT|S}Ly}Av zx31LBpG%Q%hScNLN|8995fG>N?T849;=kZUQ~dwbn^62Z-du`bDZW06ufXl6!5GP! zhJ2WysaLrT86-f-Utzq}Ie5iA7^4n3Q#F7hY}}5gV2yPe0B`eR?tfNK!Qb|QG0zJ!K0+?%*Gubh!aaz-~87rWmD%w z(rRonzG?J3%M;t`(=Blh`d{8%8?kVJ4(=?+$LLZV(T=%F4m%uxnv^NkdA!u6>@eNs zXTfRdM)_9y>o>fNDc5(v#tL_b_NH;WDSpxFf0h8M_O{vmqg^4d+|f6DWRlg3tp!-y0 z4FNSzDQXKot|%?|klEn+f&|5kQu0lZNG^x$UB0FLt0X@?llk|j?hwInuz@9i=U@1k zz}2|jX-@bh34D}5)qx(-IW|VI7{ZjtWN@380T(s?N;2r`W{{}4OzcbbOn}C->Jsli zjaIsRxYnOcVhQT&&Ax8Rv^)j0ue@%(=VOMx(p|kXkYT>VY@)07D}cK}W#@KNLM=P3;GW>#3CB(Qdx8)48NXvUn=f=b444 zWcE~=&ocv0N${!kU<>#2L78PUGj^}Ca#ckOgPCQ$GqEm^1ns%0pq{X9NE-NO;V)_0 zb3b9tM+hq{_3xc-|Ltw4Q<^mO5e2AFB@wX!=~mV&uOHR<38zfHh=V@f0#G@byvZ-H zIT+tmZ5b^#&pk8 zW;{cghI!^&Tx1yDnW4sgVI+ZBts$jpyivF?sYVB-MVp28Hd(fdo@_7LxleXzG2%&A z3fR9B)m>=Qw}^kv27=_AamChVr_s*_IHyVp!YVzf$jwAq#vpXS`Lnz^^7c4y)VLeC zJB51kTF7fEc0Igyw2D7i)&jCr1BVX>wwNFsh*nqaO*fdJKUwn^D@=fpS8$QBl#(M$ zq(=~LN6v=ZEgN{_jW_OoR`E@uNUf{(v}s?h{9~Q3k7Zo6+o}4oP5U?L@VU(C`;Cdb z5j;+R_Dyt$id?YPjt!@bq7cx?5&)?`NXC>%+FgE7$YMYlsW6FOoTtXm@J?C~z9XN& z14ceMzOgM`Hp_2K;|8-kg^dMx8E;2^ZX(@3Q!)$pmb2qt?47-PRW9!N zz4C_G;q#~uws5J76^Y|lNa4m3jPEhL4wpKS)DVWX-K)BZe|QKKO*$ve`LaX;d*!jC zs)IV0&X>*vJ{DFX>G1u;vLK8EHjH-=U%|mpfmPoe6WShtyF)uO?1~wA6QU9`nAabV zX=VN4C7;j~cTnG6(cRQo$X`~-FQaD`tekv&O<}L+%^0!1xjyeCBt1aB43 zOTVP@vj_3T@W76OUU@T$u96%l@EHRUNNH_d3)!Z z8Z814Rzxq5Z{){oE@*eW&0yRR=!a~tQWkk9f^1AdCku<{TQiDZe zl6q;5^5{#MFFjekhQ(J495+bUnvpjO^jr{{k=HNPUi2zuln#iov}8TA<(vhke+Hy| zrGG}#@(ytH855px-igE!wU@-T!#&Bipg)8Aq5|HcZ+5Dz+SVrU=GwjXi#MNAuyJ-z z7_9W;$gW_%d5sM{DJ7P*kR*h+6nro%CHjG3s(?97co#k^I2sOTCTDT(YMRRpP~sk#O){PFineer z$AfXJoJ5^t_o(*;^8W2^-rv#mSFp+sWeT%)yNVrtoH(%ss=LtM!bvT$`BXy)`(>i> zJ2fNk(F&$J8hh~AwSj`SraaElNPx4iH&>SIEh&DO{v08k^xK3iGf=zm0OKTE2ZDCZN#KForIoX|mBL8zcGr%cYV%DlnJrPD+u^pMI{3*NKm-6S}G^9sX#OnSxs$)`F87_w!2 zD%fGqT}qaUsZqaRzjzW$$N=8^Khsu$HL&XUqdVNT;_|Tc;#IwM;eQtY*Jdbaub)729#=|tewj-mcMVKl!XYCzE5@enbew6CEopjbku7Jd-b#_<@ z$Y*Og*+fZ+Hj55R3$}t9f+j+=Z~8J><}v+Lw9ikYaiDXnZktNC{jIofkZzk#4d}M> z@t~0=N=r?UmYPI8Eax@40VNRLP_WxBeG9U4!dlD{ZW`T9R~PDY{*EUUAbp3pma`C> z1gr>zWt>ahjHEdGR|medBPUB`muitni+^%%A){|LzJh)R;4E?#YQQ%WUzs1^n}M&? z0bh?Lg!X)DN8b3BB%3+QsRi^9ebcZ_mYJ(*v}F{I?N<^9qLilGOT7yA+oA7(Xkr*+ z$0jT~D32%B6rJL%(J>N2Wl3W0iv;LVb(8aF-j|_1Kj3sD6Z^%POy7#nNSeaQ6m1Wa z6~+m$woK5cr)p;62KvhJG_$>qR8xL5#Q=fMz0zbsMrxXK2@FAZpve8aiubNQER}>y zafMb2F2~l<@0P-wk(xXS$=QU*zf|gzNu2^L!9kC-oO5VDx_#&j$?0;|5oPS#)%z&U zn{O>S>Zl@*?+Hw41uY6=M6bJx?h%_BaJ~VGd@f@%r3q5&q0VEV=}bnyU>-49(Dyxgsv67)OFOf(&LGEw!>35$G7FqNjN~*%m^&POFl%=)tN$GvEUV{v9uTDtEf9hBS=@#TrzHR2ramYb-hSS=i8aN?P*h6 z3U6O+L~kj9w4xKEH@aGp*pF;cgQA7FY08D$#EH-;M=1%*MoEItGRl0w+4+r>=?wOl zInzO%Uq~kH;VSJ-qz$$9Qps!5X-oqe1+dh{X>=Mq$ewdA+~`sDytnCPAiZteQ5+ApquEG*BNXt zAwIIz6$Qb(&i34e@--6ZZhPKC6hdq>^ni4tTHjFZW`}31AdQA#4MmVqL8n;rENKdf z(N>))L|$MueEr$zj`piv&JJIH1Q{%kUT~50dBKi^$>i+pUU_->8F1yPQpw{9j_DaK zrOl8eL1(6XK++0>dgD>Psv!8t7oO2YzWq?-23`(0zate8vxKiOg_5zq^nC&a6Yl^! ztt+{VO)=Gh_nb=cMl4QM_3NKEF;*DJPe;g;uf~Htkn!qgOMno=Y1<0IC(zFvaAhkc^k|7 zwoD3%urnVy`dDQ2v5YX2n4CtKJIPbV`$9z7t;A_XoJqiU&a|wbNp}rG;wIpnvn=b| zvn}g!o}U;TGl_p3hhWL`9BJ0|v_lq_r-ZVN;k&bWc970%q+M5h@jKKvpLvkQoyub;nPj6UEZ%c>^cs%tIl?Q1OSgR5bV{h_m~kQ%PU-A_Ne zdH_N;zBf5x)p+0`;&UEd;L{ikWbTG1q6J;R861~a>#bM^D@b(Zyr9k4!L zOZ(&mtj~GY^1Q}#15bCJZ6^h+o4&Br^V}A2&2wXRz`Bs!(?R@UV=bnGgh3)l=Wx?juFL2lOR$xYY;G~SSwE3hm7GJuT`kjyl=-w(l zlG43ZMrmsIR+;nCy0^*-HR;(ZH|5?It+Ki=Zr7U@U(GW-FJOH|pGy8-m9 zDDR(MRehYkQiCf~ykD*1yuPbU3 zx(QEt_sT~+x{UX8%XcF_{_>UI7_hSOlk$nb#1s56{97(gc(uwe3s@uN#r)i){dr1I zUiW~NOCgTpT^>nK+D_8;r`M}zz`E5x|2N6~Ws>`cB==8A zZiWl*C;1(dT`O)})b>M-Ll4ZS=@%aT7;d6Gl%MIbo76;K&i<$KP2TG^tG+IerBE z(=E=VVYl51yB$B;g4@a`z5rP2^hu+Q4+T2EI7sbCdD3*9@|ek^N9(rOY+68^CXuQA~}P553D{ySuDN&n9R`TidQ`TmwJ+W!uL_!kMp{}cunzOcRPS7Cs@|zKDeoOL0=$vc=QS&`8*?# z_|FR@{yznhPx+NP{852~|3M((&k7_wbd?S-7fAS{0ttUoAmQ`->+t&pO1MD6r(Lc6 zBLeY{3B-TwHQK*eApSE2;vW`BdV{ak;iCl-K0zSi)dQ#>{o*JFUx5z`MDE`Xly>hr zP`lRy1JG=hwyHJPUA&~GQfrQ^Bko0CP(%~_Igx@ca@P8QpO5?xU_`fHRdc1J2{%(apzWcX8 z8~$^j_AeHQ|7?Ny&lAXZcQ7B5@-KW!m;cjew0rYQxKFmMzrKc>cHdj2Vg4E*c-pvD z$17S7q`nb>q#qMV`ilippN*gBbg$cto9~|f3`qP6fy94ZAn~^t{~gAEkMVE%IpLJE z?-xMI`Gx}|ofm#2-PRc5?A0*!Cm?iJ#dJ&Bt#hh|D-ks1yNj78ivMVY0Lg!{K=Qv! zAo&+J)BbY>;(w1o{O=V=J>Ft|Dc@}nNcbj!gnucJ@SV&@CEQ|eD&gq@3BUFz?LSl? z{-Xrq|3~Jh!bg7HR)^0LNccQ~gvSI*y6q@8V?-Llh_u5+7?Vmpjz^g;@QMq7xwIb( zRe`q5K`z8iyUhbi{HFv$cXwW-qXJPd*Fce-B_8CeUk!(6|Q}IM~3U z1`aoHl!0Rn9B<$x1A_)mGjN81B?g8KoNwR)1IrCuY~X_iK4Rb!1D`bTDFdH1@HqpQ z8o12Bmkq2maD{=Z4g9x(YYcqXzzqie&%jLverDiS1HUqGhk@T4xW~Ys3}oV|+9S=t zbOSRC%rr2|z-$9^49qo9>{nF#8`#0Xjs|u%FyFwg26i*Bmx28Z>~CP9fddR2Y~WA> zhZ{J`z_A97H&FIYNx6asPBTz8!-;>1fnfvZ8@Ry0asw9|_@IH07`Vj1Ck=ecz-JA7 z&cLMxE;I0D11k+&Vc=>5|83wJ1K%}pgMt4uaFcm~UWL1G^d6%fNmH_BXK5zySshHgKqc z!wno|;8+948#u|ppn=m2oMB*zfnfvZ8@Ry0asw9|_@IH07`Vj1Ck=ecz-JA7&cLMx zE;I0D11k+&Vc=>5a~YpgXcv(~1d2Q$@VrhJT$tTCB62P^5ZNr%=dn>DJd@&yaZE9=(=JxZo9qe%iq9`gQF|kT7uK~eg0wO* z70AL+C_A(wXSrHCFH0%=b(;F9_^q<4W!EXA zp$WW3v-Gi_>Zs~Ym0|=t5O1Q2O( zc&7k~Q#niI>KY!A%UAF`#B(oc9eSnj;A?#y_%w${es4)Stn2j( zr4`OgElo+es>Q06%Uh-OX_+#l#qyP_TBUXW|NVNIs)MSH*6qtH)6;}iiD}H!v+>K| z0i~9(qja9rja!i}?-}k3@A5NjtJZqi!Qu&jlk^3x@{@RD^{e{trq>ZybDw`X<&*iC zl&=YoTfVNmOL`JtenHY>3hwvo~vzcK4&ZaM;GJdchvCE=7w+D@RNf1s2} z+*t-n-w?O(1%bH+<{8+|zzzlqJxV-9@4$THR`iOyn{oFtu%Chb4JUg@8TJcf$OmE! zhap_LpcW`S!isXwJ=4k7)GL@3~GIcXrMMfPu9pDowUN$btDyLxk%=}o|d8C*VU0zkw zCa`?%KKpMwQ?ViDtV?2~5pzH^O$!jAJy!6fSx3k24is#kv3eQya~zq&KPulY`ccjE z*j}=gmurU8xiI*80*p)~`)EU7Nx2V>AJ1krx*YLs09aXPFMQ!pSn++qzMK_ZqZ{;A zSGMmS3?IHvivL5+I&}IPgbF6IaJ8cz*@Bhm@`8_Mc8&Eq*`mnV(N$I3+XPmvJz)QB zH;BnP2x3m1l^we?Q1B5l)r=J{Dcsy9D8TNNR&N*GSMv-;oLS_TZHFGEVz1B}#PXXg z+J8hw18Qu8ulAo5V7Xn?nwF6!hj(af}FBq9Zr$7r{pWq zn53fHYuK+MsYHK{Wwn`d0$bGjrbK_1sqNRf_hHD zTT?H#D>wzbh}&S(n}1i<`TfYQ=|f{#sWm4Ee(Z`9?TX2PKy}rY^yWLuI)6gwNd<34 z*H8JJQ-HXwQVDZDgrhb}ZSw3P=IJI=f! zT2UR6kmxUvE@rbmkWOBf3FG` z0u3FA(@(OEWt|jRhw*XFtdkJF*XlXYfYP+Hvr0piDFs!r;Bif6e**&a7AwrRVH?3B z3f7w=t2 zX<@R?lFl%5h}+87mkq5>i*>C&yG^WTAnG$qUm3iduX9tIxh+l~(FV&PSXw>WF}eY? zO4rQtX2OIt6A*~GJ3$+Q4&!s#v=gd>>E;G*#G_UmJ&Rc&+1A@f!@#u(0 zHpOm7ge;QCBZ&+?71GHBKOLB^CboBmgh*`pl2Fy&20x9S2gsN%RMVS5tu=B2LJ-E@OBu@m`d;b=wCPrVPVmuV*cjKTF1U;U%I|d=V($ zm!|Y=l`&833qxr=TXjsC+XAz~<(L(&#H^5+N6(f$@gXtKr(er!lj1Ntu|y{MjAsdg z<83DGc`4W~hEm01v2Tl386=WUvT6OKE+V^RQHM-A%L0i{=KVrV`p-+dzBIL8BxQ!F z_*E@$&=??!sz2W>;hWdxo22^p(e{zuQvOnh$s&amc}w*FlaSS9(3f8x&m;Ji;8!Xh zly-0^O-;iFxzjMbrMxmv%tU6MVdBwFh4a#`ROJoUQC`VU^zr3<D4vY zDj-baxxXKh@^!(5id@*(<3cna-HK9Zi`THalp@M=AkfsKos2yWl21baWfe`DraWaIIH+O~*^ z$P`;b|4-&-EHSH}@GO~Yx$PyMQmdy$%$&2=VSu;=jb>_G<}$*9`7E`_WcfLq*8$MMqH<@^~ z>daEUiYEuoF5r>5?nnb4G4L~i5V<=So(?J{o~)M&{8=F3Bk6+zW!+3*CY>M!qLlTS z6gtJH0_lUF(B@(f(iZ+K?q34~*oC|(5dZbY|6bZs{AUqA1zt4~cS@FJDPRsOP@3og?7`rO?5_4ChCCi%H@-xf*z zP6ZxvXTc$i>a{_=Ske28>JK)!sGJV#pNtcr#6h-$ zjn@_r;fd}~ctkD^;k`72$A`~0er|fbj2obSZh9SYNxlN*C-DwvJQ<;4$Nxzh@=NCb z67LEXqW`(^1WI|`UsoJEa7f+U@kHt`ZnqA+S{-mqmKXDL({tS}^!wM(|NSMA{9Nql z)Kb0HbKOn6wvm`e6TdA`-d*>(I;wG})Z+I&6XK^>qRVuDQtzQW(xy7S6l)Ccbbrrn z_|f<~Zyhnd$W_g$T^_@3D;_a6k~zNsJW9$G zpfFNCaZ9ePE(P*C^UT&IHbFDOu}bM^QAX^-kQa{K<#tj_s=1EVX|%({@J zreJICF+4Gv<<1vBjBYI6UN$h7kfUq)N8M>96KbZ@T9=$WIp5-z)UvERb7ckRzJ!*iad<#oyx@Fel7RA-7AHPi`jx-m{PSRW6l=&NY27rFFA%P<%ZPgdsSaFZNAg_ zh|hK{=j3C3k0x0W+Kl@nROwZfB$Eu4XG*9l&7Wsf^5i_Bl|qftoy8ZCK80#lwdI(2 zc9NHrBvhGJ^+iVWoxaS6>+eHfa5m2;BtbONPp#ULUHkK@FOD(as!S@IBq!Ed5>qW4 z+LBh>lcIB}YiiZz?8KTJV`>twRcffJiN98|oTu~{B*8@s=&DXhOd{KtgicPkghoiE0E=nW=$*i?C zuhbk>?*GmCDyKwg9W$dDas_l6yYn;gQMyObL*knrtvax7&I*aRoHJQYzX3We%Z_{) zYz-%}%dSd~-jEUc^yknUf#_A~W!=&umBpKe?9?^@1EcTV5Pb_>AuH*5@?Fn81h+2h z`8^B^3~IFysUBB0T+G$4Z@aJUo`MaNPl#TZu51WI>mw>cPmkArIhy@+ z83{;CG_C0GMDd!V)m6NJ-t3y!RGH9|+7&HIetdjNdZ%^KHOr~b4R*x`2l7Pstnn`A z2gC-Xq(;{aQRSC-L)3S3B+igPwf>IN$wT>pAtzL}6%R>Qc(N6Evn(A`j`6@EQtRlmZT(fsSZ%{W61=w;9izf!%3vDsSB_t*k7+siESH0U6ZF zYwDz>Xr+5IS!l&gasKbmv-Ub?pSdv5>)$JxefD1KS)?M<$NhK$#cHBozPDkco zt!R=QnnXWjoD)Xf5)>n7u%jW)3!x%i; z5Uveveo*Hxa-c;UC4&`HblOsn%W9T1xZELV+sHQ;=YzZ?6s$NR73;qo(}3z@Z+oc2uV>1gcBKiWJo_tK0TaRpbaX!F>`on6r= zj`p~5M$;xu|2*3J&BQ-WS=GB#`qptyUw&irt6Im^ghC0kcFilogWg+dUlfrqxnxNs z8t#iJ5$h=DPM?P~&EDKCRGQDChEFKUSYq6IdCxJg8-w^&)%Eh&^FzxU$w#ZD;zoJs()ka-4p-s4<@OS<^mGp&WJLI`m~?_=m#0Oh;yq zk8EMr#s#(E%uL6uw^cJ)Fkt$};;Rno#ee#l91gkKJFE#ug{P##{JZW+qx@8=4RH9Tt*Um&Ilq^Np*7fk6lx! z>V3uM^Wl@n%cDO!FZcI=g?tC8#~VH&51sq##_%!DX9=TRPhaZ`>fYqGR`R@wiL;iD zb1IuYpr;w!zlM@`oHG)?G4-GsGbpxYx1eoG zw(StX+xlG8k{n@uG1WLEr{$5#j!#yGTRM&(A6*O2bt=tmqWHCCHI*0CZ(7HV5dX(- z@|aEQYMVxNSCFjpn9<{6>swT=&Ao&ntp+)=^`I?QTO6#VgU9q7KGXW5`uLn@v+v`% z7vIcnxMW#P_fZ6?$Bn`u|1V1EfXS)3IJ;?Gb@N-P&MA~v+&zw3adyl@%NA7R)>abH z$EpvtX&q`j3RIZ$ac&no>dscaMjmEY)yb|ltp>$wgkm?9mk6Ei z%2)@GCh=u1C-SfwP&&LBZi<;f{+s+F%uR#oxwxfuYo8EZda-o#oDp%8`#P3-`N=>6 zziJt7EzgkQ+M{}Pu;LpcrR&8i2#J*lc8bE>%QJ$uC&VpCNAPO$%2{=zTeoT$n%gul zt{Y8+*AT9dApY&EzbQc_~q^O-$ z&`98_$#6ksZtci;hRQ6dXnBbfz3zkNTz4kETv6*b>*wW8t*bxKHJbkd zuj9q~hQGTVL>7maRK)uLU~y+FtP*$PG48uqmwPCawAHn>I`;zZHgxPB(DiB z0$!7;FC3?W-!vBQSpS34R^+nhaxZ0@{?z(N3*`|{H4SMY(q3U~Qb?E`eUDW((h6l< z-4z|ZMUk1kp1ECa$42cz`Q+E_`K^p=#lpZ$)No`g@Vv~eD- z=6E=|ox*6#n8Mpw7tzQ}vVy^|b;Tr=VV8CnRtgEkG%$>e#x-4g|^=0|>T;I6x z{Jkz~%=Nv!Ft7d&B`+PPkH74^%17^1W)se=4>th!SDezQs^8T2<1^jF3sRVk;6HE` zg}Jd@-+q_P1k#<1JXRQp(-IIGNa?O%XseP;Xat5s=zTzKkK_YMtrK&2esz3;cnb)r zzJYj;foPiFT~S5dDk>gJ%J8oXMCijm_p@I(BC54%EMw`D}IKPHW z0R!dva#%)JWb8EA1lO#VxL>v!1locyzLTVXdwIxBHpS#w-Z26;J< z8(Y}Qfg;|Bv(jIz+(yRuOJ-qyOTh(D<5rqh;a50R+r^n^52K&62&tLdZaLqU+=e4i zFsy%kcLjR}$l}hBhrmyFt!zafz@i#gmGZ>D;}A+|=xW+?vF9*}@5XG?T-uQ3+y%!Xi0F!>ZoAcWA#$LXb$X2pXKCK0)uPP=K(^W<*x(wpy6AC22-lzp_Zyu}J1V|V3Rt{PMSFQzKZU5ZI;$HTYVv)}$F*)# ze>8l;jZbzQ`G(Fyo!4>XW}V;IzLakyn0fuZOUQN{muTI_=vhu%Me8_r-Vo}psLai- zugtApD8t@@VQbA*X`fHwxNJw}^1G}xob!|iUA&izD++QBhy!v`cf}RGcPDfgvJJft zD{dV(i~7CyTC$>90T{BP@X_8YlXCLs3cK=mEFy)T$IrGRM4h8Fro2ePvc*C zC!kmSLm#m!b2vTG>l`pDeR!DH^ryvic^zC%ZgnFx;yAi1))=J&vLWF+FWWKs@_R+E zr&SqGkBrPK?n1}Hvs>m=)|)ZYe0K#G5Js0;<4p_1Rr7O|blgpU3SVM4q6MhUHwxL& zJW>9WuKYpW6{Em#6mH;4;g@icqvD0q0`#UZZx;C2lHtPPvCMkPE4{xh*AHYCt|=&h z+WI|Q)QJi29(I8~;oXTHU)?=q_!Q{-miAy6Aj@5y^r+wKQuB& z9w&TS3Ak28IyW?5?kE53viWuU>%%N1P#pe`2jND5x#9Mp?RxM`@|VUtg*(er7lxU- zAb%&NobTKiUF9r4uWh?@E*EBlw*7d-@hoyqLP!6*vM? z@fu#szO`QaPyGqhji#;(6J0a#a zeMM-pc7n*~ukEJIVhJoM<&z{vApt%JwN9X`!TSx|vo6hw18TSMp@$Ts5jjmVH_dZN0d{i~^}F*EF@&Fp6T0F&2t zL{AN}^OTrhG8Y89p6qqxXnB?d_70p7nyS60jxPAN5dVT6fM{d3X$Bcq(Ds~!Hy<4m zSZ4m{C-(l##wkQYf13$2b-kgF(_;DaREOn_Jl-uxKz3fmu?gSO6CLiXI{zy%hNhfu z)1G%IwCOxRPZT6nv{F`79BAhDWsvT4aC@SEm`yeRzl7aucf{_Vk`@1UgZR^Qu%Mz! z=AY@$$QuAb@yv|y-oyocLuONDdruR3#gCNT_7rvCM2FC06c|XG?DlKGVtkDHVGILg z_hojw!F?}A8Vk0DRR2h`k$a=0v;PmNdLhSCBx3v+^}W1IntRp7&j7ijwFOvi?6!Rm zIEhFWIym|LsEU$kL`?Y2MFU_=qt~(c3l!&lqr|4X9n3S(9Ute$uNDDn_XL#nrdGxG z@+Dzdv41|E@mpMtwx4SWzmirZuq1g+=aH~o`dLE7Wn(t2&N~0XP!<?06T2Nxi07uqew`;fqGbGzVs}yZ4Sxem9>E0@dMT3PFhy`Vh1{ z0r@D+c2^ue5Mrl1K)7+rgYd!m?Gv3L=QSmq1l3sE!95$6w(ue0e-rP+t+#vx69E_f;#|@C(L%5_Z4mZKF#brue6%q)CTGRcpC&AHdBg0`&?l(+ znilRCGGSDF=B?4S2zVuotD}{VOM^%Esv4mz;|HQ9n0Kd9b?10aG?tX82bnKz~WW!AC|D zc@p&Mx$ao-L{q*`SaBZ<$QX0}p$B-e{CbKwr?oNqut9G=R`i5_GUPnwLPV}7v_$N! zhHulva6`3xRDB5V`lGsE;v^TK49K)mI{Ssx18NF+NsF-KX08;* z3qC0DcD*b8Xj+KYIsAU(ky2&D6^GyD;z#%lgWJ=$HSNPRrVVsY-^QR5`jqfRY)Hs; z!k(FUhR=YMC&5N=tV4i)n^ZSO`zPh($JFKkd2e$znXhqx%#ce$F7mI~`+SJoBjgs= z%h~mpxr9#J>f%H{N{szma&x2N(fnDQ#F>pzThi)xcLUVBl zC(AoR>e!X)`vFS5%NknK7)XY-+2X9k6J0|$2TU5kA`1q^UAE{clToKKtQ{;*B6lsL z%iC0+da9pQecdjBbNm1ZOblODsQUoKX*Zu@Pz|rO{zqA_P>iOz355<2uPuz|&Aagx zDp`GQC$S2z0%DOc0?a~T2Z;HW2P?!0OJL>hpBu-F{S$3M&$U;9w(kXTRV~tCeEpkCYm(nOR2Zn9K+;Xq|(d$0JH9jWkK7|9mVD_{H%xfw#ACyODg`Firp1UNy9&E z`7h&znx+Ysa~`A{FXXQq3Mh>io@|wyn!78y2k)seKD*;_!b`ArjT2tc&Vv_2yZWYK zhVWue#ajoC`k#MwywRL%VN~ze7k7eiyY#)~u0({lLdf(rgkIGTpGj4I!5m}rI$k-R z{K*Z%mND|{&#Q%|AH&4{qK%a=?!>s|*5_nDT`s38GRsTqU~7PzlK_U8$ZAAwCnz5< z5astfUv9oX|4I>YFm5^tfErYGS>Xhp;LpP}?R|esb#3}vx^hxA`e9Q1H(=0GO#&Hz zSh$Fv6w#DHD(Bo7os$&T5j-TEwUk%TaPzubMl^lJwxbstN+#L{sNAFk%;D5U<>L1! z|4tde$Nu7o*x$a}aIAEn)^sF}kGDOxZsQ}$y_%QaqhN~T!=C>!IsYJ@ZhZK=@_Y^t zSC3Ph7(VHi*KzS-+i2-F_+hM5>ARz<^xc=Y0?S9UOPs~$wH^a?q`vS$s*)2w-| zpk1RI9W&kc8}xl<@_jO(D%|(*X=dnJ5d6{Ga$ABWAKKLY(IEdLCdqPr`vh%g0D-wX z#{KPKZ@e#XK$TF|;8wL*zR~hhWmEO^e+O;9SLI`evay__0poyR3d(rl0FV^EXCoV?JM}9yC9C+w@+RVe;-W?@-jNe?93q z^>#ku$6Eh-1>mPV80)se+?yoZx?vPuvo3@&K@x4>WX2foVTRwZcroI;f8Bt%(pb4wIc1JSI+ z;~fd+@u8IUxV`QyJU@YV!{Ybw6HYgECnWEI61$t%@py{+!0p!mvtNrHl;IOP z8*A_UgJ_^;qQ)~!F>dpt9h39$wjyZz0j`D_*6~5^VicG{^E*eY(>pC(s06dXnKf7M8s@x*CP4nX-U8$)DO+r^xT{_WVsHPIfM0b?-Mi;3dXL;F> z7hw98>6q1-vARXbAE!dcQ5nN5v=NeV9(Ykf)o3)q3RVwUFt=7muw~>`qyI9&s`G}H z%-}SshC)@8~oKNjq#9G<0sH!S{Q>sV*YSl#z z3{w@cAS2yx?P*vrQZ&_;})mL@N3YHId73$ed5Hon_9^ z4jGecynw`maqdJGL*udM&f(F^5}lpJ<37s56o4#;RJJ z37Oo~N>7UyGiM{Of1{&mVl{^eP7ePYTyd~G5v|`ROC2dx!KH!jZN7_VeYsa(KxArR zVZE(gpVPEkVd1RB_m0pW)wvWIk0&}wK1}m!{H~S%(*|UoT?BC#78RY9u$>bJ=r>dY0ebr5Jw8GHe7P?5HxZ2Wa}YgY7%%MSI)bva{vF{Dar(TAxOKWhHR z+Sx&QaUmM5@~1(D_9<&;??2FdXP@GLVDi_wwOYUu7oo0B3DV_G-KC-V&%+kVT}W}2 zZ&E$d^K*oQgl2f3WQa2^@l9rjZJk6~qqQb}peB8hqEf(M`OjQ)p{oNo=TKP^vyYyObxG0-nt8oog;f^~(4I zLzaKOi2sv253nkJ4h?D9cFr9Wz>p<&Fx2RRlft(!ulnFmWD4WICaZr|-8)`JCtyAr zuQQ)O_dm$5QXdaL##tlyOjH1`85d-egNd=J&Eskp2&jzr!1W@tDiQhkPQi>XA(%)J zPzT~h+0N#|vEy1e|A%dd$JR-9ENnI@0c2!cm9%ddC7Kj=IbG6EH8oPj`+?-_l*^5P zOtE1~5EDP`VxsB>D>Cf7|B4dP+mdFAdKw?#gtSAiAVrTRF!LTaI+fgEY1wV`Z|0}t zydrM7BF4RfU`VB~jHiN^_-Cw*-*kpn3!sYlpLB7H^O*~@yOq-l#ul#Cv_YYsV#^zq!o_na0(;ZgsLum^A`S)~{ zaLwQJYN9sREY;)6y{&lR^i1>%SLSW($PWsQ)!~;s(8lV*iPaoQ(Y9`>P|^R`k7J<) zgv$1R>_tqwnD4fEq+{Ne!Y8(bj~+bpjY+#V@fIRBHGS+y=kU00<`({~;GB$gGx4E} zBCZOnnySLavEkeGJ$$rduj;}FDSu93VFua{NJHjO05*VB&8Z3b|J>?K@8h|{Dx3du zy0ubOSXfhdyL{JU@uX*_KeS|RXuqHdUofgLXKeWKvHS}IXTh)>2i3TtW<$F7nyQZr zY~ch*ru2DZ!}G@$KCOMSZw*hV2CMMn8C&TZzC(!izTyz>y*)|T5`MV+s)4Mjjulm; z5XooubEC7Iy~8mTJ(XQ8)5+s0S_hjkk!E^A_<14#_ zi1LZ)tOZyyC0Oy^j!Sak)|RcolB2??;ew#;0(8IQsKwY$`_(+6H2VUV11+d2WnqsTl z_rcANP3U4Z)LfQM#LyPBDLaI^pzWPJL|5EZr10Is%~NQTGbsx9I-KE+^QOkPK)KJK zw}?2ULmfvOai8ZA;u-*H#Eo-DeFQ5G>o_~7)`JUv7d}CJAC8Wi5*?Azu~&+YvEnUs z>`rS&M}~)J-O3^zrwa{FhaF0jqGK#{)SP!{{AU=P&>cuVFDwiw@R|DdAcaocIIq%tU8yZy;ES)cR%oD%H1xq#G&#!TA z36Jz?wX`_=Q*fjSHRVR$^{ki3t80mH0Rh7NpP54ADdIdq- zi_ZU7vlEe%cqSRAy&;T^@8_%2SITq7NzitS%5%<7cV%V#Q=VDN_)4@7ILGey`A`ydq_6FQKiNMXv=n&(~P$wo(|HC^h)PBY{jU zMEOp~Zns%7_hvR|`yF3lW_>bJn;J})H)e_M$^_^^26Ug`dwy^J>RM*ZwNFXAyaw)l zy6xRS)}+72r{ST6FWbC>YpRGo-(|SwwXe!%4xB!Swkxy>C$$CZ!n++=I@`6h<1^Ou zZYTS~EH%|45c${C9@Yu>yJ{iT*6|;7&f9BU)=v2)OdT4IP}-4fPu+`O~t z)?(AAI~F8cRO5YU%>4IEPV2~RPi+L9Ps{0zl`pfeN}WREexXXnpcR7Qy7&qHxLu|9 z;nk8YBt;QM-@w&UI^RgK-tNRs6(6-@RNeSfk`ae5q28ww{mwu_T2*ik@2B!SO|9{F za*+Q4@DpA9gPX@|?UQB(ZLjN#Q>Hde|8yMXmJeKQ&u+ip%k+>tj&|?At@lT}_dnG8 zWI4k3^nP~fy?EL3QcG^z_)EugkVU;tehl&#b4;TB%Iep>bg*(8_RVd3%aQ=RIZA!5 zPmlWQuKFHdI}7s~z^GD3Mrcl5ok&dN9^sD7IHVxAAz1oF_vt?W$?y^# z@-iJSC0jMrG*u(|Q4_Z~Q##|}5eyRK z_FB1{z$75GDAQ36JY~tz8^257H8^OTG71^#Qt-;z0GPd=`?M}oLOJVg2he-@#>j4eLr{tyg_@Gysx7nxxVPK^gAbyVG5B3Pz~EZ`ME9>tP}Q&m@CI=7B&=D^ zL(hT|Ebg1sotD}r7z%09DszE#U(GK#pVg3 zmv3`k=4@yyH}l<-FPij`sZTALdb|hkau;b)z%=HP!H-#0wIt@H*By72%iI zPjj6ZCTnrFvo0Yov8Mk9ZNJrUQ6K%cKQQJygx1Q+c_$Z#uUcKAY0YlP1R(#OC)vm@Kp9*5g&w@qlN_1{d_H_J6lQ!PypwX7_%^`228qzHDas%OAyc+Sz{EDk=JE!LPb=D4yG}1&`E$|H6U|O= z(ZMS5zEsov1xte6B9tQJvwv$S=QnTh3fy#rQ1@!Y-;A72$R@$RJC>CUyS-Ih#~<{D zlylDM&ct@y62NlxkI$yOKdq&mwF=I5uSN60xPfM5vmrm@FM^N0Vz)v5AY_&*us1*B z*%a`g&gI!96#nd&pzUmNYC@{e8N5gV`INp_@;&u#e||3RjC-N8Ke!4$#gFr0ap%01 z_{ECcKPGbgU-s_4J~vVEPTs+U8Zrae&(qkfdt-@}*odmi_wsK=bO-bBuAa*C)umsS zsN_=R8lRw?Dy}@hm8;Pd#PIMJ7U54w>J5#TLZZj3R`sksWj3ORKS_I5F2S@vJ<)5P z9wL7~da`1YQK`Y^9@u-8u+8^m<@C{ z{T8hFCQR5?+z;5CrA;Yi(oX>`bUh%xc$N7 z3*%s9ZTK+kO^)ac+CGUObK6EVeU71{`YDf_v(;1TJ z39ecloky|w24FbB758^H+$qVcS7Z{@xh&a*2$8c|u!mx7$gdJU=D?iDg0@xE^GVJP zsJ@%Gms#d6U05k2&*v zd!oM)ha589KzYjIY11D-#SVBI-Mc#RAJJXKf)49nx}xP+d)muaGGsx$FngNuAo~0t zXwZ=rJq?Uf)J1agHepzDv7LELBo;;dlZ4Q`xV-9RT9NBlhXmmuG zXZ~@69?Wa~qM1{TNw-vap7A$h`hu!#iRLOB=+0fVkX-Og5jk^O8B>cYmIXC&c1tvd zA(!|pv5S6JbkYBLey!!(_M4rheoCOeW&AR0&KbX^tCEWog#<4%!)o4Z7}`9RYveX1 z7~S#bRl^+NF!qEcF)EE!c`}Ewr}@Ay*^{qS!rgBNN&{rv+O+~#PhI#qE#G1+-+hEp&pY!%~B`H)%rQ3gPru{o1Wd?Or zMen`V|B0UElPkEE20!Zxwk5i3vT?d>0;S)Yc$G3GFu4>hYYeMay=7fegf6r0`<0Wv zrb<$%#CuALPVRm_dvbvpsuP%dI#2VRZb=LAsfIbi3|F*vy;QAJ#*Z9PTwbMN&?K0R z=`I{SF}V5m8+cW9y9R1?QXhyH01%zVP)EnizFe;+8OKj~mcX(6>y+V_j@caV)G1i; zeq&{@Vs>TWQxm)XUOi^5s(1apsxpqA!k6opaiQw$iI%{6)<{V#fnr2+cV)M-k+kYk{MnQd9YAG~Z#s zV*IAJ6qf49Kb{UV0>3R8KHGGV8;=@l0YKqIrpuex=aL&vt1g&0bA2($aD-^Vbkd+rB5a(33gm5C# z2R8S(z3H43*!v;RcRE>5yv|i6)1GMBThl*R{0K1NGn=0YXWfV@HBq zMz?^=RbS^6(b2%27OYtGj*8~H!mZPO*Zf-!7Pmr|K8sznaq=PmX=&nAHjC5%`La)} z17Zcl3Fe!b3l2vr=iq`zwlvj!fZ5PRbsxz6yK>W-%H|o|K@zn6n4*_`+13CaK}Kd< zU3#k>-ny2@Eu(Y4k>XVNdo69=(EGLgrsjKKTD_S?^rc^VPAUtokD_0gQhXQOn&6}b zkjmb#+uWD3TySgtCK=o;@SCfYl!SB+OZ@3MPTDwW+w@1_tVW3%n2#m;b0qZ#DuOoM zRn#%Na{Ah!?Vn_fYRTnY8W$z#X#dC#yG^Yera`T#u9i|zX?9kBT?UevRDJZG|9FDd z7(x3uf_6^`8mGLmvg7E=Nt+q{n8pC=Kztb09}b^aIei204Tg_L#qysNKD}or44Ng{ zw*+ku!iIsgPue_OYdKo8mc-6VB8SZ}i28jW-~4!Pbyd=+5&Z6dmos4RpF2nQC-u*r zR2>sg5>p$S_A$uT20*f&BDRgMt`cjL2714r2vpOc6rAJap)}7|NzrfUT=QBvI!kX% zyiOVwG&BpZW^qf%^o_+ut7#pfcQom_;rMjo-+VqV4MDGpd`hs2pCJnpfe!B->CyAA zmgD`%&j!bP7I@Ebc<1NfaB$tlR;?AX2B)I&XI0iS!`ZYFlmsprqNKfmzXj`}i)K-sqZTiz3 z9YLzB>o8dGqpAC{Mty554|IA|%;Uh$+jn#sO=7mrXcg1SaR!HBjkW<0^0}t#iRIv_ z6^b48{d72b_Fq)cs&XyGsE^+GNnf8?O#D4EQ7&FH77V6l=hK}LSK`-Xbkt4yyMvUC zme7ccWzJzOrWNAnJ7lXYRNNzU)*8=oY^#oc089=z)=4SgV9gwc;_3WgolD+eUAL?q z%{420#NnvHj3;fp1R9OMZs?^w#o@oKLa3v7vCgexm{Vv$TebCn2 zB?nJm7F<26?){`QR}xyA4}jzEuV~r_GaoQiK|B;ns{mNiC@%;aceWEX{*&Pp2seG5 z7%c6id@EElKzwyq&>lh)Kk1SNOSdy@VGXjP2G1nuSxT0Tx@B6aUxNPPeU{TR%3|fm zCJxOQRmKw68!2M7;d#0jAEUJ8H?&lvzP4*gmc$ziYsSPu)%r#th-I)U-$p2MJg~0y zkb;^Dwyq5-7=0>lZKOkDH2xJ|Zh|YP%XEu4i7))r?~Ku#1X3l(dxDk2#E(ACprp01 z!!Z5KbG}|;%EnPwFU?c6DdqCg{jut)Kv6}Ds+Va`l{@TS4?j)O@OT|rgg-nzDPBZx z`5)JIsXGHAS zSDh32a%mNu3P?d5lRywVg| zxdAk#@w&PQe|UOQyogRxJpuA*)K2=|cT-Omf{jm?XAIKr_(4Wk$Y;n?Pz~;E z-Nkyl#^L3vXPA1*rQ8GU?Ah%fF*sncr;>hHINf zb=*6Sw=U`KiT?X-7h|~EtB)~u8)qCHpU`^V>z8dukU}8 z({WFFOoq1vanx(Z0mXW|Ca0JF==_IZ#hMW*?gw(KWo;|r3w(^ejugsyL};z!ZYCG?k_g z5t?RH-c@*Jx0a#FLbhnLW~^RmIyu}Dta!9AyOI5O4CFsB{UJsI8k*)z*%Gd0pKQmR zzI<1Z*QOlWsByp(yGZaK^Dn3?N;Sog=#P)lSGAj%te$%4nr;@`vfwl26|Yej(aj3i zl?zau8eD+-;%lBu6MkOfCs&zX?$1cYR7Q;7#-_1kYaP4bw2X`mYMjS@4W$O3zJVS4 zQR0=W4GyzKPt=TSBefXm!K8bqkBF(MwuSNO8tdViKftBv!edGk`i(Y`BK`snpo zgJKPcTb8w+9#6P7K819+=+BN1pFYmg;(6i2xqsA#YpfBEoy6Oo647#I(#pCQJL$u& zegyuEHd+NT2S}HTCz+VTuO8@(g&se-fqhe5x+?0KKUwzxNG! zPAIQ_n5mm``~jG#W`C13nIw{U>S0rcA6_X0gSHa^uO8ey{`TwlCAb&)yTAxIK77)1 zxtkRwg>geL7!(g4fa1{BlSc6nP%PZ5t%=6wLi@E)<~uyb@q`g}Bsl88J|{{($yt=Q56Vd+dq6_$|KmaZ-ZD(#oe< z{rp&T2zdA(}^leqh`;~QUs$8Kd`DDlUhUF!**chF`FEfj8DQS0Rk<+7V$ftt9 z6KyoLBRBLZnxVCEoieAOttN3pTE5ZGtYV$8=JPLHJZF$u>c#wUE;^UZ#aFK)BS2>L z!P2c@qpiWlqT)XOj=i)zdurjhiDFY~_P-;u+MVU$oc2Xb#Svpp(O|DGnJ(DDWdy=8 zEi=vw+H^7ppX&iq9EqkqhRlMz<{fxnooHWLtDIWy4?L7QwVfI4l?<>Ices4?%tX-~o?UotmQieIFP5LZF zW!3)Ny2;U!uY)lUNPc%_J8ZevRF->HI=aLF5ngIKt2aronNHIVn9Bqw0SrJ|@d8Xz zpG-(HQ&ITjLXP&x&jgqlOo{jM_f#?GWuU>gjUdYF!EzR#iIm0}g;Q~{N6r9vgsx@A z4RojSvces4$9nDA6NL<~O*cAbEz8IQ#I|h%hTn|$Iq*?m$5{u>FAH2|rkZd$*jE>TnX0wYpmQ|2EM0gFYZk%@S}#ttM`&-ZV{ zSEsq@c-Oz)r>O@M4b+gjvt6Aab7B2aFwn(xOTC6JCgr?NANsX&oo1|tfR_WNRei?;3dP(_g0j^ZM@e0efb}$>`@nq?-Jjn`kMj_4(_UPc0Lj6% z^-s%6aFbT5J^&^6|$C<>GRz1XD>2E)I#<%d^^u+7cO$L%c#vnjZucnz^#l5`i zSpJ5rLZ97wAT!0FO()69MsT4e8|gF~NzBUWfW!ojhu#4AelBi`T$~)QH_Md2;8W3G zY`q?t>%}1DY+-t$c#o;v<%5?qZOPQ_#nP>>$Y<2z2e@cwgmJSf3s!~32`GzfKl>keCyviI)ti5iE zdx=~Q$G{W2H#|I?fyvOCM?DJC(BHO~P)Ib?(V-@XrsGn8prc9&&X+&)>tBIZBJVRP z*d;BUDMcfwYptF%^euw~^-T)ux4m185Dw|M8UIwSEVX`6h`R2eJO=b8TzZzSnEAdR zQDJfCf;+`m^-o99|6+f7ma1>hMSC!2rDkA?v=P^eSq7=#y1ahzz5dAEq2f z3MzETRXSxJOFdCJ(V-9cR=r8c$f(LEvxp0s^3B394WhEEKX#^p zHl~p-_wDP{lsf?x)i?|{g&#HxOtf;KHZ{{5vqko2AZ)um)frR2EJ&z5t=W^yv4gqX?Mz35n1%)NbtM{Q_f-jS5Mn=CL-t|9C|zroj4(09v9!Wc~-% z50unAl@mVxypHNRezwtHcv}DX1Qyk5!cGt1YSBDj?TK9 z)`Vt}NyYL$hZH%{D6oR}!R7E^@Xa8?#obe=b>qV*)9v4-S$T#sCuPj=Xcpa6Dvylr zyK884(~jnN!8azB^><~>1K_Ke*M*aJ06$%BGm|hr)}DS@N-ySAhv>x%+j9?AhI5$F znCy-NQU7H2-1ww76?UfD*&KfV-0`-h&du`FM(@YFl`D5i9#Tt>=n@cMH)^s6cpTmc z>73i*srIU)$}+hAPU*w0`u;GPVy)>SAnKTY(JDyC`Q( zryy8-dgD%N=J@D+hGiAb4pL}FSAM&HIU!Y6&SJ_LDksNMj9H4~PL;Aefm4wh74sZy z0uL|38!s8sjY8{w67b-$#Au+%7Xe^$G!j3CmGJUKcr-*kr<)qT@#s0iQp}3JrMVlu zC=$kVLf8(N9DVnW{){UI@w6U9hX{Td z=OBh}#HXZXN}M?9Zq3Y#>Y~;ZnNc>1auO3X15-uE+_e3CNac)p?;!MJc&+)U@F>H7 z=z3}VM^O)zcm#eqzo&%-lD%=ZpM|PFa1|3gE^SDcbcD34Zo-%|Rn9zV0?CwpAi)dn zr<`e1I`xvlW)n>KGr(ZgIr_v3mrGcTu~v6DR9Yu&htN=w=LL2*Q#wOwXgbtgxr1_vCOiK}xxy&xRC(LT zWJ~QS5+j<~f+isr?aoPbFa{kaLQ(qu z6J~67M&B<{IfH1-DpQJOyz*>bP=q%~Ir!(xy{`z*$S#AIb{KD0-|c_0pWSXP+0Tp% zc4R-lx$ys2`}yWApe)t%dXaJsY5RFE(`t^T1MMt5%rZjLZz|$UR@yhHojt=;Ou3y+ z!!h`LNBhUz3AgNXA5q`{EZtjCX1E^Tj3pa>0w%f~xP_yw(|$8;7ml7q*Qbt-{~+d6 zoN9^YQfqMNmy47l^g4q+*Nj98S{iR~reKD&G1|^lNVw6{ZMjPkT>}6UcbTvO-B+pmy~sNitapZ zK~?|f?ST8An`8&vuKOl`pJkWZc0|i&*@dOmKyl2wuD_4COTg$SvIBIWoFypXSJ}f+ z*BS!a7%c+5>AlU5#y_V%^^UW=%#Iwaiyp!LoD~oB3hlx@aeMoSMgiW%3Dg5`_Vp$R z8bPmUF9YIi!dJ>wL@)o^(S0}o`3OlnV8c2`S%-E} zfayv{QpqO*OU|QV(N;`Ot>hr-gbF2WwegTQG>2}E)V|+HE164jDRob@ z1?410eB*ri$01k1mkU<-IH>I@s2>HYV_2=;?lkSQg|$HL;$DHb7OCAe!9I19Z*SKG z`vdBw1zS;>q%K)U?x2GGGL^hwzkd!5mkHKvcqat=E}>i|Sp66%*t;0c^nyLG*#vvX zxjPgrVlpKu6L7z+310weKf&%4?Pvbd*PGxtw38NlsOpvRsYvYrOE*PNJj?c9crNXl zLabFiQ@~wQhz{!Y58A>Mo@TQ8o8WcO*A%ZIVo<#*xY>nlj$zpS)P=%6Ba`4C4|gZbZS7hjL8lJWe2pDX7aT^@6Tj0ZFnqC zDb`bRLo0S9(m)liRxeQGm3f1~uuAd3h6die(bGP>_(iK1Pq*q>ivz`P<&wlzTuikY zEvFvW@;c2)*qvVXkaQ2;v#ey31&k4ATZfc1JyhIoRKASLK{Tc(O%G(#V@#`gOFz^> zefUgS`cPfOLADs?oZu2Qx(tXr)AI3ZStC=1l#Oqh9!W&To)o*%igWVMENd%T0mn05 zj6-xY_8s>Dkn^q%H%<-?@`oT7MXQ7P z>(3{Co@amF@I^RQciu2CG-s<5+}QB&1Z9##R9Ay*Zu{GVrPuH-SaH>ZjH)l2Uw2q; zbq#+G*BMZpqs5R4M{5UHJR|H_$;5enkMO9O;9$iqx&@us)}}-R1>LkV-}#~|b0}qWFrgc6ioW$Z zd);;buXQTKVd1OEq20L+*=3C*f)$SyuQLsnHC82gubtMVLlGJ|6k$FjE@X@S8usOK zF71KMZ?S8s+t$&%no33^CninZ3Mp#p@a~Fg4neGjE!|uc&RwZ$pgWsc)twy~bZ1Ac z=+2Jjx%#SLxfXLlSv}`OiZas`sfnKr6r~8rpCB1Eu!w=9uNRQ1TVCHitM2d`{yD57 zK7(vl=XXfA#jyn0#VDCoW_{n%w4`DeK_&Wdr%n@t-dPDyskU~ZAmcI6I|eXI5%3?l3^!OdCj*^b2)G(T9{?1e z#{40^QC$J>lLG|Q){`85Z3YT;5q_fpHVU;2UxQm|Jjc976DUoF|3kr z_u@VoM%;^=Tc6yB%Maa-FEZln{Nk>Km9tsF;Ob2fw4Ls+d|36c>z(NzshG#J??=A9 zfnm(brTj9=Q>?d+da0aa=lUz(q>|4$y3x~tnFIvyD37olWUinjF72GtEHsXh!yCFE zA~se~qlBS;VykI=X(Yo%nJFz$)51eIy3c`uz7NnpNy@ON(V*Oo$Byy31Djv$)H{TNfZ zRgI(R6~9}yG54x-&w~|>yd4v?{RKEvo^9E-`@L%7f_*u>GD5o+YyIUk@le3^H@Av- z0m$ZG;it0TIg7a480BxVc+?O+6TTX(s302E;?x*oQHkj3yUndNK>v*#;(Q@ex)BVn zB`i1r$zW)qx{tr^Zs)AtBx&3Obe?Fffe14zxcB3=yca6GY7DzOX4yRunL<@pd|=eU zu)4C8V{1_}Tip~zTR(?9rIDmxQFIZ%7zotaMA_m&AH4tk=VhgXrkYULFy-;wx(OgK ze>cJ$Cm2CO?zPH1%P)ic+2d)V@``my zG?E_CG4?9KDC}i_a@+cv_UWAd)cGUAr=~x#WCV9WcV!BD@Va>ewN2`(y*sr{54`+i z9pM?Qn8OKKkF{>Q4~R>~!lH#bPT&%2azq04ne!KgPk30dj;HAiR$N#aZlxyt*ZSbA zXej|QnzI6?RWyH=I{_U&!3s{8E;W*T{{n_E{Wb7?st9=>g~Qw4E#fwH)i!@VdDph7g3RG{) z;?7N7H9`JoI7$jsb-g&Y^+lbFVlBD0Gdy>_Fp7r%1p{eUsUqhsAVw7!P^D6M_$uSE zLXU^5H{R77vZ?Tqu9ruR*%q&+G0PvZm)xoe9FM!Y5`WVeKlnNymaybbmUjpYv)QLx zM!`hWEN6C78Lv-AFnfo_&*9K+)HiK(+=Esa6-~hArJwOTQGcnV*>X9&^u)od%?02%U?F_)YlXG!*8{z`K z;`w_Q+nNvV>;=`;A4$x~8ArZdZf4yGQu?_gf-5$f$KEHm!900;jN1XXx#Sl4C;4YduOcuJV$6j<1m;RKDWKH^>?qJ2qm3?*JuSJuMk9V9bW;`fZE0Y2HvYZEa zH3L=UI4urP>@7}i@SJi@n>Jd%Wd6vej|S~~pcL?HzQtJdKpma3Hgb_JcB~2i#2I&} zn%BoyuQA5XB2n5O*-@*8KQ3OB)lXNtn@Uqw8Ey!Bq}U>zL^*=1Rs|~_hnXFjZ0^OE zbE^*wnGuMhkArLYC!6>bAS1R$Cej~GkJo3^gu|&+0eK8rVImbAw+^J3N68$yco;qK zF9=13VMK_D4m;6iq~_aQG;87$ofmCvebaPjH@s*gj;0qYLUp(x zrlBbt_4r;WznFa1*#J%OyB`;76{(k7Z6QSw7H7OZ#{c}|O;#&dRVT3s9D z-vg21qq<%jH<4R^VAuLl+z>nF(fGt7zLPdG=7DCKikj{ilO67ZV!Ph}Y>Q#tuwD6z z$F?49#USYQ7&i(x`TH9|?+&QE_dx!c(2aTs$F7$~aplCA?)blGjg>Pxq$oxQ*ZYk~ z)A0dC592$NmQn_>->(5E)0UzHOlLgjKgqg*_z|_WX*KcjX&}I@s;>2853=wmW;ym{ zU>u=Di#u^l<-LF>{tEu>rgXaOyd1u6EiA&9 z!6;r=lNGdmVNamGKo0sVhWm)aBXchjQpXW^$GDt95qM8~cF}mOJ!f*Olts9Be&A-K zuNn@v9VK`#0`CTccl^lQdZ-;|T498W$~}!}htXJj&g9lfa~uN>*akd>*gGV6<2G!c z?{%HOEzs%+rK>Y(jzFjW8Ihrqg5wqtfM zvg@UBB}I}J?P*Gd0rNc8o=qNJ!5$PpCp~8#8V7(Wi?dOGdGNbT_dm^w0PFd?iX4P# zbu0>d`*`yQ=GpB)zD*-4!!_Jg2hu*fcz(XisK(P`l3}o0V^rMsZ`kJYTl8eU1{3}W zCyAYNnGVmd;z}p4C1$n7D4cbeC!YKqP1eb(i(6O4B!^}C{)Rb}i_e#+mS}`{{yvJ@ zx3eUN0J5W~y^lGCeo_1I&H+)o*lM{)Nrn1RRB{ngd8IgA^ojiD{P_r=xF%ArX>eqa zsAg1^`CII!#>?TSOxUN=2wcrh2>4toIi!+th!RrfsP_<3q%%Icy4y(x=nZL2iqi2V zOiIZ^LUb8>JnFs6Jr;u}4~3V(qL@5v|FlaU)QNzNmNygV_WrN8L&?{&vggX=tAu}u ztgN34IuU&2yi)A68^#9Go$_1nE)wD8n`Cl{rgr20lc*0GHH>f%BA>J)e6quH#mh!| zjuK?*Og7B`3}3aL2LP)H*L?%6^OWy$h6o*$#kEvj(=;<^U;0*4`a$$dP-ww)Q%$|k zD#=9`6Q?7M5YL%%&A;jICeWG{{4H_FG-aU5d!4!c>z+Hx4%DPj zFLCF1fRPQIg0g6NO>quyUUfLrFR_`Yb4{i>-zM1>sm}^zBDVv+f0c+CO$h|@8l63Q@;<~ibBTyIWB|0sh{$wJ2$3n1G77a z99P|OWMBSK&c1~R=OKdprwG#Yfos61+@uoTJEJz%I6B}(TLHD6UEPnxp6*iiBdL1o z8>v(7wS;a-AvXRMm=5_tdRQGNjU5PHs^!7I%A9+$!8Uj4*hGKT0tJKyH@J{~Gig8) z*ScEXA-Ys8R>?!!9NypQx%nIMX=<80 z6@Sw(rs;^F{mV?$NI)(i5wWE(gCdZN#v~XfS{5Qco-d(Nxz>~is&}jh$v+JfSE`|;Jg)rO(XbQBKS*4O+so8noF87PZlh8; zAw|(qzapCde3_;yybKTY}R2I$9gV`=J9CQHs8(%y>8D z`(rPpOS*D34c(FbUm$<42zhW48U*>2{{`}q!$5xVFHS421GsXHr_rpPbBOO#m2#K( zWLud|oJ`Mqc=26FrNo>8IMAH4U|8m!Ypme`nVo8;1J#^zWGdG03^H#kA(Qx)M6r_$ z?$$r2eak^}OtXAGJ9~rAXJz4c$kUjP&ELToW;zSMI_Ejzvo0W{^y@=3ZoTtef|@Nt z9bC88KMPc8{VqY>aJk2I@R;*8pq8BQ8?()e9u(83Rs5CTtz1=@niqi#4$f~ndOH6G z?R&%Z9lF(IT(DpFZV}idFf)1iMm4SE&O3E?Qv&0AC2QS6pNFtAAMf5lpULoQdpv0S zASr=H<~3j6P!+Uo!$tW?ys3_k&-(H-)1bk{bMd4y1)3W)Qm6F0nA_dh3WsKAO3~hG zcAQiVkbX``I_QJ_xl}86q2ghQtUaE=%Pm*8+4ww%0g}-S{xJBF8e1AN>56|IYB+9oNygd6I+4_zY5ic@6IO-@FVQ>KNZK5)`p^j7GmC=RQ@} zR(taZ{|f?_2tp^l#*a*cLFeomvAZ7t1sewJLC;)57~8+l|%u>V-&Tc~m`w(Q32GF>n2 zSw3dx#_4R_&yUkhzz#IJTy8dQ$j}WFG6Y^4XP%cf8-=SOIsza6teKb1LdKV1J{?VU zXT+cRhc|w|2t~*aA7dLXp`Nw&PRgV8H9MEDWvGY7G`hOQwlb}Pl6W$1y@|fJ$m2C3 zfzO`=FLPeFG&N7lmScNocEiP%Fci0R45%b9s$`Xuj+gfDx+PLkbbU6xs^TDiX)bsf z=@PE_3}#2QE~7CMFX0Vv%&)pboqdQE)*jiXb3f>y*^NgO-n zIQlv4qRTMY{c&A$QNkFyN^>jqRTS;JYV)HEG26RP(|z2wWOIMfyg$;b(ju355{(Wq zjpGUF-`H^j8k3z3-PlV{B#jXU8{#|YHUV*#7~%rV1fF=a16@f6rk<~Q9Z0&-8tofG zH`Dd5Q$2GC(l1Y&>2!M0cQow;XAvqIpS~UmtKTk2eyDTM(3{97(VatREE)VbWOjze z%Ic^r?=k`!&yly}@GB-ZuehG(;?49Q@Fz@}RCc|1KzTqNmzu0`vk%S>Ikz-2w`z28 z_F?f~%waGkR@t@wfbuvyE;UEv<{O;naE@eTZr$kOe8XAd0O^NuU}z7Z5hur=gacE) zveO(m&F1_xJC!Eb`CCV@n_?Mers_%3Ry-t=QfY#nhjawHNtIzHsP=X4d=U2giKKC< ziKMb=CGo$%t3ME|?v<|F^vtNPmkua*_2W|0Gj6KJP5!wMV50CL-~cR#j4}Td5jwt5 zzK7$F-I!K%u)Ewn$?c?ZF1MRoSHlI+{XE-M7kCr$-U<9t-s#XsY2X&c03mMEJObF~ z3IQz3llQGUU&EP4I#y7=Oy&EbV2jh96pvisdF9I~g18;At*LVRsho<~@hU(`!ApDF5%dNN*VvlQSzP@) zIy&|`x-rsH$R>@60Fb1NRb`vW z-H2jwoAo{O2$bpbF^iQfZY7ejGd)UsvzJk+aCC#grTkEPvp+|%_}T4FkDLTeUS$$Y zvpA~`poHQxM?+sNr1XYJrhUa3fIAdP0 z1wm3QX%~wUmQ+(NSg|zED+8?WSyeOCT_Mzj-SyEcmnNQ$&pMC#ETqNGc55a4lAn8P ztOlGsm>+01a7l9sr0WfmJ8LXekv75)$*U$So6Ef^Ur*;N9gWGF_-lB>VKbG#IEemN z1jOTcpJ3wnkjP>XboO%SwCFyaFT(wRlE?bnH>L}o>jpVYe;b(WGRkQ)+|-yUnUMSxo=(fr?~SubSmfEy2fSm z>kihbmuuiJo2SNt_dxkcE-B9{WGK7-BG2R<$xw$3{qz{PfM$(?x50`t>JBzLE8Q-^ zrjo?WIK(1a2HbF+TX*De@j{Yl2H${^7Se@h5`t|r0rzc85&xTpIZtx$LnN)lfhQ@8Buh zSiKoOX?MXkp9!}Iy+e*brF?;{7irMj%w5@Sa z_O!5o3SF?A+nhGV?V^^U+8aZAP9Mu`tw{IJ?=KoKTWf0umtWd=? zG4)hZHZfomc*=XH4fu8zEqc@oVE*y8EbuSbP?d6x%i50f)ZuSJ|KrCKuHdp#K9Hrgul{z7n z7N0;)Lv%B|5|v?YNof(^{LxU@6Dw z+51F*dv*HW!SWY0^)9DZb^canA|TR`n5nD3)-B`jE+1^SbumQPWJQ2;W#CAsHUmEePu}kRjRdA%682@b(B|`T{G8m}_TIQtr4|l4s}X(q*IXQw~onx8$5rB7y;3jh^Uo8W(eJrmQl_m-$=l zYNTv0aoj_8H8}s?APr`;2fTMk6@yBr`Q~ntzTlvoEgEsfsRYc^tpl(x^!g&u z11S#*rC2Myi)NMsy>6#~eiERC56Kiigllm89vuANR+i!1LV9fxVuy_Q*XKMV1_ydY zIncLix!thb{mw8z4+E%^eQ^Mzc4y!o30#R9zQSGC&m0z+-3K633_T{5U)@>8wh!!- zRPH!s$81|z4)o-m0{Z!3fL4_Qtzg(^cv-v^pk5VMDp@xr7v-i)(Xa1NmnU`X)b6

    HJS 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

    C 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 diff --git a/dlls/regex/lib_win/pcre.lib b/dlls/regex/lib_win/pcre.lib index 303c9274bc23cd44038aa9ba14839a302724b700..5645dd7356a669bbf10514140301ba6132758622 100755 GIT binary patch literal 454662 zcmeEv31C#k{r|k(O|m&)1B4qT&~S+YNeG0?Y!VU@azZ#1g=Ld0VIiBOn_Us>5lo_l zmDaY}*4F;2t!=HnYelrSO+Z2IrSxxWYY)^`P0<#uMG$KKpYP1Peedm&0}?#S`{vDj z=R4nPjyG@Sy?L7{OP$`Dt(PavO*J0r^XJXa%1&RnAlpcvCzBZqGcyIcIe{^@fw6J7 zGnO_%oHObfyX-#0sbplZvpVh7OzG{cFJ(%@ai(}L7U#7~nL_7HpX>K&nV!lbo|pWX zS^7E`Zeo_4S6IxJaV+L<$63rj>WAcveYuv!cE9CtG}U-rj%#b`oz2ZGC&!U*cg)Mn zwJ*;vU0GCEyuzNHGe0vcCo5xK`uvu6@EVu5+1=Q{q@HV>_3m1S-?v32 z_-kq%HO^*Ny{oy|(d_ay>odHrnnrJ}fz<4C*16L4Oq`OTQYtDP^{$3G-`1ei*5)Q> zjmuH*ZuY56{+cF7UA50yUGFlGTn)aRO$HLBz0QU@jp*Bw?ckD{6B^0U?7l7nYtTCs zTuNsK4F^f{HInA3&*x}xdR)QM_(9McxkgtywRH;ZW#xG#%L^*(Tb%BCS8Yy~uQ4a9 z&gIL=^0+*W-kmwTfh2o=fxWc2qHIMa8q?{m^LtPWIav*j2x=NVO+taYAtx(4C#%{` zI_zpc$X{VESYA|EQMfYS?r!k8ybaF!oGh2u+vv^7%*kqOs%flsNnO;Ib(&<6y<}xs zX-RHTk=@_0y`gaj3_vQ&-GC+sFYGin`OtHO(X{+xO}4~dR8W~$xx9E~B&!~GbF;gl z4&FPPe15OHK@+U7mo3jPE?-enqARJpS$gQy7uf5n^Vh4Lc#GHNay0w=wL4|6*5h8+ zmYPO?L$JxvV>5Ie+}-SGaP6pfHw62|4yQ(vZBTA6DP2*LS6NzO&&kM1%P+xMnv=G? zGAFGFabZQy{4}6tAQ$6Y2@=TKRpxPSckxacyhPD7g+&#G75ODa_G_~jTB%)73{o|XO*{GZS?g%_S2z36+v+4Y&k7~-^7KxW0~L3j zYL2e{aP7RFxw!_vr`qL}Ml~|;4Gvt&UN;RML3N?VxrFMv-u4!MJv!}{Mk%XnnA$B) zeLK}OHf(X%sY62M^2+?;l9iQ}_R>PpQ>mBAZk}0CSdyP#P?~FBm6K6m7=<#6%2pJV z=I0jL^H+z-&0kSmRG3>)o@Za1k4u93zfSA?l8W-OvOIfk`IX^$rR90Kr4`Ey?Q7SB z`;!HedCQmQuY}PE?q*e%lojVMht)NO*|6qHsJ;l#bLps={ySeyk#D^{*pQBqoI z=a*_GuH`ZeiD`x9;?%jnpsaAk@|EQ}&Wb3U*+sc!D=W&&OR1<4J4BIgxj zP%kT9<5*pgzjk$1aRuxy$EmXm-ty%YD~ng;uCSL^IC9snsc=+QR87%=!!`JB8+Su%KRPXe;9JmqS!W{TacftI0b*4KSQ{CIgF*YHMvHBT|-FF#d85s(z zwkxb*o5D)#6?VKqVHbN9w)9$seeNcOrB1i7A75f&n-*HwD>)W6Zc7Y1{sa¨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

    oEIvnrHTnt40|Z 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 Date: Sun, 6 Jul 2014 00:25:44 +0200 Subject: [PATCH 07/18] Regex: Update documentation + add regex_match_simple stock. --- plugins/include/regex.inc | 335 ++++++++++++++++++++++---------------- 1 file changed, 196 insertions(+), 139 deletions(-) diff --git a/plugins/include/regex.inc b/plugins/include/regex.inc index 62b616da..976e25d1 100755 --- a/plugins/include/regex.inc +++ b/plugins/include/regex.inc @@ -1,21 +1,44 @@ -/* Regular Expression API - * (C)2004 by David "BAILOPAN" Anderson - * Licensed under the GNU General Public License. - * No warranties of any kind. +/** + * Regular Expressions API + * By the AMX Mod X Development Team + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * this program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. */ #if defined _regex_included - #endinput + #endinput #endif #define _regex_included #if AMXX_VERSION_NUM >= 175 - #pragma reqlib regex - #if !defined AMXMODX_NOAUTOLOAD - #pragma loadlib regex - #endif + #pragma reqlib regex + #if !defined AMXMODX_NOAUTOLOAD + #pragma loadlib regex + #endif #else - #pragma library regex + #pragma library regex #endif @@ -27,14 +50,125 @@ enum Regex REGEX_OK }; +/** + * Precompile a regular expression. + * + * @note Use this if you intend on using the ame expression multiple times. + * Pass the regex handle returned here to regex_match_c to check for matches. + * + * @note This handle is automatically freed on map change. However, + * if you are completely done with it before then, you should + * call regex_free on this handle. + * + * @param pattern The regular expression pattern. + * @param ret Error code encountered, if applicable. + * @param error Error message encountered, if applicable. + * @param maxLen Maximum string length of the error buffer. + * @param flags General flags for the regular expression. + * i = Ignore case + * m = Multilines (affects ^ and $ so that they match + * the start/end of a line rather than matching the + * start/end of the string). + * s = Single line (affects . so that it matches any character, + * even new line characters). + * x = Pattern extension (ignore whitespace and # comments). + * + * @return -1 on error in the pattern, > valid regex handle (> 0) on success. + */ +native Regex:regex_compile(const pattern[], &ret, error[], maxLen, const flags[]=""); /** - * @section Flags for compiling regex expressions. - * These come directly from the pcre library and can be used in MatchRegex and CompileRegex. + * Matches a string against a pre-compiled regular expression pattern. * - * @note To be used with regex_compile_ex. - * Only available in 1.8.3 and above. - */ + * @note You should free the returned handle with regex_free() + * when you are done with this pattern. + * + * @note Use the regex handle passed to this function to extract + * matches with regex_substr(). + * + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param ret Error code, if applicable, or number of results on success. + * + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. + */ +native regex_match_c(const string[], Regex:pattern, &ret); + +/** + * Matches a string against a regular expression pattern. + * + * @note If you intend on using the same regular expression pattern + * multiple times, consider using regex_compile and regex_match_ex + * instead of making this function reparse the expression each time. + * + * @note Flags only exist in amxmodx 1.8 and later. + * + * @note You should free the returned handle with regex_free() + * when you are done extracting all of the substrings. + * + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param ret Error code, or result state of the match. + * @param error Error message, if applicable. + * @param maxLen Maximum length of the error buffer. + * @param flags General flags for the regular expression. + * i = Ignore case + * m = Multilines (affects ^ and $ so that they match + * the start/end of a line rather than matching the + * start/end of the string). + * s = Single line (affects . so that it matches any character, + * even new line characters). + * x = Pattern extension (ignore whitespace and # comments). + * + * @return -2 = Matching error (error code is stored in ret) + * -1 = Error in pattern (error message and offset # in error and ret) + * 0 = No match. + * >1 = Handle for getting more information (via regex_substr) + */ +native Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); + +/** + * Returns a matched substring from a regex handle. + * + * @note Substring ids start at 0 and end at ret - 1, where ret is from the corresponding + * regex_match, regex_match_c or regex_match_ex function call. + * + * @param id The regex handle to extract data from. + * @param str_id The index of the expression to get - starts at 0, and ends at ret - 1. + * @param buffer The buffer to set to the matching substring. + * @param maxLen The maximum string length of the buffer. + * + * @return 1 on success, otherwise 0 on failure. + */ +native regex_substr(Regex:id, str_id, buffer[], maxLen); + +/** + * Frees the memory associated with a regex result, and sets the handle to 0. + * + * @note This must be called on all results from regex_match() when you are done extracting + * the results with regex_substr(). + * + * @note The results of regex_compile() or regex_compile_ex() (and subsequently, regex_match_c() or regex_match_ex()) + * only need to be freed when you are done using the pattern. + * + * @note Do not use the handle again after freeing it! + * + * @param id The regex handle to free. + * @noreturn + */ +native regex_free(&Regex:id); + + +/** + * The following natives are only available in 1.8.3 and above. + */ + +/** + * Flags for compiling regex expressions. + * These come directly from the pcre library and can be used in regex_compile_ex. + */ #define PCRE_CASELESS 0x00000001 /* Ignore Case */ #define PCRE_MULTILINE 0x00000002 /* Multilines (affects ^ and $ so that they match the start/end of a line rather than matching the start/end of the string). */ #define PCRE_DOTALL 0x00000004 /* Single line (affects . so that it matches any character, even new line characters). */ @@ -45,13 +179,13 @@ enum Regex #define PCRE_NOTEMPTY 0x00000400 /* An empty string is not a valid match. */ #define PCRE_UTF8 0x00000800 /* Use UTF-8 Chars */ #define PCRE_NO_UTF8_CHECK 0x00002000 /* Do not check the pattern for UTF-8 validity (only relevant if PCRE_UTF8 is set) */ +#define PCRE_FIRSTLINE 0x00040000 /* Force matching to be before newline */ +#define PCRE_DUPNAMES 0x00080000 /* Allow duplicate names for subpattern */ #define PCRE_UCP 0x20000000 /* Use Unicode properties for \ed, \ew, etc. */ /** * Regex expression error codes. - * - * @note To be used with regex_compile_ex and regex_match_ex natives. - * Only available in 1.8.3 and above. + * This can be used with regex_compile_ex and regex_match_ex. */ enum RegexError { @@ -88,72 +222,25 @@ enum RegexError REGEX_ERROR_DFA_BADRESTART = -30, REGEX_ERROR_JIT_BADOPTION = -31, REGEX_ERROR_BADLENGTH = -32, + REGEX_ERROR_UNSET = -33 }; - /** - * Precompile a regular expression. Use this if you intend on using the - * same expression multiple times. Pass the regex handle returned here to - * regex_match_c to check for matches. + * Precompile a regular expression. * - * @param pattern The regular expression pattern. - * @param errcode Error code encountered, if applicable. - * @param error Error message encountered, if applicable. - * @param maxLen Maximum string length of the error buffer. - * @param flags General flags for the regular expression. - * i = Ignore case - * m = Multilines (affects ^ and $ so that they match - * the start/end of a line rather than matching the - * start/end of the string). - * s = Single line (affects . so that it matches any character, - * even new line characters). - * x = Pattern extension (ignore whitespace and # comments). + * @note Use this if you intend on using the ame expression multiple times. + * Pass the regex handle returned here to regex_match_ex() to check for matches. * - * @return -1 on error in the pattern, > valid regex handle (> 0) on success. + * @note Unlike regex_compile(), this allows you to use directly PCRE flags, and + * to get a more complete set of regular expression error codes. * - * @note This handle is automatically freed on map change. However, - * if you are completely done with it before then, you should - * call regex_free on this handle. - */ -native Regex:regex_compile(const pattern[], &ret, error[], maxLen, const flags[]=""); - -/** - * Matches a string against a pre-compiled regular expression pattern. + * @param pattern The regular expression pattern. + * @param flags General flags for the regular expression, see PCRE_* defines. + * @param error Error message encountered, if applicable. + * @param maxLen Maximum string length of the error buffer. + * @param errcode Regex type error code encountered, if applicable. * - * - * @param pattern The regular expression pattern. - * @param string The string to check. - * @param ret Error code, if applicable, or number of results on success. - * - * @return -2 = Matching error (error code is stored in ret) - * 0 = No match. - * >1 = Number of results. - * - * @note You should free the returned handle (with regex_free()) - * when you are done with this pattern. - * - * @note Use the regex handle passed to this function to extract - * matches with regex_substr(). - */ -native regex_match_c(const string[], Regex:pattern, &ret); - -/** - * Precompile a regular expression. - * - * @note Use this if you intend on using the ame expression multiple times. - * Pass the regex handle returned here to regex_match_ex to check for matches. - * - * @note Unlike regex_compile, this allows you to use directly PCRE flags, and - * to get a more complete set of regular expression error codes. - * Only available in 1.8.3 and above. - * - * @param pattern The regular expression pattern. - * @param flags General flags for the regular expression, see PCRE_* defines. - * @param error Error message encountered, if applicable. - * @param maxLen Maximum string length of the error buffer. - * @param errcode Regex type error code encountered, if applicable. - * - * @return Valid regex handle (> 0) on success, or -1 on failure. + * @return Valid regex handle (> 0) on success, or -1 on failure. */ native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = 0, &RegexError:errcode = REGEX_ERROR_NONE); @@ -166,79 +253,49 @@ native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = * @note You should free the returned handle with regex_free() * when you are done with this pattern. * - * @note Unlike regex_match_c(), this allows you to get a more complete + * @note Unlike regex_match_c(), this allows you to get a more complete * set of regular expression error codes and parameter is optional. - * Only available in 1.8.3 and above. * - * @param str The string to check. - * @param regex Regex Handle from regex_compile_ex() - * @param ret Error code, if applicable. + * @param str The string to check. + * @param regex Regex Handle from regex_compile_ex() + * @param ret Error code, if applicable. * - * @return -2 = Matching error (error code is stored in ret) - * 0 = No match. - * >1 = Number of results. + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. */ native regex_match_ex(Handle:regex, const str[], &RegexError:ret = REGEX_ERROR_NONE); /** * Matches a string against a regular expression pattern. * - * @note If you intend on using the same regular expression pattern - * multiple times, consider using regex_compile and regex_match_c - * instead of making this function reparse the expression each time. + * @note If you intend on using the same regular expression pattern + * multiple times, consider using compile regex_compilex_ex and regex_match_ex + * instead of making this function reparse the expression each time. * - * @param string The string to check. - * @param pattern The regular expression pattern. - * @param ret Error code, or result state of the match. - * @param error Error message, if applicable. - * @param maxLen Maximum length of the error buffer. - * @param flags General flags for the regular expression. - * i = Ignore case - * m = Multilines (affects ^ and $ so that they match - * the start/end of a line rather than matching the - * start/end of the string). - * s = Single line (affects . so that it matches any character, - * even new line characters). - * x = Pattern extension (ignore whitespace and # comments). + * @param str The string to check. + * @param pattern The regular expression pattern. + * @param flags General flags for the regular expression. + * @param error Error message, if applicable. + * @param maxLen Maximum length of the error buffer. * - * @return -2 = Matching error (error code is stored in ret) - * -1 = Error in pattern (error message and offset # in error and ret) - * 0 = No match. - * >1 = Handle for getting more information (via regex_substr) - * - * @note Flags only exist in amxmodx 1.8 and later. - * @note You should free the returned handle (with regex_free()) - * when you are done extracting all of the substrings. + * @return -2 = Matching error (error code is stored in ret) + * -1 = Pattern error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. */ -native Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); +stock regex_match_simple(const str[], const pattern[], flags = 0, error[]="", maxLen = 0) +{ + new Regex:regex = regex_compile_ex(pattern, flags, error, maxLen); -/** - * Returns a matched substring from a regex handle. - * - * @note Substring ids start at 0 and end at ret - 1, where ret is from the corresponding - * regex_match, regex_match_c or regex_match_ex function call. - * - * @param id The regex handle to extract data from. - * @param str_id The index of the expression to get - starts at 0, and ends at ret - 1. - * @param buffer The buffer to set to the matching substring. - * @param maxLen The maximum string length of the buffer. - * - * @return 1 on success, otherwise 0 on failure. - */ -native regex_substr(Regex:id, str_id, buffer[], maxLen); + if (regex < 0) + { + return -1; + } -/** - * Frees the memory associated with a regex result, and sets the handle to 0. - * - * @note This must be called on all results from regex_match() when you are done extracting - * the results with regex_substr(). - * - * @note The results of regex_compile() or regex_compile_ex() (and subsequently, regex_match_c() or regex_match_ex()) - * only need to be freed when you are done using the pattern. - * - * @note Do not use the handle again after freeing it! - * - * @param id The regex handle to free. - * @noreturn - */ -native regex_free(&Regex:id); + new substrings = regex_match_ex(regex, str); + + regex_free(regex); + + return substrings; +} From ee4f6b8a8921b8925c9a2afec75902882b27afed Mon Sep 17 00:00:00 2001 From: Arkshine Date: Sun, 6 Jul 2014 12:13:01 +0200 Subject: [PATCH 08/18] Regex: Use AMTL. --- dlls/regex/AMBuilder | 6 ++- dlls/regex/module.cpp | 82 ++++++++++++++++----------------- dlls/regex/msvc10/regex.vcxproj | 8 ++-- 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/dlls/regex/AMBuilder b/dlls/regex/AMBuilder index d1436354..9c79e1c7 100644 --- a/dlls/regex/AMBuilder +++ b/dlls/regex/AMBuilder @@ -10,8 +10,10 @@ elif builder.target_platform == 'mac': elif builder.target_platform == 'windows': binary.compiler.postlink += [binary.Dep('lib_win\\pcre.lib')] -binary.compiler.defines += ['PCRE_STATIC'] - +binary.compiler.defines += [ + 'PCRE_STATIC', + 'HAVE_STDINT_H', +] binary.sources = [ 'sdk/amxxmodule.cpp', 'module.cpp', diff --git a/dlls/regex/module.cpp b/dlls/regex/module.cpp index 48c58bd4..f175ce6d 100755 --- a/dlls/regex/module.cpp +++ b/dlls/regex/module.cpp @@ -1,55 +1,55 @@ /* AMX Mod X -* Regular Expressions Module -* -* by the AMX Mod X Development Team -* -* This file is part of AMX Mod X. -* -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation; either version 2 of the License, or (at -* your option) any later version. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* In addition, as a special exception, the author gives permission to -* link the code of this program with the Half-Life Game Engine ("HL -* Engine") and Modified Game Libraries ("MODs") developed by Valve, -* L.L.C ("Valve"). You must obey the GNU General Public License in all -* respects for all of the code used other than the HL Engine and MODs -* from Valve. If you modify this file, you may extend this exception -* to your version of the file, but you are not obligated to do so. If -* you do not wish to do so, delete this exception statement from your -* version. -*/ + * Regular Expressions Module + * + * by the AMX Mod X Development Team + * + * This file is part of AMX Mod X. + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + */ #include #include "pcre.h" #include "amxxmodule.h" -#include "CVector.h" +#include #include "CRegEx.h" -CVector PEL; +ke::Vector PEL; int GetPEL() { - for (int i=0; i<(int)PEL.size(); i++) + for (int i=0; i<(int)PEL.length(); i++) { if (PEL[i]->isFree()) return i; } RegEx *x = new RegEx(); - PEL.push_back(x); + PEL.append(x); - return (int)PEL.size() - 1; + return (int)PEL.length() - 1; } // native Regex:regex_compile(const pattern[], &ret, error[], maxLen, const flags[]=""); @@ -150,7 +150,7 @@ static cell AMX_NATIVE_CALL regex_match_c(AMX *amx, cell *params) int id = params[2]-1; const char *str = MF_GetAmxString(amx, params[1], 0, &len); - if (id >= (int)PEL.size() || id < 0 || PEL[id]->isFree()) + if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree()) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id); return 0; @@ -187,7 +187,7 @@ static cell AMX_NATIVE_CALL regex_match_ex(AMX *amx, cell *params) { int id = params[1] - 1; - if (id >= (int)PEL.size() || id < 0 || PEL[id]->isFree()) + if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree()) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id); return 0; @@ -226,7 +226,7 @@ static cell AMX_NATIVE_CALL regex_match_ex(AMX *amx, cell *params) static cell AMX_NATIVE_CALL regex_substr(AMX *amx, cell *params) { int id = params[1]-1; - if (id >= (int)PEL.size() || id < 0 || PEL[id]->isFree()) + if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree()) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id); return 0; @@ -252,7 +252,7 @@ static cell AMX_NATIVE_CALL regex_free(AMX *amx, cell *params) int id = *c; *c = 0; id -= 1; - if (id >= (int)PEL.size() || id < 0 || PEL[id]->isFree()) + if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree()) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id); return 0; @@ -282,7 +282,7 @@ void OnAmxxAttach() void OnAmxxDetach() { - for (int i = 0; i<(int)PEL.size(); i++) + for (int i = 0; i<(int)PEL.length(); i++) { if (PEL[i]) { diff --git a/dlls/regex/msvc10/regex.vcxproj b/dlls/regex/msvc10/regex.vcxproj index 06fd9a49..f2255e89 100644 --- a/dlls/regex/msvc10/regex.vcxproj +++ b/dlls/regex/msvc10/regex.vcxproj @@ -52,8 +52,8 @@ Disabled - ..\;..\sdk;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;REGEX_EXPORTS;PCRE_STATIC;%(PreprocessorDefinitions) + ..\;..\..\..\public\amtl;..\sdk;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;REGEX_EXPORTS;HAVE_STDINT_H;PCRE_STATIC;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebug @@ -75,8 +75,8 @@ - ..\;..\sdk;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;REGEX_EXPORTS;PCRE_STATIC;%(PreprocessorDefinitions) + ..\;..\..\..\public\amtl;..\sdk;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;REGEX_EXPORTS;HAVE_STDINT_H;PCRE_STATIC;%(PreprocessorDefinitions) MultiThreaded false From a44d20b26b35a2d9846f8f15fa71a0aab30013f8 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Mon, 7 Jul 2014 20:49:38 +0200 Subject: [PATCH 09/18] Regex: Add regex_match_all_c and regex_match_all natives (by Nextra) --- dlls/regex/CRegEx.cpp | 102 ++++++++++++++++++++++++++++++++------ dlls/regex/CRegEx.h | 13 ++++- dlls/regex/module.cpp | 90 +++++++++++++++++++++++---------- plugins/include/regex.inc | 57 ++++++++++++++++++++- 4 files changed, 219 insertions(+), 43 deletions(-) diff --git a/dlls/regex/CRegEx.cpp b/dlls/regex/CRegEx.cpp index efa374c4..4073621f 100755 --- a/dlls/regex/CRegEx.cpp +++ b/dlls/regex/CRegEx.cpp @@ -42,7 +42,7 @@ RegEx::RegEx() re = NULL; mFree = true; subject = NULL; - mSubStrings = 0; + mSubStrings.clear(); } void RegEx::Clear() @@ -54,9 +54,9 @@ void RegEx::Clear() re = NULL; mFree = true; if (subject) - delete [] subject; + delete[] subject; subject = NULL; - mSubStrings = 0; + mSubStrings.clear(); } RegEx::~RegEx() @@ -152,11 +152,11 @@ int RegEx::Match(const char *str) if (mFree || re == NULL) return -1; - + this->ClearMatch(); //save str - subject = new char[strlen(str)+1]; + subject = new char[strlen(str) + 1]; strcpy(subject, str); rc = pcre_exec(re, NULL, subject, (int)strlen(subject), 0, 0, ovector, 30); @@ -166,37 +166,110 @@ int RegEx::Match(const char *str) if (rc == PCRE_ERROR_NOMATCH) { return 0; - } else { + } + else { mErrorOffset = rc; return -1; } } - mSubStrings = rc; + RegExSub res; + mSubStrings.ensure(rc); + + for (int s = 0; s < rc; ++s) + { + res.start = ovector[2 * s]; + res.end = ovector[2 * s + 1]; + mSubStrings.append(res); + } return 1; } + +int RegEx::MatchAll(const char *str) +{ + int rc = 0; + int rr = 0; + int offset = 0; + + if (mFree || re == NULL) + return -1; + + this->ClearMatch(); + + //save str + subject = new char[strlen(str) + 1]; + strcpy(subject, str); + + RegExSub sub, whole; + while ((rr = pcre_exec(re, NULL, subject, (int)strlen(subject), offset, 0, ovector, 30))) + { + if (rr < 0) + { + if (rr == PCRE_ERROR_NOMATCH) + { + break; + } + else + { + mErrorOffset = rr; + + if (rc) + this->ClearMatch(); + + return -1; + } + } + + rc += rr; + mSubStrings.ensure(rc); + + for (int s = 1; s < rr; ++s) + { + sub.start = ovector[2 * s]; + sub.end = ovector[2 * s + 1]; + mSubStrings.append(sub); + } + + offset = ovector[1]; + } + + if (!rc) + return 0; + + sub = mSubStrings.at(0); + whole.start = sub.start; + sub = mSubStrings.back(); + whole.end = sub.end; + + mSubStrings.insert(0, whole); + + return 1; +} + void RegEx::ClearMatch() { // Clears match results mErrorOffset = 0; mError = NULL; if (subject) - delete [] subject; + delete[] subject; subject = NULL; - mSubStrings = 0; + mSubStrings.clear(); } const char *RegEx::GetSubstring(int s, char buffer[], int max) { int i = 0; - if (s >= mSubStrings || s < 0) + if ((size_t)s >= mSubStrings.length() || s < 0) return NULL; - char *substr_a = subject + ovector[2*s]; - int substr_l = ovector[2*s+1] - ovector[2*s]; + RegExSub sub = mSubStrings.at(s); - for (i = 0; i= max) break; @@ -206,5 +279,4 @@ const char *RegEx::GetSubstring(int s, char buffer[], int max) buffer[i] = '\0'; return buffer; -} - +} \ No newline at end of file diff --git a/dlls/regex/CRegEx.h b/dlls/regex/CRegEx.h index 498ab929..ed88824f 100755 --- a/dlls/regex/CRegEx.h +++ b/dlls/regex/CRegEx.h @@ -32,29 +32,40 @@ */ #ifndef _INCLUDE_CREGEX_H #define _INCLUDE_CREGEX_H + +#include class RegEx { public: + struct RegExSub { + int start, end; + }; + RegEx(); ~RegEx(); + bool isFree(bool set=false, bool val=false); void Clear(); int Compile(const char *pattern, const char* flags = NULL); int Compile(const char *pattern, int iFlags); int Match(const char *str); + int MatchAll(const char *str); void ClearMatch(); const char *GetSubstring(int s, char buffer[], int max); + public: int mErrorOffset; const char *mError; - int mSubStrings; + int Count() { return mSubStrings.length(); } + private: pcre *re; bool mFree; int ovector[30]; char *subject; + ke::Vector mSubStrings; }; #endif //_INCLUDE_CREGEX_H diff --git a/dlls/regex/module.cpp b/dlls/regex/module.cpp index f175ce6d..d3048a1b 100755 --- a/dlls/regex/module.cpp +++ b/dlls/regex/module.cpp @@ -79,7 +79,7 @@ static cell AMX_NATIVE_CALL regex_compile_ex(AMX *amx, cell *params) { int len; const char *regex = MF_GetAmxString(amx, params[1], 0, &len); - + int id = GetPEL(); RegEx *x = PEL[id]; @@ -95,9 +95,7 @@ static cell AMX_NATIVE_CALL regex_compile_ex(AMX *amx, cell *params) return id + 1; } -// 1.8 includes the last parameter -// Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); -static cell AMX_NATIVE_CALL regex_match(AMX *amx, cell *params) +cell match(AMX *amx, cell *params, bool all) { int len; const char *str = MF_GetAmxString(amx, params[1], 0, &len); @@ -105,24 +103,29 @@ static cell AMX_NATIVE_CALL regex_match(AMX *amx, cell *params) int id = GetPEL(); RegEx *x = PEL[id]; - + char* flags = NULL; - + if ((params[0] / sizeof(cell)) >= 6) // compiled with 1.8's extra parameter { flags = MF_GetAmxString(amx, params[6], 2, &len); } - + if (x->Compile(regex, flags) == 0) { cell *eOff = MF_GetAmxAddr(amx, params[3]); const char *err = x->mError; *eOff = x->mErrorOffset; - MF_SetAmxString(amx, params[4], err?err:"unknown", params[5]); + MF_SetAmxString(amx, params[4], err ? err : "unknown", params[5]); return -1; } - int e = x->Match(str); + int e; + if (all) + e = x->MatchAll(str); + else + e = x->Match(str); + if (e == -1) { /* there was a match error. destroy this and move on. */ @@ -130,24 +133,38 @@ static cell AMX_NATIVE_CALL regex_match(AMX *amx, cell *params) *res = x->mErrorOffset; x->Clear(); return -2; - } else if (e == 0) { + } + else if (e == 0) { cell *res = MF_GetAmxAddr(amx, params[3]); *res = 0; x->Clear(); return 0; - } else { + } + else { cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->mSubStrings; + *res = x->Count(); } - return id+1; + return id + 1; } -// native regex_match_c(const string[], Regex:id, &ret); -static cell AMX_NATIVE_CALL regex_match_c(AMX *amx, cell *params) +// 1.8 includes the last parameter +// Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); +static cell AMX_NATIVE_CALL regex_match(AMX *amx, cell *params) +{ + return match(amx, params, false); +} + +// Regex:regex_match_all(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); +static cell AMX_NATIVE_CALL regex_match_all(AMX *amx, cell *params) +{ + return match(amx, params, true); +} + +cell match_c(AMX *amx, cell *params, bool all) { int len; - int id = params[2]-1; + int id = params[2] - 1; const char *str = MF_GetAmxString(amx, params[1], 0, &len); if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree()) @@ -155,31 +172,50 @@ static cell AMX_NATIVE_CALL regex_match_c(AMX *amx, cell *params) MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id); return 0; } - + RegEx *x = PEL[id]; - int e = x->Match(str); + int e; + if (all) + e = x->MatchAll(str); + else + e = x->Match(str); + if (e == -1) { /* there was a match error. move on. */ cell *res = MF_GetAmxAddr(amx, params[3]); *res = x->mErrorOffset; /* only clear the match results, since the regex object - may still be referenced later */ + may still be referenced later */ x->ClearMatch(); return -2; - } else if (e == 0) { + } + else if (e == 0) { cell *res = MF_GetAmxAddr(amx, params[3]); *res = 0; /* only clear the match results, since the regex object - may still be referenced later */ + may still be referenced later */ x->ClearMatch(); return 0; - } else { - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->mSubStrings; - return x->mSubStrings; } + else { + cell *res = MF_GetAmxAddr(amx, params[3]); + *res = x->Count(); + return x->Count(); + } +} + +// native regex_match_c(const string[], Regex:id, &ret); +static cell AMX_NATIVE_CALL regex_match_c(AMX *amx, cell *params) +{ + return match_c(amx, params, false); +} + +// native regex_match_all_c(const string[], Regex:id, &ret); +static cell AMX_NATIVE_CALL regex_match_all_c(AMX *amx, cell *params) +{ + return match_c(amx, params, true); } // native regex_match_ex(Regex:id, const string[], &RegexError:ret = REGEX_ERROR_NONE); @@ -219,7 +255,7 @@ static cell AMX_NATIVE_CALL regex_match_ex(AMX *amx, cell *params) } else { - return x->mSubStrings; + return x->Count(); } } @@ -270,6 +306,8 @@ AMX_NATIVE_INFO regex_Natives[] = { {"regex_match", regex_match}, {"regex_match_c", regex_match_c}, {"regex_match_ex", regex_match_ex}, + {"regex_match_all", regex_match_all}, + {"regex_match_all_c", regex_match_all_c}, {"regex_substr", regex_substr}, {"regex_free", regex_free}, {NULL, NULL}, diff --git a/plugins/include/regex.inc b/plugins/include/regex.inc index 976e25d1..32f9646c 100755 --- a/plugins/include/regex.inc +++ b/plugins/include/regex.inc @@ -266,6 +266,61 @@ native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = */ native regex_match_ex(Handle:regex, const str[], &RegexError:ret = REGEX_ERROR_NONE); +/** + * Matches a string against a pre-compiled regular expression pattern, matching all + * occurances of the pattern inside the string. This is similar to using the "g" flag + * in perl regex. + * + * + * @param pattern The regular expression pattern. + * @param string The string to check. + * @param ret Error code, if applicable, or number of results on success. + * + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. + * + * @note You should free the returned handle (with regex_free()) + * when you are done with this pattern. + * + * @note Use the regex handle passed to this function to extract + * matches with regex_substr(). + */ +native regex_match_all_c(const string[], Regex:pattern, &ret); + +/** + * Matches a string against a regular expression pattern, matching all occurances of the + * pattern inside the string. This is similar to using the "g" flag in perl regex. + * + * @note If you intend on using the same regular expression pattern + * multiple times, consider using regex_compile and regex_match_c + * instead of making this function reparse the expression each time. + * + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param ret Error code, or result state of the match. + * @param error Error message, if applicable. + * @param maxLen Maximum length of the error buffer. + * @param flags General flags for the regular expression. + * i = Ignore case + * m = Multilines (affects ^ and $ so that they match + * the start/end of a line rather than matching the + * start/end of the string). + * s = Single line (affects . so that it matches any character, + * even new line characters). + * x = Pattern extension (ignore whitespace and # comments). + * + * @return -2 = Matching error (error code is stored in ret) + * -1 = Error in pattern (error message and offset # in error and ret) + * 0 = No match. + * >1 = Handle for getting more information (via regex_substr) + * + * @note Flags only exist in amxmodx 1.8 and later. + * @note You should free the returned handle (with regex_free()) + * when you are done extracting all of the substrings. + */ +native Regex:regex_match_all(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); + /** * Matches a string against a regular expression pattern. * @@ -298,4 +353,4 @@ stock regex_match_simple(const str[], const pattern[], flags = 0, error[]="", ma regex_free(regex); return substrings; -} +} \ No newline at end of file From 287f471ac497d8aac3acbc07ed377f5aa9fce558 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Tue, 8 Jul 2014 00:08:35 +0200 Subject: [PATCH 10/18] Regex: Remove regex_match_ex and RegexError tag, change regex_match_all to use flags and update documentation. - regex_match_ex was kind of duplicated. - regex_match_all uses now integer flags (header like regex_compiler_ex) - Removed RegexError tag to allow old natives to use these constants without mismatch tag error. - Made all error params optional --- dlls/regex/module.cpp | 119 ++++++-------- plugins/include/regex.inc | 329 +++++++++++++++++--------------------- 2 files changed, 196 insertions(+), 252 deletions(-) diff --git a/dlls/regex/module.cpp b/dlls/regex/module.cpp index d3048a1b..9bb08737 100755 --- a/dlls/regex/module.cpp +++ b/dlls/regex/module.cpp @@ -64,9 +64,8 @@ static cell AMX_NATIVE_CALL regex_compile(AMX *amx, cell *params) if (x->Compile(regex, flags) == 0) { - cell *eOff = MF_GetAmxAddr(amx, params[2]); const char *err = x->mError; - *eOff = x->mErrorOffset; + *MF_GetAmxAddr(amx, params[2]) = x->mErrorOffset; MF_SetAmxString(amx, params[3], err?err:"unknown", params[4]); return -1; } @@ -74,7 +73,7 @@ static cell AMX_NATIVE_CALL regex_compile(AMX *amx, cell *params) return id+1; } -// native Regex:regex_compile_ex(const pattern[], flags = 0, error[] = "", maxLen = 0, &RegexError:errcode = REGEX_ERROR_NONE); +// native Regex:regex_compile_ex(const pattern[], flags = 0, error[] = "", maxLen = 0, &errcode = 0); static cell AMX_NATIVE_CALL regex_compile_ex(AMX *amx, cell *params) { int len; @@ -85,9 +84,8 @@ static cell AMX_NATIVE_CALL regex_compile_ex(AMX *amx, cell *params) if (x->Compile(regex, params[2]) == 0) { - cell *eOff = MF_GetAmxAddr(amx, params[5]); const char *err = x->mError; - *eOff = x->mErrorOffset; + *MF_GetAmxAddr(amx, params[5]) = x->mErrorOffset; MF_SetAmxString(amx, params[3], err ? err : "unknown", params[4]); return -1; } @@ -104,23 +102,36 @@ cell match(AMX *amx, cell *params, bool all) int id = GetPEL(); RegEx *x = PEL[id]; - char* flags = NULL; + char *flags = NULL; + cell *errorCode; + int result = 0; - if ((params[0] / sizeof(cell)) >= 6) // compiled with 1.8's extra parameter + if (!all) { - flags = MF_GetAmxString(amx, params[6], 2, &len); + if (*params / sizeof(cell) >= 6) // compiled with 1.8's extra parameter + { + flags = MF_GetAmxString(amx, params[6], 2, &len); + } + + result = x->Compile(regex, flags); + errorCode = MF_GetAmxAddr(amx, params[3]); + } + else + { + result = x->Compile(regex, params[3]); + errorCode = MF_GetAmxAddr(amx, params[6]); } - if (x->Compile(regex, flags) == 0) + if (!result) { - cell *eOff = MF_GetAmxAddr(amx, params[3]); const char *err = x->mError; - *eOff = x->mErrorOffset; + *errorCode = x->mErrorOffset; MF_SetAmxString(amx, params[4], err ? err : "unknown", params[5]); return -1; } int e; + if (all) e = x->MatchAll(str); else @@ -129,33 +140,31 @@ cell match(AMX *amx, cell *params, bool all) if (e == -1) { /* there was a match error. destroy this and move on. */ - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->mErrorOffset; + *errorCode = x->mErrorOffset; x->Clear(); return -2; } - else if (e == 0) { - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = 0; + else if (e == 0) + { + *errorCode = 0; x->Clear(); return 0; } - else { - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->Count(); + else + { + *errorCode = x->Count(); } return id + 1; } -// 1.8 includes the last parameter -// Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); +// native Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); static cell AMX_NATIVE_CALL regex_match(AMX *amx, cell *params) { return match(amx, params, false); } -// Regex:regex_match_all(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); +// native Regex:regex_match_all(const string[], const pattern[], flags = 0, error[] = "", maxLen = 0, &errcode = 0); static cell AMX_NATIVE_CALL regex_match_all(AMX *amx, cell *params) { return match(amx, params, true); @@ -163,9 +172,7 @@ static cell AMX_NATIVE_CALL regex_match_all(AMX *amx, cell *params) cell match_c(AMX *amx, cell *params, bool all) { - int len; int id = params[2] - 1; - const char *str = MF_GetAmxString(amx, params[1], 0, &len); if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree()) { @@ -173,6 +180,10 @@ cell match_c(AMX *amx, cell *params, bool all) return 0; } + int len; + const char *str = MF_GetAmxString(amx, params[1], 0, &len); + cell *errorCode = MF_GetAmxAddr(amx, params[3]); + RegEx *x = PEL[id]; int e; @@ -184,24 +195,25 @@ cell match_c(AMX *amx, cell *params, bool all) if (e == -1) { /* there was a match error. move on. */ - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->mErrorOffset; + *errorCode = x->mErrorOffset; + /* only clear the match results, since the regex object may still be referenced later */ x->ClearMatch(); return -2; } - else if (e == 0) { - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = 0; + else if (e == 0) + { + *errorCode = 0; + /* only clear the match results, since the regex object may still be referenced later */ x->ClearMatch(); return 0; } - else { - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->Count(); + else + { + *errorCode = x->Count(); return x->Count(); } } @@ -218,47 +230,7 @@ static cell AMX_NATIVE_CALL regex_match_all_c(AMX *amx, cell *params) return match_c(amx, params, true); } -// native regex_match_ex(Regex:id, const string[], &RegexError:ret = REGEX_ERROR_NONE); -static cell AMX_NATIVE_CALL regex_match_ex(AMX *amx, cell *params) -{ - int id = params[1] - 1; - - if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree()) - { - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id); - return 0; - } - - int len; - const char *str = MF_GetAmxString(amx, params[2], 0, &len); - - RegEx *x = PEL[id]; - - int e = x->Match(str); - if (e == -1) - { - /* there was a match error. move on. */ - cell *res = MF_GetAmxAddr(amx, params[3]); - *res = x->mErrorOffset; - - /* only clear the match results, since the regex object - may still be referenced later */ - x->ClearMatch(); - return -2; - } - else if (e == 0) - { - /* only clear the match results, since the regex object - may still be referenced later */ - x->ClearMatch(); - return 0; - } - else - { - return x->Count(); - } -} - +// native regex_substr(Regex:id, str_id, buffer[], maxLen); static cell AMX_NATIVE_CALL regex_substr(AMX *amx, cell *params) { int id = params[1]-1; @@ -305,7 +277,6 @@ AMX_NATIVE_INFO regex_Natives[] = { {"regex_compile_ex", regex_compile_ex}, {"regex_match", regex_match}, {"regex_match_c", regex_match_c}, - {"regex_match_ex", regex_match_ex}, {"regex_match_all", regex_match_all}, {"regex_match_all_c", regex_match_all_c}, {"regex_substr", regex_substr}, diff --git a/plugins/include/regex.inc b/plugins/include/regex.inc index 32f9646c..9bff0b08 100755 --- a/plugins/include/regex.inc +++ b/plugins/include/regex.inc @@ -50,121 +50,6 @@ enum Regex REGEX_OK }; -/** - * Precompile a regular expression. - * - * @note Use this if you intend on using the ame expression multiple times. - * Pass the regex handle returned here to regex_match_c to check for matches. - * - * @note This handle is automatically freed on map change. However, - * if you are completely done with it before then, you should - * call regex_free on this handle. - * - * @param pattern The regular expression pattern. - * @param ret Error code encountered, if applicable. - * @param error Error message encountered, if applicable. - * @param maxLen Maximum string length of the error buffer. - * @param flags General flags for the regular expression. - * i = Ignore case - * m = Multilines (affects ^ and $ so that they match - * the start/end of a line rather than matching the - * start/end of the string). - * s = Single line (affects . so that it matches any character, - * even new line characters). - * x = Pattern extension (ignore whitespace and # comments). - * - * @return -1 on error in the pattern, > valid regex handle (> 0) on success. - */ -native Regex:regex_compile(const pattern[], &ret, error[], maxLen, const flags[]=""); - -/** - * Matches a string against a pre-compiled regular expression pattern. - * - * @note You should free the returned handle with regex_free() - * when you are done with this pattern. - * - * @note Use the regex handle passed to this function to extract - * matches with regex_substr(). - * - * @param string The string to check. - * @param pattern The regular expression pattern. - * @param ret Error code, if applicable, or number of results on success. - * - * @return -2 = Matching error (error code is stored in ret) - * 0 = No match. - * >1 = Number of results. - */ -native regex_match_c(const string[], Regex:pattern, &ret); - -/** - * Matches a string against a regular expression pattern. - * - * @note If you intend on using the same regular expression pattern - * multiple times, consider using regex_compile and regex_match_ex - * instead of making this function reparse the expression each time. - * - * @note Flags only exist in amxmodx 1.8 and later. - * - * @note You should free the returned handle with regex_free() - * when you are done extracting all of the substrings. - * - * @param string The string to check. - * @param pattern The regular expression pattern. - * @param ret Error code, or result state of the match. - * @param error Error message, if applicable. - * @param maxLen Maximum length of the error buffer. - * @param flags General flags for the regular expression. - * i = Ignore case - * m = Multilines (affects ^ and $ so that they match - * the start/end of a line rather than matching the - * start/end of the string). - * s = Single line (affects . so that it matches any character, - * even new line characters). - * x = Pattern extension (ignore whitespace and # comments). - * - * @return -2 = Matching error (error code is stored in ret) - * -1 = Error in pattern (error message and offset # in error and ret) - * 0 = No match. - * >1 = Handle for getting more information (via regex_substr) - */ -native Regex:regex_match(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); - -/** - * Returns a matched substring from a regex handle. - * - * @note Substring ids start at 0 and end at ret - 1, where ret is from the corresponding - * regex_match, regex_match_c or regex_match_ex function call. - * - * @param id The regex handle to extract data from. - * @param str_id The index of the expression to get - starts at 0, and ends at ret - 1. - * @param buffer The buffer to set to the matching substring. - * @param maxLen The maximum string length of the buffer. - * - * @return 1 on success, otherwise 0 on failure. - */ -native regex_substr(Regex:id, str_id, buffer[], maxLen); - -/** - * Frees the memory associated with a regex result, and sets the handle to 0. - * - * @note This must be called on all results from regex_match() when you are done extracting - * the results with regex_substr(). - * - * @note The results of regex_compile() or regex_compile_ex() (and subsequently, regex_match_c() or regex_match_ex()) - * only need to be freed when you are done using the pattern. - * - * @note Do not use the handle again after freeing it! - * - * @param id The regex handle to free. - * @noreturn - */ -native regex_free(&Regex:id); - - -/** - * The following natives are only available in 1.8.3 and above. - */ - /** * Flags for compiling regex expressions. * These come directly from the pcre library and can be used in regex_compile_ex. @@ -187,7 +72,7 @@ native regex_free(&Regex:id); * Regex expression error codes. * This can be used with regex_compile_ex and regex_match_ex. */ -enum RegexError +enum /*RegexError*/ { REGEX_ERROR_NONE = 0, /* No error */ REGEX_ERROR_NOMATCH = -1, /* No match was found */ @@ -225,6 +110,121 @@ enum RegexError REGEX_ERROR_UNSET = -33 }; +/** + * Precompile a regular expression. + * + * @note Use this if you intend on using the ame expression multiple times. + * Pass the regex handle returned here to regex_match_c to check for matches. + * + * @note This handle is automatically freed on map change. However, + * if you are completely done with it before then, you should + * call regex_free on this handle. + * + * @param pattern The regular expression pattern. + * @param ret Error code encountered, if applicable. + * @param error Error message encountered, if applicable. + * @param maxLen Maximum string length of the error buffer. + * @param flags General flags for the regular expression. + * i = Ignore case + * m = Multilines (affects ^ and $ so that they match + * the start/end of a line rather than matching the + * start/end of the string). + * s = Single line (affects . so that it matches any character, + * even new line characters). + * x = Pattern extension (ignore whitespace and # comments). + * + * @return -1 on error in the pattern, > valid regex handle (> 0) on success. + */ +native Regex:regex_compile(const pattern[], &ret = 0, error[] = "", maxLen = 0, const flags[]=""); + +/** + * Matches a string against a pre-compiled regular expression pattern. + * + * @note You should free the returned handle with regex_free() + * when you are done with this pattern. + * + * @note Use the regex handle passed to this function to extract + * matches with regex_substr(). + * + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param ret Error code, if applicable, or number of results on success. See REGEX_ERROR_* defines. + * + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. + */ +native regex_match_c(const string[], Regex:pattern, &ret = 0); + +/** + * Matches a string against a regular expression pattern. + * + * @note If you intend on using the same regular expression pattern + * multiple times, consider using regex_compile and regex_match_ex + * instead of making this function reparse the expression each time. + * + * @note Flags only exist in amxmodx 1.8 and later. + * + * @note You should free the returned handle with regex_free() + * when you are done extracting all of the substrings. + * + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param ret Error code, or result state of the match. + * @param error Error message, if applicable. + * @param maxLen Maximum length of the error buffer. + * @param flags General flags for the regular expression. + * i = Ignore case + * m = Multilines (affects ^ and $ so that they match + * the start/end of a line rather than matching the + * start/end of the string). + * s = Single line (affects . so that it matches any character, + * even new line characters). + * x = Pattern extension (ignore whitespace and # comments). + * + * @return -2 = Matching error (error code is stored in ret) + * -1 = Error in pattern (error message and offset # in error and ret) + * 0 = No match. + * >1 = Handle for getting more information (via regex_substr) + */ +native Regex:regex_match(const string[], const pattern[], &ret = 0, error[] = "", maxLen = 0, const flags[] = ""); + +/** + * Returns a matched substring from a regex handle. + * + * @note Substring ids start at 0 and end at ret - 1, where ret is from the corresponding + * regex_match, regex_match_c or regex_match_ex function call. + * + * @param id The regex handle to extract data from. + * @param str_id The index of the expression to get - starts at 0, and ends at ret - 1. + * @param buffer The buffer to set to the matching substring. + * @param maxLen The maximum string length of the buffer. + * + * @return 1 on success, otherwise 0 on failure. + */ +native regex_substr(Regex:id, str_id, buffer[], maxLen); + +/** + * Frees the memory associated with a regex result, and sets the handle to 0. + * + * @note This must be called on all results from regex_match() when you are done extracting + * the results with regex_substr(). + * + * @note The results of regex_compile() or regex_compile_ex() (and subsequently, regex_match_c() or regex_match_ex()) + * only need to be freed when you are done using the pattern. + * + * @note Do not use the handle again after freeing it! + * + * @param id The regex handle to free. + * @noreturn + */ +native regex_free(&Regex:id); + + +/** + * The following natives are only available in 1.8.3 and above. + */ + /** * Precompile a regular expression. * @@ -238,33 +238,11 @@ enum RegexError * @param flags General flags for the regular expression, see PCRE_* defines. * @param error Error message encountered, if applicable. * @param maxLen Maximum string length of the error buffer. - * @param errcode Regex type error code encountered, if applicable. + * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. * * @return Valid regex handle (> 0) on success, or -1 on failure. */ -native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = 0, &RegexError:errcode = REGEX_ERROR_NONE); - -/** - * Matches a string against a pre-compiled regular expression pattern. - * - * @note Use the regex handle passed to this function to extract - * matches with regex_substr(). - * - * @note You should free the returned handle with regex_free() - * when you are done with this pattern. - * - * @note Unlike regex_match_c(), this allows you to get a more complete - * set of regular expression error codes and parameter is optional. - * - * @param str The string to check. - * @param regex Regex Handle from regex_compile_ex() - * @param ret Error code, if applicable. - * - * @return -2 = Matching error (error code is stored in ret) - * 0 = No match. - * >1 = Number of results. - */ -native regex_match_ex(Handle:regex, const str[], &RegexError:ret = REGEX_ERROR_NONE); +native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0); /** * Matches a string against a pre-compiled regular expression pattern, matching all @@ -272,54 +250,49 @@ native regex_match_ex(Handle:regex, const str[], &RegexError:ret = REGEX_ERROR_N * in perl regex. * * - * @param pattern The regular expression pattern. - * @param string The string to check. - * @param ret Error code, if applicable, or number of results on success. + * @param pattern The regular expression pattern. + * @param string The string to check. + * @param ret Error code, if applicable, or number of results on success. + * See REGEX_ERROR_* defines. * - * @return -2 = Matching error (error code is stored in ret) - * 0 = No match. - * >1 = Number of results. + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of results. * - * @note You should free the returned handle (with regex_free()) - * when you are done with this pattern. + * @note You should free the returned handle (with regex_free()) + * when you are done with this pattern. * - * @note Use the regex handle passed to this function to extract - * matches with regex_substr(). + * @note Use the regex handle passed to this function to extract + * matches with regex_substr(). */ -native regex_match_all_c(const string[], Regex:pattern, &ret); +native regex_match_all_c(const string[], Regex:pattern, &ret = 0); /** * Matches a string against a regular expression pattern, matching all occurances of the * pattern inside the string. This is similar to using the "g" flag in perl regex. * - * @note If you intend on using the same regular expression pattern - * multiple times, consider using regex_compile and regex_match_c - * instead of making this function reparse the expression each time. + * @note If you intend on using the same regular expression pattern + * multiple times, consider using regex_compile and regex_match_ex + * instead of making this function reparse the expression each time. * - * @param string The string to check. - * @param pattern The regular expression pattern. - * @param ret Error code, or result state of the match. - * @param error Error message, if applicable. - * @param maxLen Maximum length of the error buffer. - * @param flags General flags for the regular expression. - * i = Ignore case - * m = Multilines (affects ^ and $ so that they match - * the start/end of a line rather than matching the - * start/end of the string). - * s = Single line (affects . so that it matches any character, - * even new line characters). - * x = Pattern extension (ignore whitespace and # comments). + * @note Flags only exist in amxmodx 1.8 and later. * - * @return -2 = Matching error (error code is stored in ret) - * -1 = Error in pattern (error message and offset # in error and ret) - * 0 = No match. - * >1 = Handle for getting more information (via regex_substr) + * @note You should free the returned handle with regex_free() + * when you are done extracting all of the substrings. * - * @note Flags only exist in amxmodx 1.8 and later. - * @note You should free the returned handle (with regex_free()) - * when you are done extracting all of the substrings. + * @param string The string to check. + * @param pattern The regular expression pattern. + * @param flags General flags for the regular expression, see PCRE_* defines. + * @param error Error message encountered, if applicable. + * @param maxLen Maximum string length of the error buffer. + * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. + * + * @return -2 = Matching error (error code is stored in ret) + * -1 = Error in pattern (error message and offset # in error and ret) + * 0 = No match. + * >1 = Handle for getting more information (via regex_substr) */ -native Regex:regex_match_all(const string[], const pattern[], &ret, error[], maxLen, const flags[] = ""); +native Regex:regex_match_all(const string[], const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0); /** * Matches a string against a regular expression pattern. @@ -339,16 +312,16 @@ native Regex:regex_match_all(const string[], const pattern[], &ret, error[], max * 0 = No match. * >1 = Number of results. */ -stock regex_match_simple(const str[], const pattern[], flags = 0, error[]="", maxLen = 0) +stock regex_match_simple(const str[], const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0) { - new Regex:regex = regex_compile_ex(pattern, flags, error, maxLen); + new Regex:regex = regex_compile_ex(pattern, flags, error, maxLen, errcode); if (regex < 0) { return -1; } - new substrings = regex_match_ex(regex, str); + new substrings = regex_match_c(regex, str); regex_free(regex); From 939a724b1ad74f0ba9714aed18405f3744f03bfa Mon Sep 17 00:00:00 2001 From: Arkshine Date: Thu, 17 Jul 2014 11:20:52 +0200 Subject: [PATCH 11/18] Regex: Add regex_replace native. --- dlls/regex/AMBuilder | 1 + dlls/regex/CRegEx.cpp | 664 ++++++++++++++++++++++-- dlls/regex/CRegEx.h | 28 +- dlls/regex/module.cpp | 40 ++ dlls/regex/msvc10/regex.vcxproj | 2 + dlls/regex/msvc10/regex.vcxproj.filters | 6 + dlls/regex/utils.cpp | 236 +++++++++ dlls/regex/utils.h | 8 + plugins/include/regex.inc | 51 +- plugins/testsuite/regex_test.sma | 451 ++++++++++++++++ support/PackageScript | 1 + 11 files changed, 1432 insertions(+), 56 deletions(-) create mode 100644 dlls/regex/utils.cpp create mode 100644 dlls/regex/utils.h create mode 100644 plugins/testsuite/regex_test.sma diff --git a/dlls/regex/AMBuilder b/dlls/regex/AMBuilder index 9c79e1c7..ae88213a 100644 --- a/dlls/regex/AMBuilder +++ b/dlls/regex/AMBuilder @@ -18,6 +18,7 @@ binary.sources = [ 'sdk/amxxmodule.cpp', 'module.cpp', 'CRegEx.cpp', + 'utils.cpp', ] AMXX.modules += [builder.Add(binary)] diff --git a/dlls/regex/CRegEx.cpp b/dlls/regex/CRegEx.cpp index 4073621f..1a1cfdef 100755 --- a/dlls/regex/CRegEx.cpp +++ b/dlls/regex/CRegEx.cpp @@ -30,10 +30,12 @@ * you do not wish to do so, delete this exception statement from your * version. */ +#include "amxxmodule.h" #include "pcre.h" #include "CRegEx.h" #include -#include "amxxmodule.h" +#include +#include "utils.h" RegEx::RegEx() { @@ -43,6 +45,9 @@ RegEx::RegEx() mFree = true; subject = NULL; mSubStrings.clear(); + mMatchesSubs.clear(); + mSubsNameTable.clear(); + mNumSubpatterns = 0; } void RegEx::Clear() @@ -57,6 +62,9 @@ void RegEx::Clear() delete[] subject; subject = NULL; mSubStrings.clear(); + mMatchesSubs.clear(); + mSubsNameTable.clear(); + mNumSubpatterns = 0; } RegEx::~RegEx() @@ -143,6 +151,19 @@ int RegEx::Compile(const char *pattern, int iFlags) mFree = false; + /** + * Retrieve the number of captured groups + * including the full match. + */ + pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &mNumSubpatterns); + ++mNumSubpatterns; + + /** + * Build the table with the named groups, + * which contain an index and a name per group. + */ + MakeSubpatternsTable(mNumSubpatterns); + return 1; } @@ -153,13 +174,13 @@ int RegEx::Match(const char *str) if (mFree || re == NULL) return -1; - this->ClearMatch(); + ClearMatch(); //save str subject = new char[strlen(str) + 1]; strcpy(subject, str); - rc = pcre_exec(re, NULL, subject, (int)strlen(subject), 0, 0, ovector, 30); + rc = pcre_exec(re, NULL, subject, (int)strlen(subject), 0, 0, ovector, REGEX_MAX_SUBPATTERNS); if (rc < 0) { @@ -188,61 +209,103 @@ int RegEx::Match(const char *str) int RegEx::MatchAll(const char *str) { - int rc = 0; int rr = 0; - int offset = 0; + int rc = 0; + int startOffset = 0; + int exoptions = 0; + int notEmpty = 0; + int sizeOffsets = mNumSubpatterns * 3; + int subjectLen = strlen(str); if (mFree || re == NULL) + { return -1; + } - this->ClearMatch(); - - //save str - subject = new char[strlen(str) + 1]; + ClearMatch(); + + subject = new char[subjectLen + 1]; strcpy(subject, str); - RegExSub sub, whole; - while ((rr = pcre_exec(re, NULL, subject, (int)strlen(subject), offset, 0, ovector, 30))) + RegExSub sub; + + while (1) { - if (rr < 0) + rr = pcre_exec(re, NULL, subject, (int)subjectLen, startOffset, exoptions | notEmpty, ovector, REGEX_MAX_SUBPATTERNS); + + /** + * The string was already proved to be valid UTF-8 + */ + exoptions |= PCRE_NO_UTF8_CHECK; + + /** + * Too many substrings + */ + if (rr == 0) { - if (rr == PCRE_ERROR_NOMATCH) + rr = sizeOffsets / 3; + } + + if (rr > 0) + { + mMatchesSubs.append(rr); + + for (int s = 0; s < rr; ++s) { - break; + sub.start = ovector[2 * s]; + sub.end = ovector[2 * s + 1]; + + mSubStrings.append(sub); + } + } + else if (rr == PCRE_ERROR_NOMATCH) + { + /** + * If we previously set PCRE_NOTEMPTY after a null match, + * this is not necessarily the end. We need to advance + * the start offset, and continue. Fudge the offset values + * to achieve this, unless we're already at the end of the string. + */ + if (notEmpty && startOffset < (int)subjectLen) + { + ovector[0] = startOffset; + ovector[1] = startOffset + 1; } else { - mErrorOffset = rr; - - if (rc) - this->ClearMatch(); - - return -1; + break; } } - - rc += rr; - mSubStrings.ensure(rc); - - for (int s = 1; s < rr; ++s) + else { - sub.start = ovector[2 * s]; - sub.end = ovector[2 * s + 1]; - mSubStrings.append(sub); + mErrorOffset = rr; + + if (mMatchesSubs.length()) + { + ClearMatch(); + } + + return -1; } - offset = ovector[1]; + /** + * If we have matched an empty string, mimic what Perl's /g options does. + * This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try + * the match again at the same point. If this fails (picked up above) we + * advance to the next character. + */ + notEmpty = (ovector[1] == ovector[0]) ? PCRE_NOTEMPTY | PCRE_ANCHORED : 0; + + /** + * Advance to the next piece. + */ + startOffset = ovector[1]; } - if (!rc) + if (!mMatchesSubs.length()) + { return 0; - - sub = mSubStrings.at(0); - whole.start = sub.start; - sub = mSubStrings.back(); - whole.end = sub.end; - - mSubStrings.insert(0, whole); + } return 1; } @@ -256,18 +319,14 @@ void RegEx::ClearMatch() delete[] subject; subject = NULL; mSubStrings.clear(); + mMatchesSubs.clear(); } -const char *RegEx::GetSubstring(int s, char buffer[], int max) +const char *getSubstring(char *subject, size_t start, size_t end, char buffer[], size_t max, size_t *outlen) { - int i = 0; - if ((size_t)s >= mSubStrings.length() || s < 0) - return NULL; - - RegExSub sub = mSubStrings.at(s); - - char *substr_a = subject + sub.start; - int substr_l = sub.end - sub.start; + size_t i; + char * substr_a = subject + start; + size_t substr_l = end - start; for (i = 0; i < substr_l; i++) { @@ -278,5 +337,516 @@ const char *RegEx::GetSubstring(int s, char buffer[], int max) buffer[i] = '\0'; + if (outlen) + { + *outlen = i; + } + return buffer; -} \ No newline at end of file +} + +const char *RegEx::GetSubstring(size_t start, char buffer[], size_t max, size_t *outlen) +{ + if (start < 0 || start >= mSubStrings.length()) + { + return NULL; + } + + RegExSub sub = mSubStrings.at(start); + + return getSubstring(subject, sub.start, sub.end, buffer, max, outlen); +} + +const char *RegEx::GetSubstring(size_t startOffset, size_t endOffset, char buffer[], size_t max, size_t *outlen) +{ + if (startOffset < 0 || endOffset < 0) + { + return NULL; + } + + return getSubstring(subject, startOffset, endOffset, buffer, max, outlen); +} + +void RegEx::MakeSubpatternsTable(int numSubpatterns) +{ + int nameCount = 0; + int rc = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &nameCount); + + if (rc < 0) + { + return; + } + + if (nameCount > 0) + { + const char *nameTable; + int nameSize = 0; + int i = 0; + + int rc1 = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &nameTable); + int rc2 = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameSize); + + rc = rc2 ? rc2 : rc1; + + if (rc < 0) + { + mSubsNameTable.clear(); + return; + } + + NamedGroup data; + + while (i++ < nameCount) + { + data.index = 0xff * (unsigned char)nameTable[0] + (unsigned char)nameTable[1]; + data.name = nameTable + 2; + + mSubsNameTable.append(ke::Move(data)); + nameTable += nameSize; + } + } +} + +int RegEx::Replace(char *text, size_t textMaxLen, const char *replace, size_t replaceLen, int flags) +{ + char *output = text; + + /** + * Retrieve all matches and store them in + * mSubStrings list. + */ + if (MatchAll(output) == -1) + { + return -1; + } + + size_t subjectLen = strlen(subject); + size_t total = 0; + size_t baseIndex = 0; + size_t diffLength = 0; + + char *toReplace = new char[textMaxLen + 1]; + char *toSearch = NULL; + + /** + * All characters which is not matched are not copied when replacing matches. + * Then original text (output buffer) should be considerated as empty. + */ + if (flags & REGEX_FORMAT_NOCOPY) + { + *output = '\0'; + } + else + { + /** + * This is used only when we do replace matches. + */ + toSearch = new char[textMaxLen + 1]; + } + + /** + * Loop over all matches found. + */ + for (size_t i = 0; i < mMatchesSubs.length(); ++i) + { + char *ptr = toReplace; + + size_t browsed = 0; + size_t searchLen = 0; + size_t length = 0; + + /** + * Build the replace string as it can contain backreference + * and this needs to be parsed. + */ + for (const char *s = replace, *end = s + replaceLen; s < end && browsed <= textMaxLen; ++s, ++browsed) + { + unsigned int c = *s; + + /** + * Supported format specifiers: + * + * $number : Substitutes the substring matched by group number. + * n must be an integer value designating a valid backreference, greater than 0, and of two digits at most. + * ${name} : Substitutes the substring matched by the named group name (a maximum of 32 characters). + * $& : Substitutes a copy of the whole match. + * $` : Substitutes all the text of the input string before the match. + * $' : Substitutes all the text of the input string after the match. + * $+ : Substitutes the last group that was captured. + * $_ : Substitutes the entire input string. + * $$ : Substitutes a literal "$". + */ + if (c == '$' || c == '\\') + { + switch (*++s) + { + case '\0': + { + /** + * End of string. + * Copy one character. + */ + *(ptr + browsed) = c; + break; + } + case '&': + { + /** + * Concatenate retrieved full match sub-string. + * length - 1 to overwrite EOS. + */ + GetSubstring(baseIndex, ptr + browsed, textMaxLen, &length); + browsed += length - 1; + break; + } + case '`': + { + /** + * Concatenate part of original text up to + * first sub-string position. + */ + length = mSubStrings.at(baseIndex).start; + memcpy(ptr + browsed, subject, length); + browsed += length - 1; + break; + } + case '\'': + { + /** + * Concatenate part of original text from + * last sub-string end position to EOS. + */ + length = mSubStrings.at(baseIndex).end; + memcpy(ptr + browsed, subject + length, subjectLen - length); + browsed += (subjectLen - length) - 1; + break; + } + case '+': + { + /** + * Copy the last group that was captured. + */ + GetSubstring(baseIndex + mMatchesSubs.at(i) - 1, ptr + browsed, textMaxLen, &length); + browsed += length - 1; + break; + } + case '_': + { + /** + * Copy the entire input string. + */ + memcpy(ptr + browsed, subject, subjectLen); + browsed += (subjectLen - 1); + break; + } + case '$': + case '\\': + { + /** + * Copy the single character $ or \. + */ + *(ptr + browsed) = c; + break; + } + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '{': + { + /** + * Checking backreference. + * Which can be either $n, ${n} or ${name}. + */ + size_t backref = -1; + const char *walk = s; + bool inBrace = false; + bool nameCheck = false; + + /** + * ${nn}. + * ^ + */ + if (*walk == '{') + { + inBrace = true; + ++walk; + } + + /** + * Valid number. + * $nn or ${nn} + * ^ ^ + */ + if (*walk >= '0' && *walk <= '9') + { + backref = *walk - '0'; + ++walk; + } + else if (inBrace) + { + nameCheck = true; + + /** + * Not a valid number. + * Checking as string. + * ${name} + * ^ + */ + if (*walk) + { + const char *pch = strchr(walk, '}'); + + if (pch != NULL) + { + /** + * A named group maximum character is 32 (PCRE). + */ + char name[32]; + size_t nameLength = strncopy(name, walk, pch - walk + 1); + + int flags, num = 0; + pcre_fullinfo(re, NULL, PCRE_INFO_OPTIONS, &flags); + + /** + * If PCRE_DUPNAMES is set, the pcre_copy_named_substring function should be used + * as pcre_get_stringnumber output order is not defined. + */ + if (flags & PCRE_DUPNAMES) + { + memset(ovector, 0, REGEX_MAX_SUBPATTERNS); + + /** + * pcre_copy_named_substring needs a vector containing sub-patterns ranges + * for a given match. + */ + for (size_t j = 0; j < mMatchesSubs.at(i); ++j) + { + ovector[2 * j] = mSubStrings.at(baseIndex + j).start; + ovector[2 * j + 1] = mSubStrings.at(baseIndex + j).end; + } + + num = pcre_copy_named_substring(re, subject, ovector, mMatchesSubs.at(i), name, ptr + browsed, (int)textMaxLen); + + if (num != PCRE_ERROR_NOSUBSTRING) + { + browsed += num - 1; + s = pch; + break; + } + ++pch; + } + else + { + /** + * Retrieve sub-pattern index from a give name. + */ + num = pcre_get_stringnumber(re, name); + if (num != PCRE_ERROR_NOSUBSTRING) + { + backref = num; + walk = ++pch; + } + } + + if (num == PCRE_ERROR_NOSUBSTRING || num >= (int)mMatchesSubs.at(i)) + { + /** + * If a sub-string for a given match is not found, or if > to + * number of sub-patterns we still need to check if this + * group name is a valid one because if so we want to escape it. + * Looking at the name table. + */ + bool found = false; + for (size_t i = 0; i < mSubsNameTable.length(); ++i) + { + if (!mSubsNameTable.at(i).name.compare(name)) + { + --browsed; + s = --pch; + found = true; + break; + } + } + + if (found) + { + continue; + } + } + } + } + } + + if (!nameCheck) + { + /** + * Valid second number. + * $nn or ${nn} + * ^ ^ + */ + if (*walk && *walk >= '0' && *walk <= '9') + { + backref = backref * 10 + *walk - '0'; + ++walk; + } + + if (inBrace) + { + /** + * Invalid specifier + * Either hit EOS or missing }. + * ${n or ${nn or ${nx or ${nnx + * ^ ^ ^ ^ + */ + if (*walk == '\0' || *walk != '}') + { + backref = -1; + } + else + { + ++walk; + } + } + } + + length = walk - s; + s = --walk; + + /** + * We can't provide a capture number >= to total that pcre_exec has found. + * 0 is implicitly accepted, same behavior as $&. + */ + if (backref >= 0 && (int)backref < mNumSubpatterns) + { + /** + * Valid available index for a given match. + */ + if (backref < mMatchesSubs.at(i)) + { + /** + * Concatenate retrieved sub-string. + * length - 1 to overwrite EOS. + */ + GetSubstring(baseIndex + backref, ptr + browsed, textMaxLen, &length); + browsed += length - 1; + } + else + { + /** + * Valid unavailable index for a given match. + */ + --browsed; + } + } + else + { + /** + * If we here it means the syntax is valid but sub-pattern doesn't exist. + * So, copy as it is, including $. + */ + memcpy(ptr + browsed, s - length, length + 1); + browsed += length; + } + + break; + } + default: + { + /** + * Not a valid format modifier. + * So we copy characters as it is. + */ + *(ptr + browsed) = *s; + break; + } + } + } + else + { + /** + * At this point, direct copy. + */ + *(ptr + browsed) = c; + } + } + + *(ptr + browsed) = '\0'; + + /** + * Concatenate only replace string of each match, + * as we don't want to copy unmatched characters. + */ + if (flags & REGEX_FORMAT_NOCOPY) + { + /** + * We want just the first occurrence. + */ + if (total++ && (flags & REGEX_FORMAT_FIRSTONLY)) + { + break; + } + + strncat(output, toReplace, textMaxLen + 1); + } + else + { + /** + * Retrieves full string of a given match. + */ + const char *search = GetSubstring(baseIndex, toSearch, textMaxLen, &searchLen); + + /** + * We get something to replace, but the sub-pattern to search is empty. + * We insert replacement either a the start end or string. + */ + if (*toReplace && !searchLen) + { + if (output - text > 0) + { + strncat(output, toReplace, textMaxLen); + } + else + { + strncat(toReplace, text, textMaxLen); + strncopy(text, toReplace, strlen(toReplace) + 1); + } + + ++total; + } + else if ((output = UTIL_ReplaceEx(text + mSubStrings.at(baseIndex).start + diffLength, textMaxLen, search, searchLen, toReplace, browsed, false)) != NULL) + { + /** + * Then we simply do a replace. + * Probably not the most efficient, but this should be at least safe. + * To avoid issue where the function could find a string which is not at the expected index, + * We force the input string to start from index of the full match. + */ + ++total; + } + + if (total && (flags & REGEX_FORMAT_FIRSTONLY)) + { + break; + } + } + + /** + * mMatchesSubs is a flat list containing all sub-patterns of all matches. + * A number of sub-patterns can vary per match. So we calculate the position in the list, + * from where the first sub-pattern result of current match starts. + */ + baseIndex += mMatchesSubs.at(i); + diffLength += browsed - searchLen; + } + + delete[] toReplace; + + if (toSearch != NULL) + { + delete[] toSearch; + } + + /** + * Return the number of successful replacements. + */ + return total; +} diff --git a/dlls/regex/CRegEx.h b/dlls/regex/CRegEx.h index ed88824f..d1f19912 100755 --- a/dlls/regex/CRegEx.h +++ b/dlls/regex/CRegEx.h @@ -34,6 +34,19 @@ #define _INCLUDE_CREGEX_H #include +#include + +/** + * Maximum number of sub-patterns, here 50 (this should be a multiple of 3). + */ +#define REGEX_MAX_SUBPATTERNS 150 + +/** + * Flags to used with regex_replace, to control the replacement behavior. + */ +#define REGEX_FORMAT_DEFAULT 0 // Uses the standard formatting rules to replace matches. +#define REGEX_FORMAT_NOCOPY 1 // The sections that do not match the regular expression are not copied when replacing matches. +#define REGEX_FORMAT_FIRSTONLY 2 // Only the first occurrence of a regular expression is replaced. class RegEx { @@ -42,6 +55,11 @@ public: int start, end; }; + struct NamedGroup { + ke::AString name; + size_t index; + }; + RegEx(); ~RegEx(); @@ -52,8 +70,11 @@ public: int Compile(const char *pattern, int iFlags); int Match(const char *str); int MatchAll(const char *str); + int Replace(char *text, size_t text_maxlen, const char *replace, size_t replaceLen, int flags = 0); void ClearMatch(); - const char *GetSubstring(int s, char buffer[], int max); + const char *GetSubstring(size_t start, char buffer[], size_t max, size_t *outlen = NULL); + const char *GetSubstring(size_t start, size_t end, char buffer[], size_t max, size_t *outlen = NULL); + void MakeSubpatternsTable(int numSubpatterns); public: int mErrorOffset; @@ -63,9 +84,12 @@ public: private: pcre *re; bool mFree; - int ovector[30]; + int ovector[REGEX_MAX_SUBPATTERNS]; char *subject; ke::Vector mSubStrings; + ke::Vector mMatchesSubs; + ke::Vector mSubsNameTable; + int mNumSubpatterns; }; #endif //_INCLUDE_CREGEX_H diff --git a/dlls/regex/module.cpp b/dlls/regex/module.cpp index 9bb08737..70fbe8b1 100755 --- a/dlls/regex/module.cpp +++ b/dlls/regex/module.cpp @@ -153,6 +153,8 @@ cell match(AMX *amx, cell *params, bool all) else { *errorCode = x->Count(); + if (all) + return x->Count(); } return id + 1; @@ -272,6 +274,43 @@ static cell AMX_NATIVE_CALL regex_free(AMX *amx, cell *params) return 1; } +//native regex_replace(Regex:pattern, string[], maxLen, const replace[], flags = REGEX_FORMAT_DEFAULT, &errcode = 0); +static cell AMX_NATIVE_CALL regex_replace(AMX *amx, cell *params) +{ + int id = params[1] - 1; + if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree()) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id); + return 0; + } + + int textLen, replaceLen; + char *text = MF_GetAmxString(amx, params[2], 0, &textLen); + const char *replace = MF_GetAmxString(amx, params[4], 1, &replaceLen); + + cell *erroCode = MF_GetAmxAddr(amx, params[6]); + + RegEx *x = PEL[id]; + int e = x->Replace(text, params[3] + 1, replace, replaceLen, params[5]); + + if (e == -1) + { + *erroCode = x->mErrorOffset; + x->ClearMatch(); + return -2; + } + else if (e == 0) + { + *erroCode = 0; + x->ClearMatch(); + return 0; + } + + MF_SetAmxString(amx, params[2], text, params[3]); + + return e; +} + AMX_NATIVE_INFO regex_Natives[] = { {"regex_compile", regex_compile}, {"regex_compile_ex", regex_compile_ex}, @@ -280,6 +319,7 @@ AMX_NATIVE_INFO regex_Natives[] = { {"regex_match_all", regex_match_all}, {"regex_match_all_c", regex_match_all_c}, {"regex_substr", regex_substr}, + {"regex_replace", regex_replace}, {"regex_free", regex_free}, {NULL, NULL}, }; diff --git a/dlls/regex/msvc10/regex.vcxproj b/dlls/regex/msvc10/regex.vcxproj index f2255e89..96257caf 100644 --- a/dlls/regex/msvc10/regex.vcxproj +++ b/dlls/regex/msvc10/regex.vcxproj @@ -99,6 +99,7 @@ + @@ -107,6 +108,7 @@ + diff --git a/dlls/regex/msvc10/regex.vcxproj.filters b/dlls/regex/msvc10/regex.vcxproj.filters index 2f71fd98..b3be6a74 100644 --- a/dlls/regex/msvc10/regex.vcxproj.filters +++ b/dlls/regex/msvc10/regex.vcxproj.filters @@ -32,6 +32,9 @@ Module SDK\SDK Base + + Source Files + @@ -52,6 +55,9 @@ Module SDK\SDK Base + + Header Files + diff --git a/dlls/regex/utils.cpp b/dlls/regex/utils.cpp new file mode 100644 index 00000000..9b9debc0 --- /dev/null +++ b/dlls/regex/utils.cpp @@ -0,0 +1,236 @@ + +#include "amxxmodule.h" +#include +#include "utils.h" + +int UTIL_CheckValidChar(char *c) +{ + int count; + int bytecount = 0; + + for (count = 1; (*c & 0xC0) == 0x80; count++) + { + c--; + } + + switch (*c & 0xF0) + { + case 0xC0: + case 0xD0: + { + bytecount = 2; + break; + } + case 0xE0: + { + bytecount = 3; + break; + } + case 0xF0: + { + bytecount = 4; + break; + } + } + + if (bytecount != count) + { + return count; + } + + return 0; +} + +unsigned int strncopy(char *dest, const char *src, size_t count) +{ + if (!count) + { + return 0; + } + + char *start = dest; + while ((*src) && (--count)) + { + *dest++ = *src++; + } + *dest = '\0'; + + return (dest - start); +} + +/** +* NOTE: Do not edit this for the love of god unless you have +* read the test cases and understand the code behind each one. +* While I don't guarantee there aren't mistakes, I do guarantee +* that plugins will end up relying on tiny idiosyncrasies of this +* function, just like they did with AMX Mod X. +* +* There are explicitly more cases than the AMX Mod X version because +* we're not doing a blind copy. Each case is specifically optimized +* for what needs to be done. Even better, we don't have to error on +* bad buffer sizes. Instead, this function will smartly cut off the +* string in a way that pushes old data out. +*/ +char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t searchLen, const char *replace, size_t replaceLen, bool caseSensitive) +{ + char *ptr = subject; + size_t browsed = 0; + size_t textLen = strlen(subject); + + /* It's not possible to search or replace */ + if (searchLen > textLen) + { + return NULL; + } + + /* Handle the case of one byte replacement. + * It's only valid in one case. + */ + if (maxLen == 1) + { + /* If the search matches and the replace length is 0, + * we can just terminate the string and be done. + */ + if ((caseSensitive ? strcmp(subject, search) : stricmp(subject, search)) == 0 && replaceLen == 0) + { + *subject = '\0'; + return subject; + } + else + { + return NULL; + } + } + + /* Subtract one off the maxlength so we can include the null terminator */ + maxLen--; + + while (*ptr != '\0' && (browsed <= textLen - searchLen)) + { + /* See if we get a comparison */ + if ((caseSensitive ? strncmp(ptr, search, searchLen) : strnicmp(ptr, search, searchLen)) == 0) + { + if (replaceLen > searchLen) + { + /* First, see if we have enough space to do this operation */ + if (maxLen - textLen < replaceLen - searchLen) + { + /* First, see if the replacement length goes out of bounds. */ + if (browsed + replaceLen >= maxLen) + { + /* EXAMPLE CASE: + * Subject: AABBBCCC + * Buffer : 12 bytes + * Search : BBB + * Replace: DDDDDDDDDD + * OUTPUT : AADDDDDDDDD + * POSITION: ^ + */ + /* If it does, we'll just bound the length and do a strcpy. */ + replaceLen = maxLen - browsed; + + /* Note, we add one to the final result for the null terminator */ + strncopy(ptr, replace, replaceLen + 1); + + /* Don't truncate a multi-byte character */ + if (*(ptr + replaceLen - 1) & 1 << 7) + { + replaceLen -= UTIL_CheckValidChar(ptr + replaceLen - 1); + *(ptr + replaceLen) = '\0'; + } + } + else + { + /* EXAMPLE CASE: + * Subject: AABBBCCC + * Buffer : 12 bytes + * Search : BBB + * Replace: DDDDDDD + * OUTPUT : AADDDDDDDCC + * POSITION: ^ + */ + /* We're going to have some bytes left over... */ + size_t origBytesToCopy = (textLen - (browsed + searchLen)) + 1; + size_t realBytesToCopy = (maxLen - (browsed + replaceLen)) + 1; + char *moveFrom = ptr + searchLen + (origBytesToCopy - realBytesToCopy); + char *moveTo = ptr + replaceLen; + + /* First, move our old data out of the way. */ + memmove(moveTo, moveFrom, realBytesToCopy); + + /* Now, do our replacement. */ + memcpy(ptr, replace, replaceLen); + } + } + else + { + /* EXAMPLE CASE: + * Subject: AABBBCCC + * Buffer : 12 bytes + * Search : BBB + * Replace: DDDD + * OUTPUT : AADDDDCCC + * POSITION: ^ + */ + /* Yes, we have enough space. Do a normal move operation. */ + char *moveFrom = ptr + searchLen; + char *moveTo = ptr + replaceLen; + + /* First move our old data out of the way. */ + size_t bytesToCopy = (textLen - (browsed + searchLen)) + 1; + memmove(moveTo, moveFrom, bytesToCopy); + + /* Now do our replacement. */ + memcpy(ptr, replace, replaceLen); + } + } + else if (replaceLen < searchLen) + { + /* EXAMPLE CASE: + * Subject: AABBBCCC + * Buffer : 12 bytes + * Search : BBB + * Replace: D + * OUTPUT : AADCCC + * POSITION: ^ + */ + /* If the replacement does not grow the string length, we do not + * need to do any fancy checking at all. Yay! + */ + char *moveFrom = ptr + searchLen; /* Start after the search pointer */ + char *moveTo = ptr + replaceLen; /* Copy to where the replacement ends */ + + /* Copy our replacement in, if any */ + if (replaceLen) + { + memcpy(ptr, replace, replaceLen); + } + + /* Figure out how many bytes to move down, including null terminator */ + size_t bytesToCopy = (textLen - (browsed + searchLen)) + 1; + + /* Move the rest of the string down */ + memmove(moveTo, moveFrom, bytesToCopy); + } + else + { + /* EXAMPLE CASE: + * Subject: AABBBCCC + * Buffer : 12 bytes + * Search : BBB + * Replace: DDD + * OUTPUT : AADDDCCC + * POSITION: ^ + */ + /* We don't have to move anything around, just do a straight copy */ + memcpy(ptr, replace, replaceLen); + } + + return ptr + replaceLen; + } + ptr++; + browsed++; + } + + return NULL; +} \ No newline at end of file diff --git a/dlls/regex/utils.h b/dlls/regex/utils.h new file mode 100644 index 00000000..05644312 --- /dev/null +++ b/dlls/regex/utils.h @@ -0,0 +1,8 @@ +#ifndef UTILS_H +#define UTILS_H + +int UTIL_CheckValidChar(char *c); +char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t searchLen, const char *replace, size_t replaceLen, bool caseSensitive); +unsigned int strncopy(char *dest, const char *src, size_t count); + +#endif // UTILS_H \ No newline at end of file diff --git a/plugins/include/regex.inc b/plugins/include/regex.inc index 9bff0b08..1f22a722 100755 --- a/plugins/include/regex.inc +++ b/plugins/include/regex.inc @@ -44,10 +44,10 @@ enum Regex { - REGEX_MATCH_FAIL = -2, - REGEX_PATTERN_FAIL, - REGEX_NO_MATCH, - REGEX_OK + REGEX_MATCH_FAIL = -2, + REGEX_PATTERN_FAIL = -1, + REGEX_NO_MATCH = 0, + REGEX_OK = 1 }; /** @@ -231,8 +231,7 @@ native regex_free(&Regex:id); * @note Use this if you intend on using the ame expression multiple times. * Pass the regex handle returned here to regex_match_ex() to check for matches. * - * @note Unlike regex_compile(), this allows you to use directly PCRE flags, and - * to get a more complete set of regular expression error codes. + * @note Unlike regex_compile(), this allows you to use directly PCRE flags. * * @param pattern The regular expression pattern. * @param flags General flags for the regular expression, see PCRE_* defines. @@ -306,6 +305,7 @@ native Regex:regex_match_all(const string[], const pattern[], flags = 0, error[] * @param flags General flags for the regular expression. * @param error Error message, if applicable. * @param maxLen Maximum length of the error buffer. + * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. * * @return -2 = Matching error (error code is stored in ret) * -1 = Pattern error (error code is stored in ret) @@ -326,4 +326,41 @@ stock regex_match_simple(const str[], const pattern[], flags = 0, error[]= "", m regex_free(regex); return substrings; -} \ No newline at end of file +} + +/** + * Flags to used with regex_replace, to control the replacement behavior. + */ +#define REGEX_FORMAT_DEFAULT 0 /* Uses the standard formatting rules to replace matches */ +#define REGEX_FORMAT_NOCOPY (1<<0) /* The sectionsthat do not match the regular expression are not copied when replacing matches. */ +#define REGEX_FORMAT_FIRSTONLY (1<<1) /* Only the first occurrence of a regular expression is replaced. */ + +/** + * Perform a regular expression search and replace. + * + * An optional parameter, flags, allows to specify options on how format the expression. + * Supported format specifiers for replace parameter: + * $number : Substitutes the substring matched by group number. + * n must be an integer value designating a valid backreference, greater than 0, and of two digits at most. + * ${name} : Substitutes the substring matched by the named group name (a maximum of 32 characters). + * $& : Substitutes a copy of the whole match. + * $` : Substitutes all the text of the input string before the match. + * $' : Substitutes all the text of the input string after the match. + * $+ : Substitutes the last group that was captured. + * $_ : Substitutes the entire input string. + * $$ : Substitutes a literal "$". + * As note, the character \ can be also used with format specifier, this is same hehavior as $. + * + * @param pattern The regular expression pattern. + * @param string The string to check. + * @param error Error message, if applicable. + * @param maxLen Maximum length of the error buffer. + * @param replace The string will be used to replace any matches. See above for format specifiers. + * @param flags General flags to control how is replaced the string. See REGEX_FORMAT_* defines. + * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. + * + * @return -2 = Matching error (error code is stored in ret) + * 0 = No match. + * >1 = Number of matches. + */ +native regex_replace(Regex:pattern, string[], maxLen, const replace[], flags = REGEX_FORMAT_DEFAULT, &errcode = 0); \ No newline at end of file diff --git a/plugins/testsuite/regex_test.sma b/plugins/testsuite/regex_test.sma new file mode 100644 index 00000000..8a524bc1 --- /dev/null +++ b/plugins/testsuite/regex_test.sma @@ -0,0 +1,451 @@ +#include +#include + +/** + * Warning: To get expected result, file encoding must be UTF-8 without BOM. + */ + +public plugin_init() +{ + register_plugin("UTF-8 Test", AMXX_VERSION_STR, "AMXX Dev Team"); + register_srvcmd("regex_test", "OnServerCommand"); +} + +new FailedCount; +new PassedCount; + +test(const regex[], const replace[], const string[], const expectedString[], expectedCount = -1, regexFlags = 0, formatFlags = 0, bufferlen = -1) +{ + new errorCode, error[128]; + new Regex:r = regex_compile_ex(regex, regexFlags, error, charsmax(error), errorCode); + + if (r == REGEX_PATTERN_FAIL || errorCode) + { + server_print("^t^t#%d. Pattern fail : ^"%s^"(%d)", ++FailedCount + PassedCount, error, errorCode); + } + else + { + new buffer[512]; + copy(buffer, charsmax(buffer), string); + + new errorCode; + new count = regex_replace(r, buffer, bufferlen != -1 ? bufferlen : charsmax(buffer), replace, formatFlags, errorCode); + + if (expectedCount != -1 && count != expectedCount) + { + server_print("^t^t#%d. Failed - count = %d, expected count = %d", ++FailedCount + PassedCount, count, expectedCount); + } + else if (!equal(buffer, expectedString)) + { + server_print("^t^t#%d. Failed - output = %s, expected output = %s", ++FailedCount + PassedCount, buffer, expectedString); + } + else + { + ++PassedCount; + } + + regex_free(r); + } +} +end() +{ + server_print("Tests successful: %d/%d", PassedCount, PassedCount + FailedCount); +} + +public OnServerCommand() +{ + server_print("Testing regex_replace()"); + + server_print("^tChecking count..."); + { + test( .regex = "(([0-9a-z]+)-([0-9]+))-(([0-9]+)-([0-9]+))", + .replace = "xxxx", + .string = "1-2-3-4 a-2-3-4 1-a-3-4 1-2-a-4 1-2-3-a a-a-a-a 4-3-2-1 100-200-300-400-500-600-700-800", + .expectedString = "xxxx xxxx 1-a-3-4 1-2-a-4 1-2-3-a a-a-a-a xxxx xxxx-xxxx", + .expectedCount = 5 + ); + + test( .regex = "([a-z]+)", + .replace = "xxxx", + .string = "Here must only number like 42 and 13 appear", + .expectedString = "Hxxxx xxxx xxxx xxxx xxxx 42 xxxx 13 xxxx", + .expectedCount = 7 + ); + + test( .regex = "((V(I|1)(4|A)GR(4|A))|(V(I|1)C(0|O)D(I|1)(N|\/\\\/)))", .regexFlags = PCRE_CASELESS, + .replace = "...", + .string = "Viagra V14GR4 Vicodin V1C0D1/\/ v1c0d1/|/", + .expectedString = "... ... ... ... v1c0d1/|/", + .expectedCount = 4 + ); + + test( .regex = "\[(right)\](((?R)|[^^[]+?|\[)*)\[/\\1\]", .regexFlags = PCRE_CASELESS | PCRE_UNGREEDY, + .replace = "", + .string = "[CODE]<td align="$stylevar[right]">[/CODE]", + .expectedString = "[CODE]<td align="$stylevar[right]">[/CODE]", + .expectedCount = 0 + ); + + test( .regex = "- This is a string$", + .replace = "This shouldn\'t work", + .string = "123456789 - Hello, world - This is a string.", + .expectedString = "123456789 - Hello, world - This is a string.", + .expectedCount = 0 + ); + + test( .regex = "[0-35-9]", + .replace = "4", + .string = "123456789 - Hello, world - This is a string.", + .expectedString = "444444444 - Hello, world - This is a string.", + .expectedCount = 8 + ); + + test( .regex = "\b[hH]\w{2,4}", + .replace = "Bonjour", + .string = "123456789 - Hello, world - This is a string.", + .expectedString = "123456789 - Bonjour, world - This is a string.", + .expectedCount = 1 + ); + + test( .regex = "(\w)\s*-\s*(\w)", + .replace = "$1. $2", + .string = "123456789 - Hello, world - This is a string.", + .expectedString = "123456789. Hello, world. This is a string.", + .expectedCount = 2 + ); + + test( .regex = "([a-z]\w+)@(\w+)\.(\w+)\.([a-z]{2,})", + .replace = "$1 at $2 dot $3 dot $4", + .string = "josmessa@uk.ibm.com", + .expectedString = "josmessa at uk dot ibm dot com", + .expectedCount = 1 + ); + + test( .regex = "\b\w{1}s", + .replace = "test", + .string = "This is a string. (0-9) as well as parentheses", + .expectedString = "This test a string. (0-9) test well test parentheses", + .expectedCount = 3 + ); + + + test( .regex = "(\d{1})-(\d{1})", + .replace = "$1 to $2", + .string = "This is a string. It contains numbers (0-9) as well as parentheses and some other things!", + .expectedString = "This is a string. It contains numbers (0 to 9) as well as parentheses and some other things!", + .expectedCount = 1 + ); + + test( .regex = "[\(!\)]", + .replace = "*", + .string = "This is a string. It contains numbers (0-9) as well as parentheses and some other things!", + .expectedString = "This is a string. It contains numbers *0-9* as well as parentheses and some other things*", + .expectedCount = 3 + ); + } + + server_print("^tChecking edges cases..."); + { + test(.regex = "[0-9]+", .replace = "*", .string = "", .expectedString = "", .expectedCount = 0); + test(.regex = "([0-9]+)", .replace = "", .string = "123", .expectedString = "", .expectedCount = 1); + test(.regex = "a", .replace = "\", .string = "a", .expectedString = "\", .expectedCount = 1); + test(.regex = "^^", .replace = "x", .string = "a", .expectedString = "xa", .expectedCount = 1); + test(.regex = "b", .replace = "\", .string = "b", .expectedString = "\", .expectedCount = 1, .bufferlen = 1); + test(.regex = "b", .replace = "^^", .string = "b", .expectedString = "b", .expectedCount = 0, .bufferlen = 0); + test(.regex = "\w+", .replace = "123", .string = "abc", .expectedString = "12", .expectedCount = 1, .bufferlen = 2); + } + + server_print("^tChecking UTF-8 support..."); + { + test(.regex = "(\w+)", .replace = "*", .string = "éà@É", .expectedString = "éà@É", .expectedCount = 0); + test(.regex = "(\w+)", .replace = "*", .string = "éà@É", .expectedString = "*@*", .expectedCount = 2, .regexFlags = PCRE_UCP | PCRE_UTF8); + test(.regex = "(\w+)", .replace = "字", .string = "éà@É", .expectedString = "字@字",.expectedCount = 2, .regexFlags = PCRE_UCP | PCRE_UTF8); + test(.regex = "(\w+)", .replace = "字", .string = "éà@É", .expectedString = "字", .expectedCount = 2, .regexFlags = PCRE_UCP | PCRE_UTF8, .bufferlen = 3); + } + + server_print("^tChecking substitutions..."); + { + test(.regex = "x", .replace = "y", .string = "text", .expectedString = "teyt" ); + test(.regex = "x", .replace = "$", .string = "text", .expectedString = "te$t" ); + test(.regex = "x", .replace = "$1", .string = "text", .expectedString = "te$1t" ); + test(.regex = "x", .replace = "${1", .string = "text", .expectedString = "te${1t" ); + test(.regex = "x", .replace = "${", .string = "text", .expectedString = "te${t" ); + test(.regex = "x", .replace = "${$0", .string = "text", .expectedString = "te${xt" ); + test(.regex = "x", .replace = "${1}", .string = "text", .expectedString = "te${1}t" ); + test(.regex = "x", .replace = "${1}", .string = "text", .expectedString = "te${1}t" ); + test(.regex = "x", .replace = "$5", .string = "text", .expectedString = "te$5t" ); + test(.regex = "x", .replace = "$5", .string = "te(x)t", .expectedString = "te($5)t" ); + test(.regex = "x", .replace = "${foo", .string = "text", .expectedString = "te${foot" ); + test(.regex = "(x)", .replace = "$5", .string = "text", .expectedString = "te$5t" ); + test(.regex = "(x)", .replace = "$1", .string = "text", .expectedString = "text" ); + test(.regex = "e(x)", .replace = "$1", .string = "text", .expectedString = "txt" ); + test(.regex = "e(x)", .replace = "$5", .string = "text", .expectedString = "t$5t" ); + test(.regex = "e(x)", .replace = "$4", .string = "text", .expectedString = "t$4t" ); + test(.regex = "e(x)", .replace = "$3", .string = "text", .expectedString = "t$3t" ); + test(.regex = "e(x)", .replace = "${1}", .string = "text", .expectedString = "txt" ); + test(.regex = "e(x)", .replace = "${3}", .string = "text", .expectedString = "t${3}t" ); + test(.regex = "e(x)", .replace = "${1}${3}", .string = "text", .expectedString = "tx${3}t" ); + test(.regex = "e(x)", .replace = "${1}${name}", .string = "text", .expectedString = "tx${name}t"); + test(.regex = "e(?x)", .replace = "${1}${name}", .string = "text", .expectedString = "tx${name}t"); + test(.regex = "e(?x)", .replace = "${1}${foo}", .string = "text", .expectedString = "txxt" ); + test(.regex = "e(?x)", .replace = "${goll}${foo}", .string = "text", .expectedString = "t${goll}xt"); + test(.regex = "e(?x)", .replace = "${goll${foo}", .string = "text", .expectedString = "t${gollxt" ); + test(.regex = "e(?x)", .replace = "${goll${foo}}", .string = "text", .expectedString = "t${gollx}t"); + test(.regex = "e(?x)", .replace = "$${foo}}", .string = "text", .expectedString = "t${foo}}t" ); + test(.regex = "e(?x)", .replace = "${${foo}}", .string = "text", .expectedString = "t${x}t" ); + test(.regex = "e(?x)", .replace = "$${foo}}", .string = "text", .expectedString = "t${foo}}t" ); + test(.regex = "e(?x)", .replace = "$${bfoo}}", .string = "text", .expectedString = "t${bfoo}}t"); + test(.regex = "e(?x)", .replace = "$${foo}}", .string = "text", .expectedString = "t${foo}}t" ); + test(.regex = "e(?x)", .replace = "$${foo}", .string = "text", .expectedString = "t${foo}t" ); + test(.regex = "e(?x)", .replace = "$$", .string = "text", .expectedString = "t$t" ); + test(.regex = "(e)(?x)", .replace = "${foo}$1$2", .string = "text", .expectedString = "txext" ); + test(.regex = "(?e)(x)", .replace = "${foo}$1$2", .string = "text", .expectedString = "teext" ); + test(.regex = "(e)(?x)", .replace = "${foo}$1$2$+", .string = "text", .expectedString = "txexxt" ); + test(.regex = "(?e)(x)", .replace = "${foo}$1$2$+", .string = "text", .expectedString = "teexxt" ); + test(.regex = "(?e)(x)", .replace = "${foo}$1$2$_", .string = "texts", .expectedString = "teextextsts"); + test(.regex = "(?e)(x)", .replace = "${foo}$1$2$`", .string = "texts", .expectedString = "teextts" ), + test(.regex = "(?e)(x)", .replace = "${foo}$1$2$'", .string = "texts", .expectedString = "teextsts" ), + test(.regex = "(?e)(x)", .replace = "${foo}$1$2$&", .string = "texts", .expectedString = "teexexts" ), + test(.regex = "x", .replace = "y", .string = "text", .expectedString = "teyt" ); + test(.regex = "x", .replace = "$", .string = "text", .expectedString = "te$t" ); + test(.regex = "x", .replace = "$1", .string = "text", .expectedString = "te$1t" ); + test(.regex = "x", .replace = "${1}", .string = "text", .expectedString = "te${1}t" ); + test(.regex = "x", .replace = "$5", .string = "text", .expectedString = "te$5t" ); + test(.regex = "x", .replace = "$5", .string = "te(x)t", .expectedString = "te($5)t" ); + test(.regex = "x", .replace = "${foo", .string = "text", .expectedString = "te${foot" ); + test(.regex = "(x)", .replace = "$5", .string = "text", .expectedString = "te$5t" ); + test(.regex = "(x)", .replace = "$1", .string = "text", .expectedString = "text" ); + test(.regex = "e(x)", .replace = "$1", .string = "text", .expectedString = "txt" ); + test(.regex = "e(x)", .replace = "$5", .string = "text", .expectedString = "t$5t" ); + test(.regex = "e(x)", .replace = "$4", .string = "text", .expectedString = "t$4t" ); + test(.regex = "e(x)", .replace = "$3", .string = "text", .expectedString = "t$3t" ); + test(.regex = "e(x)", .replace = "${1}", .string = "text", .expectedString = "txt" ); + test(.regex = "e(x)", .replace = "${3}", .string = "text", .expectedString = "t${3}t" ); + test(.regex = "e(x)", .replace = "${1}${3}", .string = "text", .expectedString = "tx${3}t" ); + test(.regex = "e(x)", .replace = "${1}${name}", .string = "text", .expectedString = "tx${name}t"); + test(.regex = "e(?x)", .replace = "${1}${name}", .string = "text", .expectedString = "tx${name}t"); + test(.regex = "e(?x)", .replace = "${1}${foo}", .string = "text", .expectedString = "txxt" ); + test(.regex = "e(?x)", .replace = "${goll}${foo}", .string = "text", .expectedString = "t${goll}xt"); + test(.regex = "e(?x)", .replace = "${goll${foo}", .string = "text", .expectedString = "t${gollxt" ); + test(.regex = "e(?x)", .replace = "${goll${foo}}", .string = "text", .expectedString = "t${gollx}t"); + test(.regex = "e(?x)", .replace = "$${foo}}", .string = "text", .expectedString = "t${foo}}t" ); + test(.regex = "e(?x)", .replace = "${${foo}}", .string = "text", .expectedString = "t${x}t" ); + test(.regex = "e(?x)", .replace = "$${foo}}", .string = "text", .expectedString = "t${foo}}t" ); + test(.regex = "e(?x)", .replace = "$${bfoo}}", .string = "text", .expectedString = "t${bfoo}}t"); + test(.regex = "e(?x)", .replace = "$${foo}}", .string = "text", .expectedString = "t${foo}}t" ); + test(.regex = "e(?x)", .replace = "$${foo}", .string = "text", .expectedString = "t${foo}t" ); + test(.regex = "e(?x)", .replace = "$$", .string = "text", .expectedString = "t$t" ); + test(.regex = "(e)(?x)", .replace = "${foo}$1$2", .string = "text", .expectedString = "txext" ); + test(.regex = "(?e)(x)", .replace = "${foo}$1$2", .string = "text", .expectedString = "teext" ); + test(.regex = "(e)(?x)", .replace = "${foo}$1$2$+", .string = "text", .expectedString = "txexxt" ); + test(.regex = "(?e)(x)", .replace = "${foo}$1$2$+", .string = "text", .expectedString = "teexxt" ); + test(.regex = "(?e)(x)", .replace = "${foo}$1$2$_", .string = "texts", .expectedString = "teextextsts"); + test(.regex = "(?e)(x)", .replace = "${foo}$1$2$`", .string = "texts", .expectedString = "teextts" ); + test(.regex = "(?e)(x)", .replace = "${foo}$1$2$'", .string = "texts", .expectedString = "teextsts" ); + test(.regex = "(?e)(x)", .replace = "${foo}$1$2$&", .string = "texts", .expectedString = "teexexts" ); + test(.regex = "<(.+?)>", .replace = "[$0:$1]", .string = "am not", .expectedString = "[:i]am not[:/i]"); + test(.regex = "(?e)(?x)", .replace = "${foo}$1$2", .string = "text", .expectedString = "teext", .regexFlags = PCRE_DUPNAMES); + test(.regex = "\b(\w+)(\s)(\w+)\b", .replace = "$3$2$1", .string = "one two", .expectedString = "two one"); + test(.regex = "\b(\d+)\s?USD", .replace = "$$$1", .string = "103 USD", .expectedString = "$103" ); + test(.regex = "\b(?\w+)(\s)(?\w+)\b", .replace = "${w2} ${w1}", .string = "one two", .expectedString = "two one"); + test(.regex = "(\$*(\d*(\.+\d+)?){1})", .replace = "**$&", .string = "$1.30", .expectedString = "**$1.30**"); + test(.regex = "B+", .replace = "$`", .string = "AABBCC", .expectedString = "AAAACC"); + test(.regex = "B+", .replace = "$'", .string = "AABBCC", .expectedString = "AACCCC"); + test(.regex = "B+(C+)", .replace = "$+", .string = "AABBCCDD", .expectedString = "AACCDD"); + test(.regex = "B+", .replace = "$_", .string = "AABBCC", .expectedString = "AAAABBCCCC"); + test(.regex = "(F)(2)(3)(4)(5)(6)(7)(8)(9)(10)(L)\11", .replace = "${S}$11$1", .string = "F2345678910L71", .expectedString = "F2345678910L71"), + test(.regex = "(F)(2)(3)(4)(5)(6)(7)(8)(9)(10)(L)\11", .replace = "${S}$11$1", .string = "F2345678910LL1", .expectedString = "${S}LF1"); + } + + server_print("^tChecking moar #1..."); + { + test(.string = "(?(w)a|o)" , .regex = "\(\?\(\w+\).*\|?.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?(w)|o)" , .regex = "\(\?\(\w+\).*\|?.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?(w)a)" , .regex = "\(\?\(\w+\).*\|?.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?(w)a|)" , .regex = "\(\?\(\w+\).*\|?.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?(w)?|a|o)" , .regex = "\(\?\(\w+\).*\|?.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?(w)||o)" , .regex = "\(\?\(\w+\).*\|?.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?(w)(a)" , .regex = "\(\?\(\w+\).*\|?.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?(w))\a|)" , .regex = "\(\?\(\w+\).*\|?.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?(2)a|o)" , .regex = "\(\?\([^^\)]+\).*\|?.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?(|)a|o)" , .regex = "\(\?\([^^\)]+\).*\|?.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "a\3b" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\(\d+)" , .replace = "\5", .expectedString = "a\5b"); + test(.string = "\3b" , .regex = "(?=(?:\A|[^^\\])(?:[\\]{2}){0,3})\\(\d+)" , .replace = "\5", .expectedString = "\5b"); + test(.string = "\\\3b" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\(\d+)" , .replace = "\5", .expectedString = "\\\5b"); + test(.string = "\\\k" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\k<(\w+)>" , .replace = "\5", .expectedString = "\\\5"); + test(.string = "\\\\k'g'" , .regex = "(?:(?:\A|[^^\\])(?:[\\]{2}){0,3})\\k'(\w+)'" , .replace = "\5", .expectedString = "\\\\k'g'"); + test(.string = "a\\\\k'g'" , .regex = "(?:(?:\A|[^^\\])(?:[\\]{2}){0,3})\\k'(\w+)'" , .replace = "\5", .expectedString = "a\\\\k'g'"); + test(.string = "\k'g'" , .regex = "(?:(?:\A|[^^\\])(?:[\\]{2}){0,3})\\k'(\w+)'" , .replace = "\5", .expectedString = "\5"); + test(.string = "(?)" , .regex = "\(\?<[A-Za-z]\w*-[A-Za-z]\w*>.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?'n1-n2'a)" , .regex = "\(\?'[A-Za-z]\w*-[A-Za-z]\w*'.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "\p{Isa}" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\\[pP]\{)Is(?=\w+\})", .replace = "In", .expectedString = "\p{Ina}"); + test(.string = "\p{Is}" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\\[pP]\{)Is(?=\w+\})", .replace = "In", .expectedString = "\p{Is}"); + test(.string = "\p{Isa" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\\[pP]\{)Is(?=\w+\})", .replace = "In", .expectedString = "\p{Isa"); + test(.string = "a(?#|)" , .regex = "\(\?#[^^\)]*\)" , .replace = "", .expectedString = "a"); + test(.string = "(?#|)" , .regex = "\(\?#[^^\)]*\)" , .replace = "", .expectedString = ""); + test(.string = "(?#|)" , .regex = "\#[^^\n\r]*" , .replace = "", .expectedString = "(?"); + test(.string = "(?inm-xs:\#)" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\()\?[imsx]*n[-imsx]*:[^^\)]+\)", .replace = "r", .expectedString = "(r"); + test(.string = "(?ni:())" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\()\?[imsx]*n[-imsx]*:[^^\)]+\)", .replace = "r", .expectedString = "(r)"); + test(.string = "(?x-i:)" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\()\?[imsx]*n[-imsx]*:[^^\)]+\)", .replace = "r", .expectedString = "(?x-i:)"); + test(.string = "(?n:))" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\()\?[imsx]*n[-imsx]*:[^^\)]+\)", .replace = "r", .expectedString = "(?n:))"); + test(.string = "(?)" , .regex = "\(\?<[A-Za-z]\w*>.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?'n1'y)" , .regex = "\(\?'[A-Za-z]\w*'.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?<45>y)" , .regex = "\(\?<\d+>.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "(?'7'o)" , .regex = "\(\?'\d+'.*\)" , .replace = "r", .expectedString = "r"); + test(.string = "\\\(" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\\(" , .replace = "r", .expectedString = "\\r"); + test(.string = "a\\\(" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\\(" , .replace = "r", .expectedString = "a\\r"); + test(.string = "\\(" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\\(" , .replace = "r", .expectedString = "\r"); + test(.string = "a\\(" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\\(" , .replace = "r", .expectedString = "a\r"); + test(.string = "\(" , .regex = "(?:(?:\A|[^^\\])(?:[\\]{2}){0,3})\\\(" , .replace = "r", .expectedString = "r"); + test(.string = "a\(" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\\(" , .replace = "r", .expectedString = "ar"); + test(.string = "?:" , .regex = "(?:^^\?[:imnsx=!>-]|^^\?<[!=])" , .replace = "r", .expectedString = "r"); + test(.string = "?-]|^^\?<[!=])" , .replace = "r", .expectedString = "r"); + test(.string = "?-" , .regex = "(?:^^\?[:imnsx=!>-]|^^\?<[!=])" , .replace = "r", .expectedString = "r"); + test(.string = "\(?" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\()\?<[A-Za-z]\w*>", .replace = "r", .expectedString = "\(r"); + test(.string = "a\(?'n'" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\()\?'[A-Za-z]\w*'", .replace = "r", .expectedString = "a\(r"); + test(.string = "\\(?<2>" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\()\?<\d+>" , .replace = "r", .expectedString = "\\(r"); + test(.string = "(?'2'" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3}\()\?'\d+'" , .replace = "r", .expectedString = "(r"); + test(.string = "\[\b]" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2})*(?:\[|\[[^^\[\]]*[^^\[\]\\])(?:[\\]{2})*)\\b(?=[^^\[\]]*\])", .replace = "\\u8", .expectedString = "\[\u8]"); + test(.string = "\[a\bb]" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2})*(?:\[|\[[^^\[\]]*[^^\[\]\\])(?:[\\]{2})*)\\b(?=[^^\[\]]*\])", .replace = "\\u8", .expectedString = "\[a\u8b]"); + test(.string = "\[\b]" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2})*(?:\[|\[[^^\[\]]*[^^\[\]\\])(?:[\\]{2})*)\\b(?=[^^\[\]]*\])", .replace = "\\u8", .expectedString = "\[\u8]"); + test(.string = "\[\b]" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2})*(?:\[|\[[^^\[\]]*[^^\[\]\\])(?:[\\]{2})*)\\b(?=[^^\[\]]*\])", .replace = "\\u8", .expectedString = "\[\u8]"); + test(.string = "\[\\b]" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2})*(?:\[|\[[^^\[\]]*[^^\[\]\\])(?:[\\]{2})*)\\b(?=[^^\[\]]*\])", .replace = "\\u8", .expectedString = "\[\\u8]"); + test(.string = "[[]" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2})*(?:\[|\[[^^\[\]]*[^^\[\]\\])(?:[\\]{2})*)\[(?=[^^\[\]]*\])" , .replace = "\\[" , .expectedString = "[\[]"); + test(.string = "\[[]" , .regex = "(?:(?:\A|[^^\\])(?:[\\]{2})*(?:\[|\[[^^\[\]]*[^^\[\]\\])(?:[\\]{2})*)\[(?=[^^\[\]]*\])" , .replace = "\[" , .expectedString = "\[[]"); + test(.string = "\[\[]" , .regex = "(?:(?:\A|[^^\\])(?:[\\]{2})*(?:\[|\[[^^\[\]]*[^^\[\]\\])(?:[\\]{2})*)\[(?=[^^\[\]]*\])" , .replace = "\[" , .expectedString = "\[\[]"); + test(.string = "\[\[]" , .regex = "(?:(?:\A|[^^\\])(?:[\\]{2})*(?:\[|\[[^^\[\]]*[^^\[\]\\])(?:[\\]{2})*)\[(?=[^^\[\]]*\])" , .replace = "\[" , .expectedString = "\[\[]"); + test(.string = "\{" , .regex = "(?=(?:\A|[^^\\])(?:[\\]{2})*)\{(?!\d\d*(,(\d\d*)?)?\})", .replace = "\{", .expectedString = "\\{"); + test(.string = "\{" , .regex = "(?=(?:\A|[^^\\])(?:[\\]{2})*)\{(?!\d\d*(,(\d\d*)?)?\})", .replace = "\{", .expectedString = "\\{"); + test(.string = "\{1,2}" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2})*)\{(?!\d\d*(,(\d\d*)?)?\})", .replace = "\{", .expectedString = "\{1,2}"); + test(.string = "\{1}" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2})*)\{(?!\d\d*(,(\d\d*)?)?\})", .replace = "\{", .expectedString = "\{1}"); + test(.string = "\{1,}" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2})*)\{(?!\d\d*(,(\d\d*)?)?\})", .replace = "\{", .expectedString = "\{1,}"); + test(.string = "\{1" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2})*)\{(?!\d\d*(,(\d\d*)?)?\})", .replace = "\\{", .expectedString = "\{1"); + test(.string = "\\(?!{1}" , .regex = "(\A|((\A|[^^\\])([\\]{2})*\((\?([:>=!]|<([=!]|(\w+>))))?))\{\d+(,(\d+)?)?\}", .replace = "\5", .expectedString = "?!"); + test(.string = "{1}" , .regex = "(\A|((\A|[^^\\])([\\]{2})*\((\?([:>=!]|<([=!]|(\w+>))))?))\{\d+(,(\d+)?)?\}", .replace = "r", .expectedString = "r"); + test(.string = "({1}" , .regex = "(\A|((\A|[^^\\])([\\]{2})*\((\?([:>=!]|<([=!]|(\w+>))))?))\{\d+(,(\d+)?)?\}", .replace = "r", .expectedString = "r"); + test(.string = "(?{1}" , .regex = "(\A|((\A|[^^\\])([\\]{2})*\((\?([:>=!]|<([=!]|(\w+>))))?))\{\d+(,(\d+)?)?\}", .replace = "r", .expectedString = "(?{1}"); + test(.string = "(?:{1}" , .regex = "(\A|((\A|[^^\\])([\\]{2})*\((\?([:>=!]|<([=!]|(\w+>))))?))\{\d+(,(\d+)?)?\}", .replace = "r", .expectedString = "r"); + test(.string = "\({1}" , .regex = "(\A|((\A|[^^\\])([\\]{2})*\((\?([:>=!]|<([=!]|(\w+>))))?))\{\d+(,(\d+)?)?\}", .replace = "r", .expectedString = "\({1}"); + test(.string = "\p{Isa}" , .regex = "(?!\\[pP]\{)Is(?=\w+\})" , .replace = "In", .expectedString = "\p{Ina}"); + test(.string = "\p{Is}" , .regex = "(?!\\[pP]\{)Is(?=\w+\})" , .replace = "In", .expectedString = "\p{Is}"); + test(.string = "\p{Isa" , .regex = "(?!\\[pP]\{)Is(?=\w+\})" , .replace = "In", .expectedString = "\p{Isa"); + test(.string = "\}" , .regex = "(?!(\\A|[^^\\])(\\{2})*\\{\\d\\d*(,(\\d\\d*)?)?)\\}", .replace = "\\}", .expectedString = "\}"); + test(.string = "{\}" , .regex = "(?!(\A|[^^\^^])(\^^{2})*\{\d\d*(,(\d\d*)?)?)\}", .replace = "\\}", .expectedString = "{\\}"); + test(.string = "{1,2}" , .regex = "(?!(\A|[^^\\])(\\{2})*\{\d\d*(,(\d\d*)?)?)\}" , .replace = "\\}", .expectedString = "{1,2\}"); + test(.string = "\{1}" , .regex = "(?!(\A|[^^\\])(\\{2})*\{\d\d*(,(\d\d*)?)?)\}" , .replace = "\\}", .expectedString = "\{1\}"); + test(.string = "\{1\}" , .regex = "(?!(\A|[^^\\])(\\{2})*\{\d\d*(,(\d\d*)?)?)\}" , .replace = "\\}", .expectedString = "\{1\\}"); + test(.string = "\{1}" , .regex = "(?!(\A|[^^\\])(\\{2})*\{\d\d*(,(\d\d*)?)?)\}" , .replace = "\\}", .expectedString = "\{1\}"); + test(.string = "{1,}" , .regex = "(?!(\A|[^^\\])(\\{2})*\{\d\d*(,(\d\d*)?)?)\}" , .replace = "\\}", .expectedString = "{1,\}"); + test(.string = "a(?" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\k<(\w)>" , .replace = "\5", .expectedString = "\\5"); + test(.string = "a\\k" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\k<(\w)>" , .replace = "\5", .expectedString = "a\\5"); + test(.string = "\\k'g'" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\k'(\w)'" , .replace = "\5", .expectedString = "\\5"); + test(.string = "a\\k'g'" , .regex = "(?!(?:\A|[^^\\])(?:[\\]{2}){0,3})\\k'(\w)'" , .replace = "\5", .expectedString = "a\\5"); + test(.string = "\k'g'" , .regex = "(?:(?:\A|[^^\\])(?:[\\]{2}){0,3})\\k'(\w)'" , .replace = "\5", .expectedString = "\5"); + } + + server_print("^tChecking moar #2..."); + { + test(.regex = "^^((?>[a-zA-Z\d!#$%&'*+\-\/=?^^_`{|}~]+\x20*|^"((?=[\x01-\x7f])[^^^"\\]|\\[\x01-\x7f])*^"\x20*)*(?<))?((?!\.)(?>\.?[a-zA-Z\d!#$%&'*+\-\/=?^^_`{|}~]+)+|^"((?=[\x01-\x7f])[^^^"\\]|\\[\x01-\x7f])*^")@(((?!-)[a-zA-Z\d\-]+(?)$" , + .replace = "$1$4@$7net>", + .string = "Name Surname ", + .expectedString = "Name Surname " + ); + + test(.regex = "([A-Z])\w+", + .replace = "*snip*", + .string = "Welcome to RegExr v2.0 by gskinner.com!\ + \ + Edit the Expression & Text to see matches. Roll over matches or the expression for details. Undo mistakes with ctrl-z. Save & Share expressions with friends or the Community. A full Reference & Help is available in the Library, or watch the video Tutorial.\ + \ + Sample text for testing:\ + abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ\ + :0123456789 +-.,!@#$%^^&*();\/|<>^"'\ + 12345 -98.7 3.141 .6180 9,000 +42\ + 555.123.4567 +1-(800)-555-2468\ + foo@demo.net bar.ba@test.co.uk\ + www.demo.com http://foo.co.uk/\ + http://regexr.com/foo.html?q=bar", + + .expectedString = "*snip* to *snip* v2.0 by gskinner.com!\ + \ + *snip* the *snip* & *snip* to see matches. *snip* over matches or the expression for details. *snip* mistakes with ctrl-z. *snip* & *snip* expressions with friends or the *snip*. A full *snip* & *snip* is available in the *snip*, or watch the video *snip*.\ + \ + *snip* text for testing:\ + abcdefghijklmnopqrstuvwxyz *snip*\ + :0123456789 +-.,!@#$%^^&*();\/|<>^"'\ + 12345 -98.7 3.141 .6180 9,000 +42\ + 555.123.4567 +1-(800)-555-2468\ + foo@demo.net bar.ba@test.co.uk\ + www.de", + .regexFlags = PCRE_EXTENDED + ); + + test(.regex = "/\*(?>[^^*/]+|\*[^^/]|/[^^*]|/\*(?>[^^*/]+|\*[^^/]|/[^^*])*\*/)*\*/", + .replace = "", + .string = "/* comment */\ + no comment\ + /* comment\ + spanning\ + multiple\ + lines */\ + /* comment /* nesting */ of /* two */ levels supported */\ + /* comment /* nesting */ of /* /* more than */ two levels */ not supported */", + .expectedString = "no comment\ + /* comment of not supported */" + ); + + test(.regex = "\b(?https?|ftp)://(?[A-Z0-9.-]+)(?/[A-Z0-9+&@#/%=~_|!:,.;-]*)?(?\?[A-Z0-9+&@#/%=~_|!:,.;]*)?", + .replace = "${protocol}s://site.com${file}^n", + .string = "http://www.alliedmods.net http://www.alliedmods.net/ http://www.alliedmods.net/test.php http://www.alliedmods.net/index.php?secret=x Something interesting at http://www.alliedmods.net.", + .expectedString = "https://site.com^nhttps://site.com/^nhttps://site.com/test.php^nhttps://site.com/index.php^nhttps://site.com^n", + .regexFlags = PCRE_CASELESS | PCRE_EXTENDED, + .formatFlags = REGEX_FORMAT_NOCOPY + ); + + test(.regex = "\b(https?|ftp)://([A-Z0-9.-]+)(/[A-Z0-9+&@#/%=~_|!:,.;-]*)?(\?[A-Z0-9+&@#/%=~_|!:,.;]*)?", + .replace = "$1s://site.com$3^n", + .string = "http://www.alliedmods.net http://www.alliedmods.net/ http://www.alliedmods.net/test.php http://www.alliedmods.net/index.php?secret=x Something interesting at http://www.alliedmods.net.", + .expectedString = "https://site.com^nhttps://site.com/^nhttps://site.com/test.php^nhttps://site.com/index.php^nhttps://site.com^n", + .regexFlags = PCRE_CASELESS | PCRE_EXTENDED, + .formatFlags = REGEX_FORMAT_NOCOPY + ); + + test(.regex = "\b(https?|ftp)://([A-Z0-9.-]+)(/[A-Z0-9+&@#/%=~_|!:,.;-]*)?(\?[A-Z0-9+&@#/%=~_|!:,.;]*)?", + .replace = "$1s://site.com$3^n", + .string = "http://www.alliedmods.net http://www.alliedmods.net/ http://www.alliedmods.net/test.php http://www.alliedmods.net/index.php?secret=x Something interesting at http://www.alliedmods.net.", + .expectedString = "https://site.com^n", + .regexFlags = PCRE_CASELESS | PCRE_EXTENDED, + .formatFlags = REGEX_FORMAT_NOCOPY | REGEX_FORMAT_FIRSTONLY + ); + + test(.regex = "^^(.++)\r?\n(?=(?:^^(?!\1$).*+\r?\n)*+\1$)", + .replace = "", + .string = "one^n\ + two^n\ + three^n\ + four^n\ + two^n\ + three^n\ + four^n\ + three^n\ + four^n\ + four", + .expectedString = "one^n\ + two^n\ + three^n\ + four", + .regexFlags = PCRE_EXTENDED | PCRE_MULTILINE + ); + } + + end(); +} \ No newline at end of file diff --git a/support/PackageScript b/support/PackageScript index 265ad942..ff5fd354 100644 --- a/support/PackageScript +++ b/support/PackageScript @@ -225,6 +225,7 @@ scripting_files = [ 'testsuite/menutest.sma', 'testsuite/native_test.sma', 'testsuite/nvault_test.sma', + 'testsuite/regex_test.sma', 'testsuite/sorttest.sma', 'testsuite/strbreak.sma', 'testsuite/sqlxtest.sma', From 9c84c17d5ead5a1c6fdedf29afbafa93c767c3c1 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Thu, 17 Jul 2014 14:02:21 +0200 Subject: [PATCH 12/18] Regex: Update regex_subtr (Increase buffer and make it UTF-8 safe) --- dlls/regex/module.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/dlls/regex/module.cpp b/dlls/regex/module.cpp index 70fbe8b1..78182c97 100755 --- a/dlls/regex/module.cpp +++ b/dlls/regex/module.cpp @@ -34,7 +34,9 @@ #include "pcre.h" #include "amxxmodule.h" #include +#include #include "CRegEx.h" +#include "utils.h" ke::Vector PEL; @@ -243,15 +245,24 @@ static cell AMX_NATIVE_CALL regex_substr(AMX *amx, cell *params) } RegEx *x = PEL[id]; - //good idea? probably not. - static char buffer[4096]; + static char buffer[16384]; // Same as AMXX buffer. - const char *ret = x->GetSubstring(params[2], buffer, 4095); + size_t length; + size_t maxLength = ke::Min(params[4], sizeof(buffer) - 1); + + const char *ret = x->GetSubstring(params[2], buffer, maxLength, &length); if (ret == NULL) + { return 0; + } - MF_SetAmxString(amx, params[3], ret, params[4]); + if (length >= maxLength && ret[length - 1] & 1 << 7) + { + maxLength -= UTIL_CheckValidChar((char *)ret + length - 1); + } + + MF_SetAmxString(amx, params[3], ret, maxLength); return 1; } From 62e4eb29eb882d290bf827342403727fe1c77e08 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Thu, 17 Jul 2014 14:58:57 +0200 Subject: [PATCH 13/18] Regex: Update documentation. --- plugins/include/regex.inc | 44 ++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/plugins/include/regex.inc b/plugins/include/regex.inc index 1f22a722..d454cabc 100755 --- a/plugins/include/regex.inc +++ b/plugins/include/regex.inc @@ -64,9 +64,14 @@ enum Regex #define PCRE_NOTEMPTY 0x00000400 /* An empty string is not a valid match. */ #define PCRE_UTF8 0x00000800 /* Use UTF-8 Chars */ #define PCRE_NO_UTF8_CHECK 0x00002000 /* Do not check the pattern for UTF-8 validity (only relevant if PCRE_UTF8 is set) */ +#define PCRE_NEVER_UTF 0x00010000 /* Lock out interpretation of the pattern as UTF-8 */ #define PCRE_FIRSTLINE 0x00040000 /* Force matching to be before newline */ #define PCRE_DUPNAMES 0x00080000 /* Allow duplicate names for subpattern */ -#define PCRE_UCP 0x20000000 /* Use Unicode properties for \ed, \ew, etc. */ +#define PCRE_NEWLINE_CR 0x00100000 /* Specify that a newline is indicated by a single character CR ) */ +#define PCRE_NEWLINE_CRLF 0x00300000 /* specify that a newline is indicated by the two-character CRLF sequence ) Overrides the default */ +#define PCRE_NEWLINE_ANY 0x00400000 /* Specify that any Unicode newline sequence should be recognized. ) newline definition (LF) */ +#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Specify that any of CR, LF and CRLF sequences should be recognized ) */ +#define PCRE_UCP 0x20000000 /* Change the way PCRE processes \B, \b, \D, \d, \S, \s, \W, \w etc. to use Unicode properties */ /** * Regex expression error codes. @@ -120,6 +125,8 @@ enum /*RegexError*/ * if you are completely done with it before then, you should * call regex_free on this handle. * + * @note Consider to use regex_compilex_ex instead if you want to use PCRE_* flags. + * * @param pattern The regular expression pattern. * @param ret Error code encountered, if applicable. * @param error Error message encountered, if applicable. @@ -149,7 +156,7 @@ native Regex:regex_compile(const pattern[], &ret = 0, error[] = "", maxLen = 0, * @param string The string to check. * @param pattern The regular expression pattern. * @param ret Error code, if applicable, or number of results on success. See REGEX_ERROR_* defines. - * + * * @return -2 = Matching error (error code is stored in ret) * 0 = No match. * >1 = Number of results. @@ -193,7 +200,7 @@ native Regex:regex_match(const string[], const pattern[], &ret = 0, error[] = "" * Returns a matched substring from a regex handle. * * @note Substring ids start at 0 and end at ret - 1, where ret is from the corresponding - * regex_match, regex_match_c or regex_match_ex function call. + * regex_match* function call. * * @param id The regex handle to extract data from. * @param str_id The index of the expression to get - starts at 0, and ends at ret - 1. @@ -210,7 +217,7 @@ native regex_substr(Regex:id, str_id, buffer[], maxLen); * @note This must be called on all results from regex_match() when you are done extracting * the results with regex_substr(). * - * @note The results of regex_compile() or regex_compile_ex() (and subsequently, regex_match_c() or regex_match_ex()) + * @note The results of regex_compile() or regex_compile_ex() (and subsequently, regex_match_c()) * only need to be freed when you are done using the pattern. * * @note Do not use the handle again after freeing it! @@ -229,7 +236,7 @@ native regex_free(&Regex:id); * Precompile a regular expression. * * @note Use this if you intend on using the ame expression multiple times. - * Pass the regex handle returned here to regex_match_ex() to check for matches. + * Pass the regex handle returned here to regex_match_c() to check for matches. * * @note Unlike regex_compile(), this allows you to use directly PCRE flags. * @@ -244,25 +251,24 @@ native regex_free(&Regex:id); native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = 0, &errcode = 0); /** - * Matches a string against a pre-compiled regular expression pattern, matching all - * occurances of the pattern inside the string. This is similar to using the "g" flag + * Matches a string against a pre-compiled regular expression pattern, matching all + * occurances of the pattern inside the string. This is similar to using the "g" flag * in perl regex. * + * @note You should free the returned handle (with regex_free()) + * when you are done with this pattern. + * + * @note Use the regex handle passed to this function to extract + * matches with regex_substr(). * * @param pattern The regular expression pattern. * @param string The string to check. - * @param ret Error code, if applicable, or number of results on success. + * @param ret Error code, if applicable, or number of results on success. * See REGEX_ERROR_* defines. * * @return -2 = Matching error (error code is stored in ret) * 0 = No match. * >1 = Number of results. - * - * @note You should free the returned handle (with regex_free()) - * when you are done with this pattern. - * - * @note Use the regex handle passed to this function to extract - * matches with regex_substr(). */ native regex_match_all_c(const string[], Regex:pattern, &ret = 0); @@ -297,7 +303,7 @@ native Regex:regex_match_all(const string[], const pattern[], flags = 0, error[] * Matches a string against a regular expression pattern. * * @note If you intend on using the same regular expression pattern - * multiple times, consider using compile regex_compilex_ex and regex_match_ex + * multiple times, consider using compile regex_compile_ex and regex_match* * instead of making this function reparse the expression each time. * * @param str The string to check. @@ -332,22 +338,22 @@ stock regex_match_simple(const str[], const pattern[], flags = 0, error[]= "", m * Flags to used with regex_replace, to control the replacement behavior. */ #define REGEX_FORMAT_DEFAULT 0 /* Uses the standard formatting rules to replace matches */ -#define REGEX_FORMAT_NOCOPY (1<<0) /* The sectionsthat do not match the regular expression are not copied when replacing matches. */ -#define REGEX_FORMAT_FIRSTONLY (1<<1) /* Only the first occurrence of a regular expression is replaced. */ +#define REGEX_FORMAT_NOCOPY (1<<0) /* The sections that do not match the regular expression are not copied when replacing matches. */ +#define REGEX_FORMAT_FIRSTONLY (1<<1) /* Only the first occurrence of a regular expression is replaced. */ /** * Perform a regular expression search and replace. * * An optional parameter, flags, allows to specify options on how format the expression. * Supported format specifiers for replace parameter: - * $number : Substitutes the substring matched by group number. + * $number : Substitutes the substring matched by group number. * n must be an integer value designating a valid backreference, greater than 0, and of two digits at most. * ${name} : Substitutes the substring matched by the named group name (a maximum of 32 characters). * $& : Substitutes a copy of the whole match. * $` : Substitutes all the text of the input string before the match. * $' : Substitutes all the text of the input string after the match. * $+ : Substitutes the last group that was captured. - * $_ : Substitutes the entire input string. + * $_ : Substitutes the entire input string. * $$ : Substitutes a literal "$". * As note, the character \ can be also used with format specifier, this is same hehavior as $. * From 0ec65bef5ba109e838d5e6928d7c84288380ae2d Mon Sep 17 00:00:00 2001 From: Arkshine Date: Fri, 18 Jul 2014 12:42:13 +0200 Subject: [PATCH 14/18] Regex: Fix compilation. --- dlls/regex/utils.cpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/dlls/regex/utils.cpp b/dlls/regex/utils.cpp index 9b9debc0..3ae8c085 100644 --- a/dlls/regex/utils.cpp +++ b/dlls/regex/utils.cpp @@ -3,6 +3,11 @@ #include #include "utils.h" +#if defined(WIN32) + #define strcasecmp stricmp + #define strncasecmp _strnicmp +#endif + int UTIL_CheckValidChar(char *c) { int count; @@ -59,18 +64,18 @@ unsigned int strncopy(char *dest, const char *src, size_t count) } /** -* NOTE: Do not edit this for the love of god unless you have -* read the test cases and understand the code behind each one. -* While I don't guarantee there aren't mistakes, I do guarantee -* that plugins will end up relying on tiny idiosyncrasies of this -* function, just like they did with AMX Mod X. -* -* There are explicitly more cases than the AMX Mod X version because -* we're not doing a blind copy. Each case is specifically optimized -* for what needs to be done. Even better, we don't have to error on -* bad buffer sizes. Instead, this function will smartly cut off the -* string in a way that pushes old data out. -*/ + * NOTE: Do not edit this for the love of god unless you have + * read the test cases and understand the code behind each one. + * While I don't guarantee there aren't mistakes, I do guarantee + * that plugins will end up relying on tiny idiosyncrasies of this + * function, just like they did with AMX Mod X. + * + * There are explicitly more cases than the AMX Mod X version because + * we're not doing a blind copy. Each case is specifically optimized + * for what needs to be done. Even better, we don't have to error on + * bad buffer sizes. Instead, this function will smartly cut off the + * string in a way that pushes old data out. + */ char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t searchLen, const char *replace, size_t replaceLen, bool caseSensitive) { char *ptr = subject; @@ -91,7 +96,7 @@ char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t se /* If the search matches and the replace length is 0, * we can just terminate the string and be done. */ - if ((caseSensitive ? strcmp(subject, search) : stricmp(subject, search)) == 0 && replaceLen == 0) + if ((caseSensitive ? strcmp(subject, search) : strcasecmp(subject, search)) == 0 && replaceLen == 0) { *subject = '\0'; return subject; @@ -108,7 +113,7 @@ char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t se while (*ptr != '\0' && (browsed <= textLen - searchLen)) { /* See if we get a comparison */ - if ((caseSensitive ? strncmp(ptr, search, searchLen) : strnicmp(ptr, search, searchLen)) == 0) + if ((caseSensitive ? strncmp(ptr, search, searchLen) : strncasecmp(ptr, search, searchLen)) == 0) { if (replaceLen > searchLen) { From ce92ef745ccb559c26361ac7c1ea60585776c342 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Fri, 18 Jul 2014 13:45:29 +0200 Subject: [PATCH 15/18] Regex: Fix compilation under OSX Lib has been recompiled to target i386. --- dlls/regex/CRegEx.cpp | 14 ++------------ dlls/regex/CRegEx.h | 1 - dlls/regex/lib_darwin/libpcre.a | Bin 522712 -> 523296 bytes 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/dlls/regex/CRegEx.cpp b/dlls/regex/CRegEx.cpp index 1a1cfdef..57b0ad38 100755 --- a/dlls/regex/CRegEx.cpp +++ b/dlls/regex/CRegEx.cpp @@ -347,7 +347,7 @@ const char *getSubstring(char *subject, size_t start, size_t end, char buffer[], const char *RegEx::GetSubstring(size_t start, char buffer[], size_t max, size_t *outlen) { - if (start < 0 || start >= mSubStrings.length()) + if (start >= mSubStrings.length()) { return NULL; } @@ -357,16 +357,6 @@ const char *RegEx::GetSubstring(size_t start, char buffer[], size_t max, size_t return getSubstring(subject, sub.start, sub.end, buffer, max, outlen); } -const char *RegEx::GetSubstring(size_t startOffset, size_t endOffset, char buffer[], size_t max, size_t *outlen) -{ - if (startOffset < 0 || endOffset < 0) - { - return NULL; - } - - return getSubstring(subject, startOffset, endOffset, buffer, max, outlen); -} - void RegEx::MakeSubpatternsTable(int numSubpatterns) { int nameCount = 0; @@ -556,7 +546,7 @@ int RegEx::Replace(char *text, size_t textMaxLen, const char *replace, size_t re * Checking backreference. * Which can be either $n, ${n} or ${name}. */ - size_t backref = -1; + int backref = -1; const char *walk = s; bool inBrace = false; bool nameCheck = false; diff --git a/dlls/regex/CRegEx.h b/dlls/regex/CRegEx.h index d1f19912..82db0311 100755 --- a/dlls/regex/CRegEx.h +++ b/dlls/regex/CRegEx.h @@ -73,7 +73,6 @@ public: int Replace(char *text, size_t text_maxlen, const char *replace, size_t replaceLen, int flags = 0); void ClearMatch(); const char *GetSubstring(size_t start, char buffer[], size_t max, size_t *outlen = NULL); - const char *GetSubstring(size_t start, size_t end, char buffer[], size_t max, size_t *outlen = NULL); void MakeSubpatternsTable(int numSubpatterns); public: diff --git a/dlls/regex/lib_darwin/libpcre.a b/dlls/regex/lib_darwin/libpcre.a index 33b63dfc8a0c83477743cd3f8000e6ab5e01f371..9eb3097c314a9ca26acc473c496ee5870d466fee 100644 GIT binary patch literal 523296 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

    J?dO?#0FHoMJ59n;36Aga};hY(ntkWAB;u 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 z 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

    60v_+Uj|V*H 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 literal 522712 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Ì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 QOqgB1sEmEHTT00P15Dn+{{R30 From 752f95e9137f7da3809ac93e753395e0b1169e69 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Fri, 18 Jul 2014 13:50:41 +0200 Subject: [PATCH 16/18] Regex: Fix plugin title. --- plugins/testsuite/regex_test.sma | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/testsuite/regex_test.sma b/plugins/testsuite/regex_test.sma index 8a524bc1..7e5e4df1 100644 --- a/plugins/testsuite/regex_test.sma +++ b/plugins/testsuite/regex_test.sma @@ -7,7 +7,7 @@ public plugin_init() { - register_plugin("UTF-8 Test", AMXX_VERSION_STR, "AMXX Dev Team"); + register_plugin("Regex Test", AMXX_VERSION_STR, "AMXX Dev Team"); register_srvcmd("regex_test", "OnServerCommand"); } From 1c9febfd226ddd707d2b5f42f5a00ccf7ccb7976 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Fri, 18 Jul 2014 17:58:37 +0200 Subject: [PATCH 17/18] Regex: Fix documention. --- plugins/include/regex.inc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/include/regex.inc b/plugins/include/regex.inc index d454cabc..76ad5bb8 100755 --- a/plugins/include/regex.inc +++ b/plugins/include/regex.inc @@ -118,14 +118,14 @@ enum /*RegexError*/ /** * Precompile a regular expression. * - * @note Use this if you intend on using the ame expression multiple times. + * @note Use this if you intend on using the same expression multiple times. * Pass the regex handle returned here to regex_match_c to check for matches. * * @note This handle is automatically freed on map change. However, * if you are completely done with it before then, you should * call regex_free on this handle. * - * @note Consider to use regex_compilex_ex instead if you want to use PCRE_* flags. + * @note Consider using regex_compile_ex instead if you want to use PCRE_* flags. * * @param pattern The regular expression pattern. * @param ret Error code encountered, if applicable. @@ -235,10 +235,10 @@ native regex_free(&Regex:id); /** * Precompile a regular expression. * - * @note Use this if you intend on using the ame expression multiple times. + * @note Use this if you intend on using the same expression multiple times. * Pass the regex handle returned here to regex_match_c() to check for matches. * - * @note Unlike regex_compile(), this allows you to use directly PCRE flags. + * @note Unlike regex_compile(), this allows you to use PCRE flags directly. * * @param pattern The regular expression pattern. * @param flags General flags for the regular expression, see PCRE_* defines. @@ -252,7 +252,7 @@ native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = /** * Matches a string against a pre-compiled regular expression pattern, matching all - * occurances of the pattern inside the string. This is similar to using the "g" flag + * occurrences of the pattern inside the string. This is similar to using the "g" flag * in perl regex. * * @note You should free the returned handle (with regex_free()) @@ -273,7 +273,7 @@ native Regex:regex_compile_ex(const pattern[], flags = 0, error[]= "", maxLen = native regex_match_all_c(const string[], Regex:pattern, &ret = 0); /** - * Matches a string against a regular expression pattern, matching all occurances of the + * Matches a string against a regular expression pattern, matching all occurrences of the * pattern inside the string. This is similar to using the "g" flag in perl regex. * * @note If you intend on using the same regular expression pattern @@ -335,7 +335,7 @@ stock regex_match_simple(const str[], const pattern[], flags = 0, error[]= "", m } /** - * Flags to used with regex_replace, to control the replacement behavior. + * Flags used with regex_replace to control the replacement behavior. */ #define REGEX_FORMAT_DEFAULT 0 /* Uses the standard formatting rules to replace matches */ #define REGEX_FORMAT_NOCOPY (1<<0) /* The sections that do not match the regular expression are not copied when replacing matches. */ @@ -344,7 +344,7 @@ stock regex_match_simple(const str[], const pattern[], flags = 0, error[]= "", m /** * Perform a regular expression search and replace. * - * An optional parameter, flags, allows to specify options on how format the expression. + * An optional parameter, flags, allows you to specify options on how the replacement is performed. * Supported format specifiers for replace parameter: * $number : Substitutes the substring matched by group number. * n must be an integer value designating a valid backreference, greater than 0, and of two digits at most. @@ -362,7 +362,7 @@ stock regex_match_simple(const str[], const pattern[], flags = 0, error[]= "", m * @param error Error message, if applicable. * @param maxLen Maximum length of the error buffer. * @param replace The string will be used to replace any matches. See above for format specifiers. - * @param flags General flags to control how is replaced the string. See REGEX_FORMAT_* defines. + * @param flags General flags to control how the string is replaced. See REGEX_FORMAT_* defines. * @param errcode Regex type error code encountered, if applicable. See REGEX_ERROR_* defines. * * @return -2 = Matching error (error code is stored in ret) From 5aba776da50d9bcfcbc1903249197e034bc36939 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Fri, 18 Jul 2014 18:01:55 +0200 Subject: [PATCH 18/18] Regex: Recompile libpcre.a with -mmacosx-version-min=10.5. --- dlls/regex/lib_darwin/libpcre.a | Bin 523296 -> 523336 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/dlls/regex/lib_darwin/libpcre.a b/dlls/regex/lib_darwin/libpcre.a index 9eb3097c314a9ca26acc473c496ee5870d466fee..04ed7f6fd9a3b9f059f655f36529c8b249f86818 100644 GIT binary patch delta 48076 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 delta 48004 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 RjP|?Mnm~_Ha^Koz`9H^rP=x>h

    !wb}(&IqB}-0?d7;L zKy3&Rf755|GZeh{$w)|zT5g$2`m!pXIGHZ`Mao=762r6&mjwC6G+CHEzI14#K+C}< zbrQ#T!AD70Y=e4F)ca1J)q*8}XYz|^zenMkNU!W3-lckk&hqq1tms-lLJ(=uWrYU< z7r#5P4!&GEmULu7=WzKIyAu!oCKJ2x&tdHYzTD5?3IdIup6Hd&!YHBQdk6!0h1czi z@*gRtXoV%U(WVJT=3o~efd7}?1^yS4`VbX0TB8`Een}|>O78Yl`qNoK5lNC-j_<<6s0* zbO@F7Fa<2dWc0CpkvFRp!AGDgCT6_5k|x_HIGnuW-Bc8U{dmzzsi*Jsmb$z!^mC|@ zbF_*1rDU5LV2^%&c>i)LXu6Y5ETdMHvutA^yo7gBy67`1ry}JOIM)9~3yQjT1ieUi zdmJ63QPDTm_nE!0@P18>wEZ3&a$EjC+WrO3s;d6~$LGw9FzDn)MMXpzb~rP}jDG)r9}k&*_Fk9wdf(sgbz^(^Nj&HpC?rso(So}c1kYYh z*+uey;H}Jfy3L0PgXr2`QCR3cx2^YEwwd;}yaU1TOv@QDfY${PvN;#FzC3dL#vnmIY6bf?1eaC*k=D9L=gTgTA@f z#?Y4@1+Nx1mK#oGl2)9)Tu5UErBx3^AxC1?_yEx@OoXikR7!cvDC=$Kp9!FW{o8&}cw~o{=XgB7YNci{6 z4wvMBao$&{IW7m<8o=adwM5!L ztFanmDhxTQKXtyKFj^*f2aa?BYyNx*Q>_rINgANZ$j~-3=aiSv@6&oDpN0}9k%Got znC~=_&;Hc2?e1AV;~)L*FvkpEZgXAXZL@JbD^iBn@33?gDGS$|7{ipzb6;>fQCHq} zxC?J-u>_CK)O?I-bI&}gVooMnCb)Wg=Fxb)2G#4q2uI~a^WZObsmD08j4*J~ zoM)G1ZL13(Rrkh~CotosI?lFQ?|=3Sdbiwk??27~O00lc+ebXMc5J2otmzBouA)1C zb!tu3(5F&st150X;ALK1@Fzd2*%<>lJcqHnZkCyDHnjXG+j;}7wcUW3+I8Gk9=BAE zT0Q3)4p`%iD~@e@FFcbkG}AvCxh|f&qjoUAc&Q^@^j}f4US>0P8I(rFYNNVddj&7m zl4hDWz>NIVuvs~E;dtMEBJhEUy!MR?cRoVX{@>;d)yX0^^Ad!p#fOIQ{)opq|H08m z=O&gcuiXksw3hOj)PELui_2|Eb>p=U_|&Lpy!6SuvdzsooyOAJ`K{wVUJ(K}Mu2h> zgLnTrhN3>a_6wn6vV6%+wZcm3l~X!j>9ZtVyGcJd6J&M2Kc{xm*?M($hZz$Sl!ukI zEjOIQGB9(x|G3)0?(odPC#7qJ2rr|<%ks!^h>fTXjzXOe6``E&%DSOk92hRa>c$FD z-Ei(j33JXT$kZ^h-;W4=5G=`=O^?j^1c>t5uQBa*h{aTlDbh+fyrDL+Dk5d@EJ19h z!|(Lc;{Z2C>(DFg*lWKCOpPgr#k(^`=POnHRs)OVCVbX5D95pz0OPpfRNPWEYPGlM4}8jT?c3oGRWg#Ph}pgL?fL4HTaQ}?4s6|J zg>`k5j;kBVqn8=WONJO;%-OW{ z#3P*gX*sZM%zj?`KkDIhU`DdbK2PYr#N64g9gpW$++4>Euc%5 z)(+rX%Pe*Yq&J#&mYX-34Ob7U72*~V09{fK3S(RZK zazuZvAM}}fQmT`d)-S0%c!?K2MhU@jhc#pV^DS3LYKU=GF&62bu_|QpDwvq?`}{H> z2q)(!wxp;pu*13Z5s?&W$SZhk+#~GdlS{E0rRlZb$gs*%s}s;$rNW)KPHLGzKuS;+ z1Y?kSy~~J|v#;T8{LblB28vLPdZA@r^ePfSNDj;s4lKh4$X-Xo2(LlW_-}OX=g5HUx0&a@5z|pcpDH32yni_dHPFz2XXMu<-oSWdRs(TN;$0_)sS}I0 za468;-oNESzFFgOZUQxXdzDZ1K|mS3@BBwK7ONa+e=T;lrw2WguT;U8TkV&A&-knC zR;PZ?gr5Wg|ApLnjd{>xo%yaEYZleXI@i=bcNpFe{|1=;Y9vARQm+ibq+#O{m^C>y z#;k=$tFMjp*2Q*%1sv`zd~|N=n^@=FpVo6(#o)(;9DifzQ8rRzZRb_wj7ad~ZO(S| z$CdNi&w~dWjdom>_%ph(g@dlfl!Y(BB|0og+?K=8{t<>+9fqp=xsmaul3~qq!zx7F zR9B&o#hp%u0(T)0a57Wo@q8zCx0ZYdU)snb1N-iX(?QXQIPN=zMVw#TFa7@9Z*}+| z8qPsYlHbrZ>44Zj4)tDCm8GK5_-nOT<0^C;W`Fl38jrSNFrGuytu^l84liZ)*W4I3 zRp71MDiGzZ?9U-!5md5tWk8D)EH`|{d0>8=sZEI`Q);K0<_EHW z#Wc^!o~HEv@kaKdk)(zj>rV|2F9pVg+L~B@KZkjW=2PUW&jcNK`SsbdwwsI>hKtq2 zi;*KbqP$AmfU-4}t1-E(74N^cX*n?pg4?uw8e=S*y_q!x^{f(^I)Zzfv=yVWKd=44 zwZWV3W4*c({u=MvSMdjzWt;vzO~U78t5Q*{j;VofxrUM8^n)QNs~4g)t3+WZ9@S3#tKbRM2wbhz(ob zUDn#LdRNQan6PqI298gRdZXn?fBn!8MzMe7DzA0^pSvpORv}Zv8DxXM&Sc%U{7#3L zVC|X#lyIs(JGz=&NIyceT{=lZ+o$Wz`(%Hr4cn_sSR36x_npX`5}CJH*z2Y1<-5{I zTgDW7#~(dFi|mF!sGr~LNbukG$9TkL{W$^N_O%+0m&x+%ukQ@mxKr`|uUhsS(IMkB zd`Wd*jc(ng@6yF^PAzTXZ-dY2pluDSM|9}C4X^F|MB;-{>)S3#TzU|{_fCXf`yr!N zUtPW=fyo>7-s~+jk$R`@mFYILl9hrCitLxQ6iKo2uejB7Yzqd8Mx9iE4^ zcvxV_AY(1lbvz_99rHc~GbK%8Mqi36OsK6ggAP{M8Y3;b-JD`HvTi&QAK{Isn!cuK zV&=z~R=SyLA&hEQCiD0}tSy9}J-f%z(m*qSAE&=P4wZ~TuC3<@|0%4|p2^=9LGo3F z=S{VdcQK%3aow4WPP1;SP;x@xaZpxuISpIC%@=@^b zy?T}z&KXc@A^_i!lKBU1BM9|Ii)2r==jDhAin33PYGm-eA-0dwa%`kOO7LIoN}6%( zPA{BE0>+Nk@JvjE&8TgAkzUv@YBd;W$M_}0VWQo>X0ig&B=UJx3m=s|HOVIdZs8Tr z_C}{|`2xqrmI=e{tj!tTjviLUp}{L)RRm%(i!2;s8zGyz+Cn< zsBO6dEJ72k{Qxk$d@3qsD)p1u3CpKtp1{0M^ZYUJ3tT!JAa$GvOF+eHUS_Z&x*XtQ zgWdrC82}GorK*K~M27)=#9QGHu2Zg(H%YUjrefc;HvLy*WIJg6iUAeYkO z!T+5MApazDkgFQ0XQL;&RW%N1X| zY0gerI+ec=W$84CGi}R-IdFSD(ns)p!ef;mAhgf64Q7c#w&f<#x*6ACYIe#^)97N_ zyn~>8bK;4p%NbFZx~Bqus7;Co5*s2enI#V4OH0^~fM&YiH}wX`ER=^A zV)}!-%EEE{RQ>QKA~nZ6TkctA*Sjx#vw=a7c&zi6nx%F))ne0@ld})Y9%Yl`xfhF! zFV9{kklwQ8y!Hf7=5_l3{2gqR+Y2AHw8&nYgHft+tK{lGSTc0AcbJMZ26MczSMl! zd*3DFDu`y5nz}qInVagW@EfZZoT265^XV|9r2?C1CiPAtwI;z#z_mZ;HF=N&vW-=e z)|F-m{sApFd+qzKX{zW?=wBfh);4wZeW@K4-gS?uEmAbsF6AM6M&Ehu4^FZE4=jA)-);1bR@~*oG6+qA_ zyn*yMQd@KKS}s-u>p%Vz%wXskmLND!qv_#5|Pf=!1Qc*6fuqcPa4>AAS< z%Bbuql(l)7^ZJkI;MAbZFX?vgMiAZspH|uRG3v51sb(U<)p~Hd>d7({lOmV?=R-5a zG*G=SHMeE37nvE&<%YkQ)J%l`mQ34qF6vGP4pq?IK8@8|zHi@q_v^!SeYuDJrt`_W zzazYaMh$<6IGKZKCVZ2BxR-1bX_;0^%AJP8g~{-GWF(5CymnH5tL!xZN0`I9|40d+ zB+NO9lsR#nz)?J__-J{0DHOt%^|Ic{)XUmxYt8t3S#K}(*KR8gq2jV^ z1$^&aw?c?xz0I`;gM#fFjVEKsZdTG7vM-{DBm30{!*z|7QsH4=hRpeM)Z>H+A>7i{ z>J@(nTrIT{Y}xuD*zA0xima6Q+HQceiojc86%08b>6h@AsMd&XaahE^_7sgcEbkoz z6MP5U>FDzGHI%VuU}u!qh?I{@j+|cMKj~hH&hVsQ@!C)49y~Ma(m|ytoL}cZ8Ab5x z!YvFe4vGSe?x0*OP_$S+>cgF%uJ%o1u^vrtn_O=?uzfLoaAx=H=@C?%r;=+&Ne>bu zr)y&9R$GaLaBM8*H1zy%n3yxEn^xBW=WWD>GnlS&y-4#53pV$$m+55!2@xTvunW$% zDDDDNWRS#B7g784lq*DPE1w5h7ycYpiRh~Rjg!oE(DPe&%+J<)i%&F!Smi&vt2WaD z+eLh|yjF=GrgE=19hg%xFlfm19r$(3{_y{ksSg&=OEY4Y!F^^V$xvOzV%jubp>}BIwf_j+iEm9$a zj0$!ngpoh%Tx*Q9Zj21)6rj9g z5pwW2A)0M|4b4Bey|{UMeguo|HU>A3-L-4WjpT_6*Tc|!nQhnD#Ym}5Jpkuky202f z^?zKhT#6^BMe1|qgp@)!ld*C&1#s@)1Dx6Ha_VS{Y?-w@LQ=Fk*RQVi!(a(qAO0Ef zWE`$Hizfl=u#-Q};dTXAm(9y;LlY*s`-+vm1%YP_t#O6))%_X1M&#moyJOg(KdFu) zG@VZK7ELa$j>uJLDIi*(d@Z*1bOood{2;cThOd?i)rPtey)_;)uBf}csbm(s(7+eA zeYnf)B4cDt{61d4H5`67^ZTxU8D1EWXEn1TsaeLm5Cw*v&Cuc~`0{=c3hWX=vlqPk z_)h_#gYupJADucN#sS38(m;$85PaTSd{BC~Z|cf`aK|QprfoU8C;j{_l^PK#&hbz++JO@SzJep#Mh%^-)B0{NqREoQq zK<>fHJSm9jUMj0nC^c=bd>(r(rMzBKr3!Y>sq#;Chb){^75+AF&oK>>OH|4)Nh1Ch zNnIcX+$QlLPLMsSKG>Ku{cjF{lU2AWpT?J~Eyvc=MU zgn%eU%$wu#h-rP#AqKrf(`EbyH3vqhF`}A8N>aT=&)uJ(M~!q3!(Oa%20cemm~m>t zI#NAJ`zAN4I9jhej(U=!2lt7UvS__VZzA*`lWX6RlaCSl%w`$XM| z5=s4y+V2Y-=*@!Tmc#?ON@_-xOy#K31~zco=%*{_^RB_PPATA&R77KZ75v^1WuV4a z`OVb@VrZ~o$0^b~I8Fh6=+-Q{ZEHC&!#o1J{w7uVW1Y}Ul2c%6TYN|OC=%=K``|HN zIl0`+Xx`5DZ15h{wLQm`)ia~qV07HWT2vQsbZAuUEqj1QB*wqyuZ4!2vR*bDR41`R z!(ONs`EPkSei=3HZym9rVZd*P*5LIlU&T!8vkw}bKe9GB;fs03UCWhyPQ#0FPvf^` z+%B*q%|V>#SNSRZ^xvbz3QG8^ZJn;*U{l^pdjhb?3(7k{#(&GhH`>9s|8L8N=ixJf z4e(u$Tj?~;F-7qG@7sdUODpQkUjNTR81*wepD#uIZ2+m+tnvo3C{lKg>~(b28^>Tc zL7K=43rwcEj56-WDXehqu57xK_`T0FAhC{d6<&SIp!gGT>|~TCErQ}g6K=ZbX2NgO zB#V*RNRp~bTk#a#S+JZJ6P4es7h~OyxkCZfcmQ3&uK?6Q{27R#>{!f56&sZ7^-DCq zjS&wx{5FF(c;;QG#>qRAnL=XU)IL3}gTJsc^WyAHl}aPZ#I5?(n?j9V~<5nn`xUT|^?SZ9?r7w!=-S6`D#0&iV3X*rS zPbHtM+h~DG;}r!LHa3XGJ?<4(bRvK?k(cOFVbE%YvQFRT7Jth_NIOWqJ@^o|fCV$qIbAGBadI%12bx8EwJg-5{ZWZBYY~ zjxLFdqk)9#?~oJHjK}NmS%vlze~Zt%dy03&0eSonI*CHY1B9{8m=8GWDY$Hm>ds?E zd%tWd&6|^V@sD@iW&4@zf^}wG;Wdmfyo8pu?#g}&R-H%#xwv&cQj|^IKof1vcC}uV z?~2x@dYKC-F{+bwY42t$T0hvEe4^L>MBDYM5{#WxV8HtGt~7ZJk|G1P-_aliW!k!9 zA6?Jbz9Bf}jSqK)KWECotPhLe98>`3o9M>~&Lz1;iQvnvM&v48N(jzuh5z1&Ct7z@ z0ciy0PwaYsXJ-Y>p27UqCmopmA~0_V0rSHTis*DHCM=K70Wmmh;3l)&w*b!f;1q*T zZf0rdldZ^u*~J?Am^&aRde304u61Dcjlg_20L=3RX3No0z}Xf2m6vf-H-+EU)V-;0 z@;;jR`R<4ftshkST^P^cXKJpB=8Qa}PrUX^IA*kp(>pVNf;Y6}a^I~^|FoS`9%&Y| z%Ij%m_r^e^iKfQ7wwZhF3OBz~z>l9%>d^6HM)%*gjj6#f*r_N1XUO>-ea40l~93N>Gv0BrTf7a1S9c*2#1$`lSW- zjPP?=7GSm4k(8%JdwQ?&+miN8P8Y=4eo(HS>4)ii(^p*A1nuRtZ5-btqPF=H!DJjx z^o(h<$dP>b$O6vkUP*7H*x~^Bs-(EC<2A<{(siTx1!r_i>j?EMRXaBC{DGpx!x_*pR@g!rds1XrrG;1{GE)jwZXN7 zla}GpJ{J&Zlt|F#(@ z(=jfO_-&?xAeTZYo%3zVmD@dE4x{fpUmm`>7&o!pbYeI~qbTAV6f_L_CfM9l6w#fb z`a!kqd87h^DJ)zIA0=TN=~ai=0{R;~K#fS2W-zU(a?(_Vxf?nFDeq5a2VOW;m;-RGB_L7#u;eGg_PR|eyyUITIm%2< z)#GpZ>y3@xJcJvTHM_N5-wi#ixo1J0ncw;;d|$%MAEzctn)wU&RR!j^xDxVep5>Y3 zHhMF?W#*@O=P+G>9=FOeJmeoBny#(1I99jnEv8}u?*oL{IW|>db75RU6_HlUKOUo@ ze1a8)`aJVxdG*D@oX7!8=IaIbQHG)qLl>(NO`0y^AaxQ;+ZnyGoM6iGhP7Ba6Rk%- z!+?xw(t247iB9aKSrg=!W^7|HBSmrkKsu9R0K}~AsMJX$+4Cl6PcR#b-hdRT9pnR_ zBOl=KX%gS}?xoQP*V#sGdgUaDCkVK@C&gVcw)MJ#%b01Q{Ez;|P+947C2h+$yo|ry zj>_d-6oHi04;aq2$5$u>s=W4*eYh4Y>A!oK2^Y-sdvhuc!{^ffeLhEN^v8(z+ZuOe zHhP)Q;(wxc`djrkM3jqGQW)%s6$~%Lv}bU{!Mk?tLnG9y3U7Vc0u){>J*OlX=i!ni z2)pp&#PUWNy-iZb=`FbyVHY;CP!-8kmZq4H>Qv0n59*yNI++Q#>=~0CiG=i+UzB;m z^zCI9Aq8&EZV-WIob&d6p=ZuhyF!T_LZlV#*=jj!^&k^CUVAE|Vk%owRA~p^`w5|x z?Yh(NLWR@^ZO;Qg53v5hk#frJPv(}mHi{1kTTQyef?(*wAd_?y;YwPPwi|P8%L)1{ z?TWXuP$z0BH_si;F(iA`K&#sKG7Tuq#TpI%Nsv{LJ6+?YAH_|y(!G0c^a1J?4)Yfq zbHlV5)GGSzZ3gvA%nn6J$e$h^2R6ch&i}F93Iiw5Whpn1PXnPiTuNfoOMhz%?A&s6 z*`D&7;i(j~G;r&Rd&kKy9^mSAcM{{$mLfnaMA{|K<&YNV4aXQ{_!Ht!e4NOeF3q2V znDA3M1!Ca|cwz;5B};;&S9%48D+}%#QK(na=Ob9EzFWfFPC_X!8Zsb7+-7o>*HFqL zKvVNA&lZy}x`m@F_>w3K>Bjxt>dz+r7H1`g^UiiDtwMVPm?N^hYt{p|nAo^@FDD{<02J|qtLgU?veyGxkOO|Dqz!yj36HydSS04zp@mFC$r>A%;y zxGVe0Tb_xZ2RGHjNJa0(zGnlsz%Rt?|cfK_for_TF~hUJ#-pZrzLP7X0dO) zHx|)yP-(GRtr@kg4MSQcSvN9!#&{{*lfiHa53rx?Z%GgEZ}e20YYO_`IZpG@H z!yJ;O?;4Gp+dchd8Tg|G0>`k-!H(VOtd1OKBx9WMr@^jVgrlk?N=8^+m@j37dj+#T zg^*An@&h89mh(a4JbLrK$U#>yUBpD>bBEIuUK7EN?Xd9$O7?n{X?o@J*thw$N!F)o zPoZ>JFrFo#{+jS+e)qnm6&EtElxYR`VoL!WT<9Hw)4i90gEHwex0%JKa5 zJqVOKb^b>W^NfcUwDbwnl9xW_ZzYt~{(8A5<^I$l2bs9=p>@TO4b)V0LP|fJvXP<+ z1Sq(iYL>+eqNL@l4^=`YDgKRIFT}q5o@o0iPH;6TEoqg|#$bfha+J?lL3xWmTmQh_ z)TjAvpv7iAymS`|L6W_dzY5Qa7v*f^y_U>oF10~qxm&Gj7Jizz(eCA57Y==nqKGwx z=TlfcFx)2T?)?63UQ&tulV%ZRtUe#YJD-g@OYgC>`@)aH#_4O`%?ZStBpZxCobsp< zh*$Y-67DY%M-{D?1ODBumNT*5#=RYr8_`BRM6Od5p3VEZoD$cy6E178rpRhY5CKR0i5f-KW|F7-f{QJankGPImbz7bZh8| zKkl(1Sn7ZNgk-Qdq%R(T*lCy25rs=t!Y#Zro8Pxk=%a>fmliBEP~awf87x|SnKOBVknzK*H4lzNhcp5^Jcrf3z0HS?q`TzJ{4S&B@z{bYG1Q7lqsf%wn&n%sk7)3P#YRoMURUxlD2M{{3v)NA;@BvunfTf5IBIv&wWIe1z@?ld+?#{xx)E zZAS0n@$WI2A9)4Bb<$Ojh?9D}CfZ{Hw|(|NxGUx`PJD{V(07qz!Mone+~(lj+_!VH zxzc&}Lp=~5GaBk$uIi@PZO}bndLY$4swv%x`DOWjj-*_!Sixxph1%5I2pN&ol9#)G zBl50ZZ^=s&PZ?OFh3aBfcBOOjL$pv`H)v|1dQQjgAN{gqu8w}WmZg7>qwQ7!7t$E@ zJ~D7anENu^t!*>A=kC8@SWI6R*rJuG%@v)S4I=WyvOMYl)_Vu8<u91(3 z&51NXtA%%TM&vekbVgLL6tSIKisY|0{?se~?`^#GC$(WERXMmO>6+ALZ8qrKe0WS! z2gW4TV#fg`>^Pt-cD`&HWpJAlG$MA$WA>x8vkhBo#AEg>LxEn1#x9fL`+vjhZ|N4| z&aO8D`-p_S`u_(2oJbqd1dBUAnWK}RHv3VgWb3^4azt(9hz+dPIx`hq(!eE}-Vavs zuKvM+kT1A)4W@IVrq?--!pmGjp8WQNzv{R8=w+68+Ji(E_J=(9e;Uz|di~#Pjqkwb zw8~Lkm%f)+wXL(frE0nkpGd9Z&e=pu#hUW6Y#$8!Fl^39CaF2n!at|Kzpsq$wUk5s zu|-^D`*_2L=;!aHedOc{w3^sEPSSxXicOc^t8EVqCyMhl` zm()|aB<*2e@Jn_D>s8JG?=oOAmZdKkjt}~IrsYM85l@ga{{2DD?>8Vg|IPrFvYqj7 zSujnV$@R$15$mEfpWs4K+(X|hKrgbw9pc&Qq=`Ptyq|QYI;#CY`8(1ZIP~f)IJm(}U&yEgj!G1OUzy|$;8&V& zLFOgw@$nR%2yO^1|2tPM&aIDE z=ed>W2KS?VRm88yFurELJmT4(5Kru$XWydTJ@BI8*)dEsY3l9kv8(8=VdRcm^5{0K zdl1EeL?^&xPQ(x3St62tTj|TjI$&yGaK_bbYg$$bTI~5H`AuX&@bW$|QM`{FE+C`$ zQGgkyxt$3f8!iOFU@*ZHkXQ(A(H4dvxM4NWprHIy2k?RQL06xxzqWD1+`y8wjS75$ zL$$90fQw<9`F&2OiM6$wi5n@a?OHf(EjqQ@#5HUv`8zQ3+`y_01W-d1`v9x{1T`m= z8j+Q;*qDNiOqsz-O>Apj0Vmk7-4p;Y1E3LK;fAL9w=DQMRctw@Ak|}OT@is~>fQNo z>UBf11t}_L2s(!Lg;diAV{6JL2cQH{ zl3fu6KFACUY=ozWSaM)O>wiAt;!|b6 z=kNmFwI%Q{{+=%bfCx6S=#$~*4`6p&-S0o z7TG~*isE708)(5xjy=|B1%Y1d!47_#S&Qrm)(%RMYz?M7T%=jH8f!SFV^5mp>!c`q z;;f_v&1jY_nvsKJBrp=$PEd#Z1QqOVE987CMFuHuxPC?b0?lvKgyrD4;Yz8TSlVvw z6W(m0cw^rtIe{R!5Y_-Btt>PuEK8$>A}+Wbf1UhkDt*8ql$m4ci*jb4 z*(21Uss7@!(%j6~_rSCS1T7T~$=Ms%EvJV`b2?KSDbJ`|yfZ+Q&bqUY(^;~nKl#03 zYfsHeV;R0iTcLg}D%gu(=M-_&mh>?aVw?Li&6xwKoHh;b+yTe8Fn?zhsdw!th)4@I zpJ5b9-0m3+8dhVb9;e&o&;l3Fyh)QM$7f(|C=Y`Kr74Gd(%M;NUizPq zQ@mjAZMWk}(oTeN^gwia*E^LT$8TE8N_M=OV6*1tb#6{h&_TM91|eS$QHQ}|`pNEN z#e5ttEtUMogG(MX3|MCzUpW#ZaU>o$;ywvRf@?}Rzdea~+@4i2x9IHid^(A&LUXhe zEoTwvK}Z9&ul| zDbBjD9PgLl{K{pt=atmECSz(CChGaDf5CYl7~{y`u3RQHg1iSHCiN1C<5g}? zM&%HKP^P&q1GeeQM(iT0IZM}$nb0Q5h;rdWI0V%g=|fInyyswo@ijy~=~>z~vGQn@ zwV^l1J+3Mbzr^d_^Yb+udPZzgP*{&TxPWrKur!TCYHo%s2tM1sdrMP7+TwO*+b&If zpmK6{W}Z+XJELO{MXVAnR4y^NkL2}d%pvu}IELEM_^#MZxd;!&LY+%FbF!onU|7xE znq?Tao0A!r`3v4P_!D8MR1o8Y8=x33hclkC@KzXtA5G>*C(}V1Z~nfznc2EyS(cR4 zv7@z=o1${r%4KK;T428we5dN@H8qoz4Dz>Gz?*Cjdi0i+z>?4R{DEUh$@i=_pS{c` zqTOw)$@jd&gTJ19&t~#H5;BwTd7OODYFJSD9$uzall4@-r$R)jWqiZ33IEdm7>WHj zl8TEFf+HHL3C-)g#cS}oImYUD96wUVRAjBv=yj>!n1=E>9Hv@ZcN~C@1kPQvk5F4) zd%w=j8s|v+>(oT5v%H@aAs=<-`7N}kPi>2}OT_2I;zNRae@>LtR9l;%t#N7#wA8om zJkVP_kkYL?_w!Pp=Ao@|M?;mjsFufvjSa-Tlv5FbbVS2AZ}HE}ZzTYhfC;Pb<&NXcL?W}~RmY*`ssKn0~Z z_*vPxN|%iukp28ehd~3@NEYlR$aO#)eoj)xA6W~spmJC)^n3fC4K+D%KZ3w7Y&>&DnTz|DT(g^ik!BGxIqbnjZTJvNGNef9@ zaOQL6JqCXVuvyn!Rz2D6fM+v(5FD*erqoX1tGj1<5BqrydQ3-w&=FBjSTV~uf=B;= zP2Hiez}kUW`EEQ1s4FP0QJRfH?SHmIOx_=nq30o9L_Of24(2WVUixc@7W*yt0Kd7+ z1$!^B>?1Zjj(&^14)hU0peGfF{9@zyA@8qoAj)t}gD*!Oz-f~oP}yi7KC1&w2T*v&6L9j8v}E*b>&}Cin@1C( zux0qmL*?|bQk)M(VfR6y;;7=AzP}HobA~)&+o$E$@F*Sf}7AR%_ zwQM?$DTcjQ8iZR7@5UBW43UOED(ZE{>}ud0DN-G1krPw;RwrBCX=GdA1i|Bx7wK}w zCYsLcN7pHTT|QC73%0VolD=Z?$1ty!eKcDT_%tt&jI*RRl6I}49a9<=KG+k}ur zXFX`O@psXX)oL|+k{1zRhL?Vr*h~yZ|4qd@O?`&1Nu@z|l|Lr?d2cziZrMk_j_@)= z;G=xlWzt&x#aawvw=URouY*weWP3<=Eg(G0e%__Kbj##_|4Imm!mb8f8>PEyf=PE$ zkOxivEOwJWKh#5SJkBbnj(RGW)NrDl$R=jzEZ*4K`7A4-;C+4%XKL;rJVMH+?*I-s z6umOy#crBq>OFAk=ko{yO~z*}MpyUz;4j$A+Z%+P_0KrMv>Bt}mobFZ<`DKt0s65K z_8il1PLrQuIxuPEo}2)!R9sKE34-o4^z+iI_*uM0`7YiqYu$O6cg_2F-mN=p=Ir0r z_c?aTW8kReIl$?#dcmvN7ZKU zkM=MdcND2IC$QCf>FE@+WJ_?C?4tAencvc!z~Ks;)R)nJ)>A%-{syZ*Emd*-4GLEh z`r7^?xSA=~q;fT}a>s;AbLF_~<=%sF^4BPi9H`gUf3Pk+NA<2Q4->qO+MC!=J!gt| z@H=g1CFFg3iw3}YUi+7s!5v#}ZYyGo3#I!c+Q#3~x??YI@x!R)iYc|Vso+#_XU5Lo zk;WyTQp;TVl-fEbr0c@3&=0V}xe)?KhOaQ8ZT)SMXpx1Waw+=}bTW+tiJ$yGD+7gE zdfHu}7$xIub9WPGbm3LB;W+Ev|1}mh<6(=!!(`gfL)jsP@>5FP*qa68G2ir83gl;F zd84WFdP}$Xq3+8+k29sa2r7$Wrz9iiLI12 zH$LoF?qnoS^9_HkXdET;Rf01<1smML?$eka=y4olw*p$EI2BENE;ovuta&1uuxfKi z&m;IV}Jql&Db(p1DY=2#aqE?IrL-X`K~HokVh8 zgxB8j$Jj!6d&KM8L_cx7{{1!w?G5Aya(G<}x_f|hR+L9zWFzxA?_-fm(K?Biz}hHb z8d?0An#gfE7RRntCr0leQG!9U?!5YJha z8-EJV8f34AMu+iBp}=QYISWu`7S7~aPOT0Px9@B?SwLkYpPCgCse&go`LcTf`vpbl z?e3phjwlw<)BbmlB07y0K8}da{A*rBZ@twFHnW&4XShN+Ym+}3=D#2|%~`46{({eM zzXM2EFqpUC<4yYbOO#ltj|=p1hCUj$A9qN3LE3P_Ar<||@-th0INr**L%5`?%4{7U zH+#PZf|1o=v*DXu5zyAusx>I%MyYiAXS`N}ZBq`ZBy$mSSngsirnr-`&6E&R7}?DQ zOg<5$m^S!q7^nI%Ke1FV$Gf3k0oC6|b-(1S;tTqYPJy^#hZB3x`e3hnyVL|#9 zI0hRbG-u0T(aegYs4*Y8QTgp_CGB43Uo1UyS4}<7v$DioHbqvL%cjT+;~R3>gUt)~ zRj56I21g><6PV!`oyvZ(ig$Hfb)Y@A{RwK?_ir2hZG7%UFOra@Y+dA!dhL^;*(~E> zzMt60b(gI>=eC5cJLhr98Ofvp6lVaFH30rLM1QA7f2Zhg>yE|V^3|<7mimA9(v5hf zN*$lXU*M@D5mJ|0U113v^JYhMB;MBzq02i!$GFxV*Ki@jk!tI^93$1bBg2QPPO{p~ zUbFN7k`Yb++HfwAuZTRIa2iek@ zX~1HOr@thyAY*}zkp>c?DwFyfS(*jR`I!UnqvnU@8yUwT(G;JiYBbiMUdQv<;oNqc zevFl(dIa=K?PKFY&b35g@wS-|<0c@cep7bh!1Z0N4do!_5P%mF@>8^eRGDA(_Jh?wMu1o8cUB3$%(Fy_+g2s~ z=N{H)FVl~?7bm&ZJp1n&$=%L!-LkUxf8}L<23boX*t9^Ue%mHx_GmGM{C1=WwR?-uxUE* zKTwnPy6g2XIDEXThxMM|5zP#BJ2#aZUI6C)E~i%D&e*+8asIiD+5Q;+bj9f>LLx%^ zTNaEX(#!D=Y8(z4^`nS`G*#~wU)BUi!dMK$dNe09<)4>c{p$6JTHzy4XX24o7#7M1|WEmo>^bSxbF_FGye}i?YfnNcm zhBFkXWes>d#!KH95g8r!f>m)Sw)A3#Wk%YvKw^$c@8$Zv+-%l=m~dxx($-+)4bI@M zbBMTwzDrW=@A^ry4DX8-VZxD z|B?^m{CBy^SG@WYE$<61SH@|%g8ebZI37Du2d*}2NkHRL=6B&4tsHFv3<=$Me{^m5 zG{tSa)4F3J7O8c|62G&hDvf9PKE-5O@~x$xFzvZEq9&uJxM@UPW0aX1n$Hq(_`nFd zx(oL89p!7n3n<5Wg$_`JDa!nXpWD}2UfN`N$+uh>XDKmkFi^8c*bqKUQ?qbqdZk97 z{7OshcB7Q#L@WSbr$~c7%lwIDs?3!FS6sOP8UyX*@DkoE!^(SU7QF(3o0ZpdfloIUGxHnNtulFoRZD_28vX z1fFO=K}}G>a7wF(aDU24qCZ1U%IS*CU-%(BSS#;#1V}wke%@9=9QQJ($F@qqWFu^YT1zw67?>OfzT}bth;oJkw?CKR`(|XU7a=+|8{G{bAhCvdB`Otd}vS zc!_4`=JLejs+3>;vNiZ0P0kHRFCNM^mQtIQhhwZIvsua3$YO@UrGu zbQ`7d3L|dI^&yfo3IkDazb)Eax~PE66BL>DwngXTjA%TGl)%W*j#YbMQ; zkAHzfdZ{oj)3iLyC-9`BF8!l{cbHkN5Zv}XV}Z0*VRE!q0j8UrTifW*(_+y2vX)V5 zS9Gx=6A5xR;f?tw*)e6oUQuVkAHGkoEi9Fm$@Rw$^fKR-6n|vsS89O(qqNY!woK4_ z>C@Gg838A2=$U&0a-%S+)MtIeylOA=DWO#SEY($6;Nz3A#aJk{36FB)k?})&x_aD;O!^#Zhd&umI8a19e_5NW*Oa)IGw%e1LpC6_+_;ABd6YcbzkuDsC( z$EsN(2Lqn?TF9uYm{mgp11Y&fD`6B^#KMMp^rryGny}$8{le$To+%-mpB-I;3ei&g zCBFi*CV*h9!{=G2zmA-vB&p7xyV0_j$-gAl8NNYx8LmRP$&(!)Lv2B<2_E@eAKcBH zy<(>sEKgA%xU;7c#Y;b&N$SSo+v)|8P*~EavtyckgWme!Sf-=GA(W2h2M~i19cCa4 zYG`Ohhrc7Sfvd$Bp+CAN{DHFr;DmSeYm+s!SJrysb?78{@R`T?$>`Jn!{2O@8^yi! z4SH0BCIffhZT#Z;KT;510i&b%Fmv_Ea)$i%-nU&t%e5ttaCR28Pg2GLS z%FfrT`mIgvDD$qpmSKABeaK>%1GgU^)#arhvVvNdco*>NNR-rVIb@mtR6_2n?zWff zyio-Yg)Ur4Ir|kk$I6|g-^MLgW+i-q0q{%RrB$aT2>SzMp2kgct0V1)_Wg!??v1f#Lo&OZsR&}5AqrHBTV zNopJHuJ595v!UIXW?#Nfa3+QQ(gAo0&u9px!_R15aZJn)b0AEA7(YF7k|O>H-eL|X z{5vC;`oWbv2&XXBg+KmpVbnzPv$Yxq)s&gE52L)=gfFj0`3>&8FP-0z*H&N|AAPiU z0yA?%k-%KIq?^Drf44`0k)7HmW*H5z(U`u)W6@CFfXx2Z?dyQja1x4J0E?NxJB4G( z%-{(o-NFZ`;kAz@;6At9#PHb_k5gK^7PKnu{V) zeGL)cvtqcuB0Pcl8);v2?yA>*1^R7trPqFG!e~f-*Z^0`)T~PP?lxN2>Qe`_gE*pT za0GB>$JBM_y{JI6OG~2*{>4m<(HJyB`pv35X&R%HC)ryNvJ;Cv|F+6iW(}>=FTq=@ zKHSxI+OE_) z*(`&o7R_ihrw}5g!`rgpZ0cFKQcy253q>T8Vd$%RPN(H6V*s6q1RIz-Q^^q zp3_S;iP2h6qT+@gDD?wC&a|R4l^Bf@YVsv`R9aTo4%jhf7V-G8#@L53hRxJoX8ITX zO-Brfczn+5z!l{&zQwaXE%p}c5eOCTWxlLu*fzRSIz$&q;jS9Z{kSo_XfpD+QSI%7IMH4rL*LgIYN%fNY~?|KB71%$L>cpent6*DxcjGoHJ8iGip-GMlVn2up_ApElSsrU9Qgmq&2$y>^o!42Riz2U+W{jPM!?0zOaPjh=cpwL^QriKikIqtSbHsYJBpr$|~(oF)X9wHoAjeLES-&fN5fb{_$OuwAt;9XdJMnC+qh~7`=FxD=!KU8 zWSKw$ZWsGIRel@uVPO`?sbbPnZ}4&Zv&IIrRo=%B+lFsdZk)i+?d&+qk+7-em?P zT!u8kh1l!#hnv8Ac*ACEhh3&Bj_@2$iV{AVs=L(0Gj>HyOdY7FxGJz>F)Uc1;;*C6 z$ezwm7&|1kr?|;9>Xe>;N2l}v`Y>^Ql%Fl=IhcDt?Xd7Emmv!G*JuTDoJVq2(5a;P zsHB}g&;iSME0Vo=W@6%CWn#G zNW*m2x$oQh!B6Mpu1odWJJ}BTd!kU=FKb?oNCjVO*vDJ+49&T-^G8=1oju5;KA7w9 z+SmI8&hN4qZ9^*zy#`fv$0&N7dkYv%;xy{-aJz(|>1>v{}CJyIPuO z#Y;_o`NA)G_Mf*4k5;qr$jkgUOAS)5uy)~itw6Acey<&E_J(9nt@63Xxjf6|aO{}` z4gQ##kSinH`uec|ImyP5UVCL9JE+BjwR#6ku&O)=<~}OW!z7hjuTHei8RQNr)yE&d zU_KtjNBN7n(R}7|JDTh$e-&yY!zAb~HruX^26P8Fa_cef!uN(alb7nMB-QMpt!xM!YmRVtuJ=Cfi>GVRec!`jnqka?P{ zMA_QYEIXeDb>pP;=l1ve`d3sj;o!0g{p(e}C=<``cy0j>tP7^ul?ZkDq#UJkQlke4 z{oVwHy(4Z6V_`MW;D#CE%674E#pdiC#gN7lA|(akhZ-@AroNj3J##0 zvH^PMx-M2qH1{S`C*2)&+g#-Ety6Q4?xtMS?O#;xCdy^UAZT7@Jv7&*4bwb4UlAJ+ zmUWj&qqw~Y8roFqQlZjSFjucc7(nTFukh&tpi);Q6FH*Ww4*fY$=omt?keeE7n3PQ z>pFzQa3{s-SmZgCGn&-RbBhgazQMo~W370-m+oQkXV%%3zZ-+(e40^ttHmp8mw_q3 zXl9?EWr^-2jC&d5b6^-sM4ejN#2788%ax0R3o49N$)TiBYBa0&Y2eif%%Fi%Mnp>w zG7i;_Upu#AV{rUz_begW7~It&7lR$i=SRnr)p0!8Y1P?>el09$6#hm<3O8aYf_GhE zGo_cCsZ6cu6OJXwismyenjGo+%!}F4oZwr{C+Yn2tj>qBBN>WRJVTg55As6my+z-Y zG1_kS`ZW7*V_*6<9Ok7D1LF;cv+j|?)u;(r`3i#2&fsu&PALRNBB5@A zcePzJS4)~Lj%q1C$4@_e$f0SqDg=u!Gidq*3V&qonihX6z-Z;oR9Jmi8~Yr2o~E9Z z&*7re`or6rIZzWPtx|U{4z3MOxeTj6fo_sgj(XNvvu8g4P?Y zsR*~?7ppzDqspc+3G~g{Ayxqp;Ivl`sV>+e_i7Z8y5X}H--AA!|t_({vY`B|qo=p=jd zN-Eg}?OobjcM>myRdj233wDX^c4xrh!Gdw+(WWci;yNjjedtks!3oSxv29F;euDWr z)cHtz5^1Fd0WI{_u0Os;TLP4m9Y{@F0Wb44Mr6(-{T2`YQ>-9-C4L_1#^^j!FVn>0 zRn8*yGRN@XTocWgv2ODcPN-+8(`4T)MP{0^Vqzs7+eJ^3tKg7nEH>);kW+@h26Gfg z0L93Y&Nth5XYU(U0nhYhCpA|4FSVSW9m3_??+fS$h3??wOAIY?gLp`xDb+JMs>I3R zpI7artANoTk{vTu^!uAO#v65Q7IFcY0=S;7M)3QkF#T1#TOwO9=^fXOo$SfXo9CVn zBl;#0W-jxDc$0gYG)uHEI*kbahlq@}lwsB&t^q>@njV2F2wL7@GA?^%r3sfbY^kO) zsV3W>Jy~I1{$vG}$)A8`Ih-bw^y5VRj^D;by)L-vJA&Lx-=k;>mO!L*5}MnCaS=YZ zlh?f>|Msh>4#z}a)D(64b{Heo3CsBJ1^?9v%xQB;cDC7ky)ycWbEp9V41&8C02%H& zb~CZUHq2+vkFJRN`2b~B*wWdhTB>j@ZQevncc>-wN9zYa#P!p5X%-v)h-o1&bQv%fbD&^ zT}PL3&FXJ%f2cBE6d;UAI({m4rC^QW!B4b&@ggf6sjH?XoEKYQhvk!OO?3=F*7{pp z9v70En9h$0$wnxe<1;-tK5HTb%n6CP|LVUZ5jhIx(%O;Qpa$OSQ9OoscS_s7Y-YjY zUg;m1eap*{#uNugieJO&p9%)}Ca@nK+(-=}Bky=J7i1ES$r$*v)vkOPhtJ#~)h2j$ z&5d)-EmZ9Y8LpBOW@+r;NR>QunwI>W%{-3b#Fjo4;SQ2Z%r_`bGUfK3X*9oPfreYn zzr?1W>hhZZG^U-6=0BT<-D&>wB{9FX=s?+ z@D2$cYEeE7@c^g2Tz9Pt4k=s~ zWLQ2xzMk`>zvcAnT7G?jU(&9F)bff=l#H#t4lDK6#nhLb!^bt@n_7Z^{xbYv^uvyC z0xwyB>?lRe^ZEY&pdakqo`@84&?BolJTUV;k$!Nxp@7OpALK+Kt{2iw?Z@ccqh1*H zn;4y?7Y=23(f$&r7pfq9X$m_5D-g{}QI}9sOGzUkZ`Z_+gk0RC0m4Eux#%PBjUi`(PoavpFN+!C5o{SR_U^ zf7>KR_NKGx%OayN6PH+qBJ*E7gkR<#=O;S8IO(UR)?WmM_~KekPfLlsOv4Wu5@6$G zO0}>)@y^1Xt?Ci?e8JwM=Cgrt@lP=+Hj)VM=P`;~?ovD1vEwsudFku0ZeIKOI^|@X z*S^Z!2)~3?YI8>D#@X~#RxfR%lm1?2%D$##MbRB7=i3V(xXdKgwZL1v6J-I*(pKSR z@#oTz2F@7|qY*`WroyIEy!P7xxvY&_93Io++PZLrA`EkGgx7vrLT5rKfoRTzC@$JZ zMX{%>C=n8JL@veOKVc%MfOQI3Ik#wScrb^8IsS1?<_ah22f@dw-xZAORIQ0t z6rZn04V9WT1iJQGYuBowmRXzWIlVD;n3FQ>0}i4u;bC*`9g!k zWN#`s_~3#n|Gi_!RQeay5RwU}e&awBfBT^~FC&AMw;DS1;;`5Y zw2ZqjU#HVz8;P12c0OO{PK&J#>ZbFlWLQAny$)mh5dJ}1Rb94G3+T;|lhklH^WDro=wcJ>f>6mw@_#hP|NFqxks)R}g|BGwH4||uue6#*S>Zm}w zdF|ExM?J|3FxD!K*wA)%BDiF-F|L_P-h_XW3P(R`%TFIXM4HRVYh)kVnl@?xc?IBi z5$y!uy&7qlO{YeF@=7GNhJ!}p&BXoAiB!sqnC7K8l;lGVD5;@Gg7#^Z+JhH~mr$i* z643(uS>IdkCe0boa1#?`;Zv-`2qt|k?qzKJs`WCyhK3usH%lfW1E9L$NT;q8Qb@e@>k%5Phs-WF&xCJ>fO*&|jL@jFU{1f784 z?gOa9vY#4(wFA;*&(j?M9KKe`M(4)r@HO5Ue4F4NS7~0A+=~)Cf42Vq z8RbfHKOXJ(Ys<(dkW9=uhyKV0_|>)k^IVt}1h?7s5v<1^pzgvZ8k4*g#{_XwxFKo$ zaY9UH)j@9vQAVtpiy>`H@Ya`065?6t(*q%#Ep>R!X@w-iK(Y*e7ip%=m2_ac8qPi& z{7#`{_z-T?8dUVW#BYuYPXiNn!hDOFFmL3yYob8-i#7FrYU&))#ld1m<<7+D3i_Eb zaz>XDjfpaz+#))o;rsRWs7Z zcN3*qJljhbYlEAo7)HlRx9o$CGB=&0p9(wubjeQ7rPFMikm9H_CM%w zvU1YosFGuWp(m86h~qkQaCi5i{#Da}-FodKDC{6zuQO@P4#QBZ%bW+?L&r{o@4B!U zKUeVvMF4&{qlMeOVmJzq)bHZ$2{P#5p}W}^r>YJ9B0`q*sa)H}A#&I?GHpzDqyf@%5XSGY!a{-Gllse&81!5C zM?3?b!$*(~cdu7?w|tc7lCSV4^92soa+yU`{irt#Zf1doE@LK&+BBqdQy<;?wl2I^ zZ*P7Se1`APozv$z@rAiYhCh`~Cu+kV^4|!)a<)|it9Tn;PyOte+5$O?3u;^C4KlZ| zYQv3eSu+gAK*szNw|0-QsQPy^4 z;@+de)%=L-%CRq5L|-9AdK^C#W-|H0zq2{|=KRW3{N}nS$~3q6o$sy{To?MJ$5fA7 z5Z?n{s&P3W5vseQF{)-R1dOWLCfwb7>%y@#F=E3#6^t+q=-;j4heScH>!+|3-MhYzw~V+?Y7@)l z%#DGTk#zZ_xehTJu^qh~u^s(hx~b6IKiZ7vHDVXJ>F@lF{Ue`P7XOd))}Nci{do)D z{JnVL(%P(c^Ob3|4dJ;P1oK;U-}OgYl{BP(_bWfoY_4_YT?`jElkiH zqEh!fyr+d$?^ftU0g@-2ncn(AbZkv>M8`sw$u6b^R$&1kbE;3VGDa_#>Sg+&=+}46 zuSei}ear9*5bF6ung8Q0vevAq_z#>Iq7n*z*zl}XHZA7-qp2#(qMp;0f#KaaW_V}P zA1pm#%OP4vWamA-_Q$>UHw1A=WV0`B7$;G3^1>Q`ZqX^>Q?pcKso)fKvyessM7boo z8^5nfql{-#;Xs>FnZ|m>+oMNz$-H6r>s`$061OS=%pny+z4TFJZo%zxHNt;9-fAAq z%)64v#^A^*og)RMkOeJv6;_L$j%jw!X_-f8$X{v)?$XH#R z($uyV)2~>y_k`N%aNajsDq*w9ka)7cYWs%Hm&^U-wXIZC8dCc-TX3IY?DZc~{~Oxr zH^tN#&xi5!rd4%GSxc2)S$jKAs4VG zCQs*aRMgoJC&U-!x*YKyto@AZdS~tX-wc&=w`)zn*nfC#%-BzejQz0S^$8R-hyEAe zH5m=_9!6}?-tsyAOc%wgKn1v%&p7yH?0MywbHxp0831+y$Cq}iXXxA=g}Ek!=dNF#=+ycNGPbA ztmHro5m9Vs#jQWfaUya19Zq8QG&a+=9FMpyR*Od5YO;HfGse_lSnj_#s2Z%b(8MUI z>FnGZ_K8(Aw0h}fG~RHvmtMkOS|3X52F{k+mZFvHv^G!I%70BGTr)_$PZK$C7@FYz!;MZoy4urRtFe$q$J9e-g ze1xR9lZXb>eGSur$E-r&`30Ozm*&y!krx=Jv*p0-^?~};yoJf~q|DE;0}F<17C76C zWEK5d#Av=Jd_@PHlaJO~xCxQ<*^a`qc}rB14*r-e=gEesdB3)z+Z}C!8U#!T?qdFp z@=}Ds;6KN8dx-1x@j+!{j zL%(+0#i1&>ymV8F|B4R&Fkro|DZpqL2JEQ&Tt}iDV~ZdS?ziP-IeKQzSoy`24-X-Y z$~-jJ@{j>4*h-pU547}?k#MU2abHlWdS_%7^#ipnm z6K@SR+o}3l0`gCJzv&`;R$9>O^t0#(C&z_+E4pSIo4_z;>HHa1JnOv7-PADh)KWXI zK-CxkP&GD^MfR$K8mfg?tHK=P&V?cAODTF*@TPgq1poe3^b08C3XD+}Ic08)-Ag>Y*;coW4vrs_-(`GD&_o>`g_CfDRzqqr8yXZ|1-lc1|5L%0#-lW> zrI+1ULiF=Fk6^wnd^^US>S|MA z2H&CQcKgeuz;=hVm%dLnB5mlSir}m{yjN4)bBZnnmaKF)`^%W3`#5mlz?uQc?J-{Z z`%-)oeW~RFq}uKrT0cow){18)lb5lkJM(QGdxPNDzy9$6eTN;HrhR*-t8gSLB=y(o zr7!`hjQ%>U#$Us6mz?p?Qaj6MBk7OHiC_=TsN~|g^QwkEogH~E_cbt9FZ~PX*fy)2 zh3i9~9{M;RvX$4QK0JnxO+-&O(Y%*l2Mtpn5^~(dgSPq+UMRdLKf}LE2!O)l$vg0H zvEf9_Q~fd1a#Wd&JC%fc^XhhA z2$lPlz74+$d(%kv;LYba> z^3pGAmLwP`cT0Db4jp1-$x|k0%muGWl-X7fUke9E&FPJMvC~U^$2U z6oPmw-}N6j7P`Zi!BcM_JyDR#%H`A{Car|_-CyOpsZCK(kXri%UA8dQRoJao)L88* z#&&GITIFP4axon2tN}X_&JA3JqFPw~r>-_;wBCT?@Z&(Q)Ht%S815o^afR}r*5${M zkKsN;(eTgObX%Z-RJ+g|i9`1427T{L=qG?a+<>O0*^ew<>$ILg=g^}IXC<^ywlWn| zNvOj{kZksAi(d#=?f?%4yJjw@Bubfvi596uisllUM}y#4w`h_uX3hIp%2>seJ9sF; zBqkE5T;|&(D)h+S>#qWdMB9+0@Yo2W*Q)J;j$kztK;cLV7wEnsR6Az*0fk-u_=|HW*(h=jW4hTez+14~v_PKCm^7k7`Q7JA=>BiCs2g^HvM6G)TbMiyEAhHi z*ceLbnw+#7hRPYrODOE@;m0G*cbMTX1S?X)#s$lpU6&L zqLOGTtxh%kxH{dJUL1n>Yt(Ichr+(b0d_@{;W3jwyO$YSqTDNCH4N2KTGD^ini2hN z*5B}6)-(Y?pUI9IavIECtv?`i!U;J6VM>UP)(CcP(_F)a*>_lERER z#tbL(E>hQHSt?ScX>F1SW~K3ojOb!fb!hpEY3(`#{a+g$oohv zg5WPF@h9?zwP{P_xSYv{`ne=?W_g(a4QWY~{+m2lUTVSLdY;W0DJYWV9eK+459c9; zQa4KVdDp$lNOSsrVDRiH!xWhDj0p?jC*mMur;We2!h|hD+ekseFk0I zGr`94yv;&>{sU7%E;F43sy35__B%nzyY)F66?~FUbTLER z!rx~71zpl2VXF?0xMZ=vRR_->!*M4RFuBgKjvovxDgHl&QiY5yezJs?R69bS1VDw1 z-8)aNv4whKBpa)%Qg<$Tn}Dda@|!B$qZFFMdjz!2npL!oPqpr-;Nm7eG9i;aYhdPy zd6%X({ioro+5gpxy#KeEs&UwT`SS(Xy`G;;A~-#7G@CJ`#o7H&sSWEY1h-HLAX}i$ zQBZ_~Ey(L82LyfU;Eewk;OEzXeKR{NU+V&1xw>D=*L@wzn!3RskD=m7OQvzuG)st? z^QdT>m4cuZ-lC&fki*bNbSMYWLFdWv0A7j4(s^MMKa>Dz`~5NeESu;*W9|o1n3#Es z;#`K_HlcPV-tBN^;~RLRrQ;18U&Z5i78`?jR&5y~b_Sf8YHVT+eg(jvbr_{V3#xK3G{2^9)JDKKsM2I?t0oCf$aiYnm3 zPSzKmTm==3zO*Ut|Bt8#{=WCQfKeg`TddTgMolXe#2{#c#`ZuiL`6;IA}Y!) zL8t*@aw1q!Lr(&n9-_3RYWrGCTW!%=ORGg{sRcpsTB)@aZPFFq6N?- zyYMCqPPGt8hQTQDUdajl?M}g({>j;hNu=XLt$uP;jzojc!z|n=`7!Hp$?Cqz(?$Oi zqJK7TJCrEH<7C+W1pc*_CN*+g-j;hb%Q8erj1>K4@}y=_GNpc(3Nz}0!qSX%)^XlI zT!`8`N6tu|u8-hs79o{pjpHt=z`L)J_Ji25!Mm)H_HXi9QZ8SjDo?uAm;-*}?Mltl z5})a^yHeYSspaj0->%ebLaIy;Seg8eTFRc$6xXfe#hWO`^c&ct>Q?cq>jOqC)eh2= z*4Va&Pv+fB#K82Nk66M;R@PHO$H`FdAKKL?PoeI|0)3CQ_w0N;x4M$AWMwpA{Nlq? z-%?>$*UQg#s*ZzkvM56Bw7)7{jHhmMwGq+H)x~5dB+cx#eLc_?S$s0nR8BQ28@led zv>#s$>SUsdrdU9u``omH42J8EznJ0BlX_#}30jKxz(B+b*lUqRC({tA&gbB(6{$PT zdR+RaB$Ixr?q|ek$y}0wKCcgU^U3W>-ODnL)!e&M15S4GY7fh+YM$Y(~C zn^wY`&xxI>+t1E$;(S)&(sj^n>KRX8!G^kF`XJAZ>k^yedyF3__)b+Y#0!qUq}+UW zK;eqi2>tlJR*g8a?XKTwmT)>oxlzuk6Rt8MsMmqm;!#i+(T-4S(FSf;Z;@btZ2Ul z&Y-ebn>>wL$n>a{!K-(qIOe5u^h*`R3>)Jji@!(0&Sp&_s*dU${cJ@rvgjdND6zY3 z_le|+qDWCdza|Rvyh@EdQBkdj@UjkzB1?ENPuRvp7JrL|v(~{z);lTOezD&7UKARL zQ@=R#lS$ZbSe%EH49BeMbQ=tEKAf8xLjjI?yO{;1--UyT*HCvqIXI)qw&{Tm@s=Kw zfpo%2u4NN|cJlmC(_V}TxgT@QAq9v%XE)0eTo_S26KM7n3z zeljLD%@iH^y~0{2MiWGl7he+`&MZz!lu zPA|&vV7?w*sYiOB|1{cfoVqKp_8Te-!GuAahmCMX7G0)+W%N_Jy_Dwd9Q_cti;FQ4 z5ZCw{M@nLkNuNoow%y4{`}w44+r5Zypm2k3oqnQg!vh`<(9`KD5R^zG9=TbPkpV^Z@hmYDN%;3SAUJR#> zZXkG9y7pO`#jx~HvGnNlJ7&y?rfZ>>Gu1=JJkkN{1!*>$w>rb8QVPScPr_fS5y`xI zs%5RUZ`#_C`U|Do$07^6({?6sukA|3NttY^72lWkLcO4@{kdI63#dT3@2Zx$&p4Qz zXDX-JF5LbK(gM2fC0fd)MN&tSJpDTo!qz;UmA(Q-(E{bEgJ^T3`O&kq?1AWqbPEX+ zyZC%<`&I1iK_}Zi4#MY{rbR*GYk^_Y?Nc{Y=@n{eSoFNu@Fwzj+DT9`j?LTJMwyd) zocm0T$!=;=M|M)Uf=I3!QAIOiV-08&7KYRbHlf|Z=eVTLn1}8w98YsU15gcLTk3>dHX={vGwPG z?LB+Gc*hRwTsIpi(^n#tP(N;;tQ4bCJuLZ!S*a={94lYYVhk1V&wI|{xRUvNdx!&> zY|DSG&o*6h;fO7$ENpI+2b%HBjSmrwWFg!afdL?O>T*+ni=H_hEA z7Yw&j|M)z%xn4IcPhAGrtYxJ-kM;(|ot*KyoLiKrDUSdB!}ucsJ_wUMKg@>z zZRse9WORNe(!Pmlgl-RGFQ+C%U}ksIMha=$eSBo`txS3;BBy)qje`{|&yaGG+2f*q z?<-%Yc(S}cPIJ9Y$?uqRNJ6QWZ;~-rSoX%{=U8+}p3~P#0M!QL;8gYTL|X66rX8zaEDvbJ4rWxq;z&2%}^@pX!&5&$)@G_yrtfSKLUYP?T({23K8Zz~^ob;xv8;3S8kvQcQnImOPLK^# zl0I20AFU->hvWK>j(PX5$G4V9wd5Ee`iPC2pJQVjbB2zM_>CMXhOKnKeV=QQWo;>& z15A^HW+GLv=1}TIYL{&7Ph0L^6P;6n^ZO*Qcv4Z3U>bU)NNMr+rjI;C{rVj)i~9{;cY-Z*Pan2Bk49G~DA4PDj+mD|z37_p{k$ z;xp%TYLczj?~k#qJzj5cf9Gkky4Kch`YT$j%d;X)1-tnvE@N>ipAp8|?3V5;N~bRI zF&B+TU%WRf)mfYg6!Ff~w$lntN~4w&yobef84;gk%;>$T9%C%s1R_!%fI6FPQ(DVS z3#dk~NdTf$)3-LXA6x}ys%=cT0`0GObRI-fBS3j-%tctk?=lnU9R2f(V!Bvl@eDW^ ze`B~hnwNfrR#xk)!{;@D>1Ejo!A6!-(xXXbux_H+jXN)~iH>m?el%<7aRg6uG0Q*k zhXb5bm^_m;3tU;y(R~`MI_7lb)N~5SZ`%V~*Sh>d!|MYxM0&FqT>|}6ULuy2bTF@& zr@u#F8RUHI{Y^WysQwJ1%7?{}_HE2Lw2-2JKh-MWIsH1TH+!4FNVfe(KVPdn)z&rb z3xq{$$3|yu)4>M_V^pPbCb05vfpx@hV?ETeROW+P8Q_*|a#l}MDXqCEiBEM-IwNUr zvbQdi&cuRGvsXLyijv)@d}RZC830!`R?Uqp+D3Bw!pB)ba~?=%EmqK&LjoL+IVhf< z*0#GxWbvaW(YVq$S+SzE+JBZwKv$q_Byv-C~V)Cbeez-0Mn9735DD^?z&Iufvl zc7ee5j7?mAr0GQ+B|JzE;UD(IZ%e4;nq&EwX5drvs%gL0wmUd)rue$oW?h%QMq`JX zwdr$a+>M%s#b+t^iyBuS^^Ho$;G=ic(YnMXzFKS>d271ExJ$E zyBppRuL|<+El1H%@rkWRV2Tc!8M|0u7OS?MRc!+hxbYaK}<^l4TH~qbAz=(W0Nx zBEbtd^b-#m9=`jKIv1ZW=ZyPHGLqsN{JKIUSd#Wb);?ga(di(t(-+WI>2|O^jw8e_4BCu zfW&))>cYur5o|ec5udGx%xI#zFE4rHw2LfW!hbz#=j}&shdxjKGT{fBSJ?4#xG&mU zY`#7yKSc5Zw!w+&evu_tV7j~fmOZ||@purS7qxVN_`b}d)aheQPd$Kx*Zw{QOGlQL$`VP*B0h*P zhQmNMe+C@fm~$m1HQBS*?oyj_P6&@V_%obbxK;=l7r&(&k~$BH)5zV%hn=a5v{J;^ zn^`OCxJ;}DWBrqEoQ)ACJgjB7O$wh1h#hcGHJ}d8=!{5hx z;>vh#biSr``f_9fADaeee?TxkASCtyEtx=1_G80|_jKNxQEmfLvd_$x8#qug@IfTD zg4AV3UT%R2dQR#xC=wOpL}hlH&?FW1r}sc)l*oB}d7TEB zVh)`{6M&{sDJ&P{O&greYu3u?ycLP({5e8B-xthVZB<9mS9=qKOO192nB$HTyHkgM zAKlYagpZWB55(Lr8I8Hfy(-lHITR{{*K%xqe!G|^g<|_L>E4s}qhdO5OK@-#R~$ua+ zDeibamhp4+GFCx>^BXP>L-ICInI=_d;odZ9KkgCENc#`P6__dRB~=R=(Y0UJPNLXf zvJhl4Y#~GE1)=nln@O+~p8=OQVrRXX^cv8IzsmZJ?gd z9A*am_F_4@@S$*C7+sauu+#5RVY{9^hEGwt^B<)-Of6OG?DV*F7-H?ZqHRwzpY;X9Z&DJ%rWK%r2X%TXuA>Bs(iQ&GUQ2Xhx7Bx-Ly?^=E zd8&^Ro7FNJ#Z=cOR@?Y3mr49GD}QNyrGPdtqYyl*+H5!FFpZF44CYa$dqqK_G2v~w zE-_#_!<}m1-)GZTpTjl!RM%nekVQ0_Wt1d=v=F?WF(s8ISeKdHSS&!Pk z{u+=yNIa>rbFT|N7;9D$1HIH~XPKkKcc!j@n5@9Ob*LfjaOyH3`K@irVm{KaP`90< zL-s4*cFWnmbsH_}rIxe4lRnO})3~+r#m%UQ%$qrvDRD80DSV&3;mb;>jZH>R#D)v7 z0a3iy^hH`KEo`NBPUgIgJs+z1jWG)} z#%1k5eaaRl4khL?lfZSQWb;AKJV{7Ns z_bipScboe$>?(6ML3%O8iWadvTZAx1iJ=D065Gu(&Kfybd1Trr{kpvEQo^dBKVU0k zuGwP8xV2GU(fN{9oY`RSi?3T)nBcSo>n6z?g%Ly(lh@yCpU#i0#`Q6d zW1w!-dIZm=B(ImDh{t12eBGQ1eLuIJ=$Vm4L)j6J(`HUQSyPmFZRjI|CWPezdCfNz z&>x-l%oBK?;MCwzM)C&lf2?`xJW}?yqs^Go z66NL?`n5fXC1_kBI=yPH9hXdEeVgDjHwLvD~8bwjNE{Ej_?JXgzP?6I-9 z5kWlMU-K}v%ReyP2V}b)J5*I*>xwtKTVCs<%ANM88{@3%93M*TPTXZ`#QFTF6b#--#}T}c z0J~;Ls_qtE-a;@XF|l7QWPAx>Zxj33;f~i^U!oQR7=)MH14j%~BOOgNiqkVvkyk6I zez6s9$SCkT&VD>M0c}0VO3ZDxfWaJ8m4kdOv3`Fwz5=!OHz3@KpcT^3u6q~t5Qdl9 zpg8Mj#vb!F#Mab{LEk2Sh$oW?p#$}u#8SSKXpXlJ@T#~tjNGhx47Lr@+aBA{6r?{X z425?Yu6Mj1`@ES)?2lhY+onjFgk9mP|t7%GG~XBqo3=N7NDs zmEBjcHT63$S3=GpgoGTHyfLNP7ztUVTgo5oMcQw(b0wF7*(JhlR%5)!^Sel6*!an4Gsdx3f{+TCx~MW^pw z;-VBlI-{MB27h`Lx63HSPCLb9pDf#IKKZGgtYf7wlR4v)Zb{B<58r*8+MvYdbqrL8 z5ots_BMJVnl`s;0lhU4zB-mEy=&zS3jMkO@>8aLq{r&ZiKGaqd4M@#2W%6#RX8P{2 z``2@5ax~_WH>se6(pm#sMNuyOK4Ga4H2E?#k5cW-Us`52FP9aRAtXdwP78KBxA0)5 zz@}(lCbp)YWhEc9KV~uwVSMv2b8Kj7*OzRv+Vl`45^l{!W^bZ%aEr`hJk5@@zo;5! z`_La1bX{|m7~9R4rH<{$@jp)^JsbF}9cH~q$8ESoRJ;AF7gx`$hIzj{N7RkHWE4uC zsDB6T>9_JhaM;vHO&vSdvVLo-?E}Yn>_yZ&Yi~MWp6{hXY&}hcDqmv7;kae{mxo5= z;q}OpBOpg*#c^X>(J(WooOU$w!7-4cJF|4gJ7T`5`{KQ~Y7u73yr^VOxgcJHA^=z#Nk&HGer3?{{;rph&WoZ2z zt<(ftVsz2@iJGQ_HS({Q(a)oaJkmz$DT$gG!TQ965@Kd1>;%B{I9ykW8)Zo>+$ihF zcVI0rI-y$)3=?3Rm-;hneC9Q#%{4JKZ2Graj)uwkd{CXbVNpA9COz{%Efo6l2`9Q) z0=e=zmBg;)ZkK+R-qkpP>~-mc#-euzIObaPsY_4I<-gB*OJ5XJt`So2XuTv)>6r!< zg?U2!N79KTM#L)W=)?i9x%N2gP%`Lt#ZQ4At7=pZX zUyZJI5@*^g{j6TIa8`q_xXmdsKK~L%#}0$E^rI+mmd4``7Wp<8tQq{-M_5)ih6K%7 z&QcxX1UKy*XD{4z<4`U)5z*nP;!{iu9)K_I*P2Onn;+e>%W$To!2D<-izkp(XnvH{ zi&}CtTrk}#zeOddev6jEN01pKzcVZ&zBX$>wBIU+O;?_Z{o-j9XnFb)YjN4`n_rmZ zg2IepcOU7}XMr>RP$2!d&M5*ngk}fY+#$%CG;!tmKAS}lqS;>SG`hvdw(hROx=Q~{ z^1->TAn0zqGaIDpMd^CH4ZiMTjM!VHRCS+&|M*l^VNZD14$J9g3QIlA6W1|M1DV4+ z6!!Zp%ENCNnwc?v)8)nlTZ^`!w=A(T5lxINN&kT;VUZrm(=1(Vl`62Ldr+&qM0Ufd z8T512@DU_-{sDjbd?0Urrj9w8_Lo#;&vVSv9X#<;k1`E{$79k{wL$cg4Wg^rN07c+ zmY475Ms~ZmCYB=Ol1v!WJ>3ldDs4jWeZLamoT{@5W9HtfgaiR@AHw2g`ffNUA(a&S zN+r)uvT6UuN=#boIN*=E(K|V-BvtcYW~BZ!mYLc5J=5Q1#*V42sWtDIK0XF>to;oH zMn>MNR!YZov3Sx?5`Q4=Jq}8oy8RtAn@)qboXSz)Xj`BJ2trF$?h`ywxeoyq*R|YV z*!cYpdoM&xxf+nSG5A;#I_8oasz0{f{zshCsx39h?}J_X$P7yD!ty`AwJ(-e(;$e< zm>lD>E2|MLrf>7Flb*14o`gd3(p@?IOG{y#VxUR%MHHMhj$ioC-i%`wG%_9p+gW{E zJK;}vZU8M9Z+_dzN0d)qj%3RspQ6+IICk5jPK4vl^9y}}%4}Oqzb|{^6W9P34cWUA zkBS3suJj)k{L&}8rICGmez&F`QerI{d=j`Q11z_(Fg@{f$aU;^Ir z_>Kk1@?_h?6r03PU0XbKUEtBS)8gpL;buSMC>?WOhQB>;-)-Q*w$tXtcHlk64~hID zUc)=FqDhNK8^MrzOeOwd#I=e#P7HkZ_4q@f5txdkDQ}t4X+96kB6V4U-J$Fdt-{2r z*nYV7Pq5J{^@G1NaBiU75iebN3Lp9Itb3{Lz02qQJ+k_#J*D5>g?BISL*S9s;ZQtv zRYfrV7cagcG~%Usk7?H_$jU{V^Yfz_h9_@TWmz9e9Rnp5?`}PoGG>xwql~EefWlYV|4D)E~XkTyU zWrI`W|83fYElY`qVxQx1n60T%JE>l^?^>@eO5D8`B+weovqps3XgyWPU#p{HZyii2 zG8h@@SU}L`xrt5!5RGz;x;!qUd9|KiMIE$N;Tq=9N{JTh7zgTPjdis9V``=}aUy}C zzAN=j6-1LM%ZFIvh*fQ1Z+pf}x7h_9vWHUVDXSXa8V8eHRi-#t@8C=WbDZB<*R6d{>1(tTSOkp5s$_OTie@>9M;_0r3TBfIZ`W& z3@aPyN|X4UCAHp}din}F`$4MnzcCrDDX}Z{(T?ocvMbd_$U0s`oO9mk7GmnbvE?^D zjyu5tE6#+g;IV1b^@1Bl-H%`ayJX>EjrtX#0eXMixZb*k!I6QS?DXS2X?h zSgH_dp9<4Vn!saPOY6H#%l`kw=0kR8@UBGQq4YDd03DiS@iKa6$dD3B|32qQrhq{D zr#aEA&cQsJA&_30`y_)Zd86L`>#XE`#28=f8XHP%XnT*ZeP2pyK2H`|t!DHB8`9_G zWLJ59#vnE0UB)jYHl)9plO#)QCLtv}M+pH}!Uqg@c_nNo;~K5wt7ycP+Zuj@tfH zlA`6U+VkfS)=4Yz&+F#vUk>s;u|B@~dXCk1|0THIRKVI&{xMfe)4n3hIIYcx?u^q~ zXe^a^ZsBev`bEv9r~~2YLDbB3!R*Rd>Iz7)#BGp1O!=KrjJ128tXpDN>KUq$yj49D zhP(H)|G)G53a!?#AEx7Zob$9zeobg<_o_~mJHN(fkOyLGAP6O3UjXNni)!C|9AA_) zzA?JeDWp5v5bh+!o~yJ!y4{d~AZR$CXlcwsLqRhWdQy$alMd5*T?ItrU)F(oKbrzj za1*5to&$Z}oXng}YCA=)hOG(F(76r#TXLS+i zmI@a?ZkO3R-D=razr^~5fA_p5Z{cpwEAbMym<3Dc~$FMF>K#m&Yb19J(K9l{QX?Y!L17nZc8z(s;(=p%RF2w=~_`h^ch5ju(( zPI}g%RiWRbxjYQWvVl(|)~`?Z;AuJ0i3fQVY5i-TjsGJ+%xxxS{cF7lu1_7s$3#1x zqJ(}#BfrAXblqQy&XwTOlWjVQs{B zu~c!;3Dkb|a#JO&<>jW3NXPeiPM|;O`SRjgQ=YyAI+zIUkEI2W#LvI-(w;p%29}sY zL<`^3%rlqTPG|mv2&v}e-bl{A%6(tW(Rz0&T)O9Qf@}qWNLiu0J59ln`z9QXedLQg z$q<7m=i^GXrZAec*t>${BQ{)lDZM$my?^4t&URDV)LBn!V2ZS#gEF46j1(9$Wt|f~ zYVTLjcC zUmGz4=bqMnNQ@BE42t0uHtrN5nmeodgwn^r30Du0Nj*4Z+eqbZeY~*S9s+qUeHZzh zAG$KqKJa)E8A|_EtMF#ONIp?QB0SrdQYLn8E$6xQ$mNr`l)hPu8taFe`F3RWSM{n~ zWc4ibiP_fze`*`S_hsXI!q*E*WF9j!ggyWD{- zX}0rfE$JG0rSDy$S;?g-V<7CI%daHoy~jDOsfxz|C?%E6;Soxqm?8ko5DwUq>I9%_(ywM zpMyK;Z=$w&Z>qiY0}_aNaGsEql|t#SNv$t64SBzGLHvyXbC)Uxlz!T z_`_=xt41Wf3ZH?Uvi8=)oDoj=NgM_w^d8Dr$Y7D`?JH86E$;?#w?%5Tf?v>Rwgvbb z@~?i$*m-L*s=4Vp zlui*De5O(+-NGDvmna=NIh(GSfGsyS-6=|^DrWF;Um)F~8TwHAhPNdJ)BTgpjCu0| zYhW4r;>ziK@4r_%@gh^M0+znqbl+7vnMav)+`DwHRr?T;noT;iu~ZUDJURe<(Qfqx zjj)bEi{LgAs!fI-N6@NXCXFlmL^>)nt;ZSju?&NI<7-DaO@8KJ|D z3F_($5$#tJ?5qv*!TI*m6mh)&YJ2+1aO{wroKLm(rnVcE!X`u^ydoS}6RY@?wcl(u zja*KH?58Nq$hg+3db|_$omE?kK(UUz>=annBl64j8UC3;RUD19j}*>HrS8nYv+lN5^#R;?i2h(=!SW-!(#vvtZGLNO__=p)4L3~95-4G|gy+Et1K2K?pR zYUl8n?SrLf6R&l;arxJeYjSQdF4{;M4zn+_NG^b;$m&+Fv*tP-$N8rq2;ORYzk_3t zxNUoXG2a8{rnBayip%HSZI9e6)>p4F(DW73t!Px*vjkeO$-MN{=H2${fa&mTFt)xM z-f8c_9@49HD)VkWY;DIo=qaB!nDc&Dk3zd&WRh+TJQ!IWte6*j4bN}IeCs5|+BsHl z=#~ebFm+g5p_-xS8m zE=y0P0P`$;f$l))7ND-g&FoYm=BjG>X$mr(s`>*4FHI?7AE#cM-!=N~@U{#5Mf)8SIH zzLyLN>O97v8UC%#;fq9R{Cz}>S?Znz2M1nEvu{f82l5GRb=DVk2pAiiDWQ5#1+FB9 zq&@L%xRTnakB3u>DL1b{9Q(Ut38t>`OWnSN458nt(iNYHt*kgKcAI@`13%#&eI40b zqkrjX1W6e%Q5BzQ{VNpQ494HdO0+q?q8w1*zHU&K2_jRRzCh5Q>bUNPNw?H!hx9A> zu$*Mc+~-yXw8{4wwt2d4N(X!zRGp)WT|Oct;e4hu{bMkgevq>A=G&Xbhze|ptnSnH z9`;e&d-Ee5pA#qMhs0ox7Env^9jMMR-`a)PO=QCp`*vjCyaH;hl~CgS#Lj`+X~l8n z4@WwBeSu!nh~xRq#EW!8%{a7ezrxvviTC~TyW8iTEg>-N8u3u;8O$`Rz*0oX;U(;t zOY|)@+Ck@2usYbve*LpUyoED7P|i9A`?vdv7H$*oZoh?DTvcRsj1SiGoeHKFXVV6q zBYA5evgq%hMRS_i>+d29Rh%e^r?@Fd)$l=7G{FI>$qxoXc4Bx^>Oevl`9@EWBwk}) zq5kR4L&>hos6(b-wyh+6uAjy!KzfN*&~7ohQs(=54tt?5+Hom%Ou`>_jGA0Y26oXh zl+bpo2rz(;0c55p53$GfcutrIBsSl#2a%5N5`1^FWPu~!xKI3P=(_dk;5!cn-}<=@ zn7}HDZw@j*a=^qvoKsFhYZow(TeOMl{<0H_{BUx7eSwK8>Yc1||CHH5{cs5cK)OhXtK0zj`rcvb(^ClM0uN| zrTiySU1HDX=y3C_hj5COY@u@-&NVEZiE**Hx|9LV>m1+T*jyB-Al6K^rm#G&<-eC& zf~FVs%Lr`pdj3{zdjBB)#jDGDZi)uRZ;A#l*c1&-*c1(q-4yMS+!XEkY*Mf6S4Uw6 zc&gwLpaM~0zzxN>eGp&QFHt?1F{ZyUp87?VpsJLKoPj!+LE&N-E^^`UiHZ-G4gjQ9 zJ&)00zyIiZyfsC&Gc0mn<0ICitu?;LV&lJ;I*uI&@jVAcZa4`|VAPNL zxf|BI+j1b+1kLLV-yGkdnJ@PF58wE3&xn_!sVtVM_UYq1@12bSz6r?< zU8U}w$}kpR5P5T2C%!?0cRAT)#G#tnMHWA-w)Lq`;WL0+RgsP_({L;yRQ?4E(^%9Y z(m;)BCK#6a?CjNq4(0qTlPb#?^CTx_PW8df3jwJYwZdWtcv`&Ub_9z4T-Rx-p?jA{ z9ys@eq3@79OgclUT{c~xJ|^`;Ue%MJOpusou^dUzZwpH@+QYPN6qvsds2VxqQ_I*s zkb~x}V-Y*IZ}>M)xmk>kJ<30}2ixvQYI3}B8}Ky$ix@Cld?k^p`_Z4VVKz~QiOU|Q z^bYyhm2ibWH_GfvAkU-ZLEjC>#cV&|tOdF*hv%bpSq~ZDw@TiOCLFevb~B30UpE|= zB|h{WH1g3Bj-l^x46s=mvqJPvWv_6geYDkh50ihW_}p9+qqz{H!{OLq@Fj|@ zECC@}dxc5}ml7d4Nv$7Gr?4L&-+YWgyNhUeR1OdvE~sLDfiVcpQ)pzm!+coN@jQCG zj++Bs@3D+?Wk>ECdo=E*)R%ep8^i}$#Em}UG2DQ^_T%A?nd}F+9)iHx)rv0Sc!_aE zJw(Nm)q`y>HT~JDUYL@n88iBFuli96+;7Wm&#IH~A)@L5@m-;7d#n-W_%-Fh&WXWm zL!A@Doo5FUDYSp;r<+W78o8t&p4!g3K;V+Hjz_LN7TtbvXI(IU&49qQeNpn4cGiUm z1g|{^Z9loQF1#stiSR{k_z^oBHjN5wKvpElYQ$gCRq1VN4k{3hJiYU>|$69d#8|_ z!J!zypB$LNXN;bDZenLxyU<7S_zQ-^;_vxX(vKc5-0h{xk<4apeT45fTZFC%O7K!! z|7iMQo60%R^}qY2RN!I%KkeNSVgx;GX0WMxmLKz3siG|_aX@5PS+S3F3v<%-RXRl! zaKOmM^P6VJtE3Yl{?3*@UWqF=<5JVeN>2>u;(wbt&~Ky4hZqW52|bVcHnP-e>k+WI zl-boIsu-vC+u6R|y}l|Xr?xo#QmL~&c*js zo(B`ka$I7$BgUPi^IN+&y%&;yCW8_8$)`cgC>Ft~o~ZQ4(y{q(j2Hd0V3!#utgg#g ziA=43)O5!}o=eIcMwxVm1#k)>-R~Cse2%iQuRyom!V+K?8qU}|4XBiM75-H0E0A;B zV}=|P^L*^sW&3?4zzvdjF+$NXmk86kST&d~vY1TFfuHZ>cl7>u7<@|&zDWC1Kydc7 zI8E&HvE$jVwqN?JS$e-UUQ*SlFUvw1+XzP=bI8h8?lRqm2d3LlWJc_N&-(q)NACX| zXp~7E&)9$a%(R3|wvReB8`daCKG&B9Tw;+T{6c#50U;fx-3J*PwY`%}whT-YLpH#c zAtF;7d6m*u*gdzd_x)D*aaQD2VMp6BB?nUBo5*zkF=R0mQ73UdhnO!xjNcOfkK~?Z zQY$cL)3^iWi@n9h9QghiD}SAKi81w;9~$l~cVhErD>hF)Y%rVH=iPTn_P3uRUv3UX z@IHy$bg=yYvE`;tdkc(iFDy4ZFUo711CyKgS$Z!lH@1npG}Thd_#|?(oMJw<+)O6Z zzT{@lg;}|ojwZvpxLGZ{Csu{ryt&D=u8H}$a+7*mXZFz6Lic?T$8MLkI<C6#Q74aRH2 z?4k|F&n+rSp1S?>jt)^!1`c^l5?cp>AIJBF;l#)yYB9X?g20HsL>8Y%i6kgX9^CPW zD#&LR6hjr+4#W)hi0vbjwc%t_apKW;p9)S0FF8z;me^pr%{vcu8a!}-* z#W^cP_`SDK@uEckQn}>09bi}MxC#6@@Lu|LxUY7_$=<#O94w%Hmz_ENmV}a{Xwe=6 zx5iUF5@L9d^aExYW>g@a3deWRL@P*t?Tk&K6b?yRgH|nC8E8F+#wEp|8Y6b$1A z72o9x!7?KRV|^jmzF7T1o}kJPXzY=yWi-uOXgdFBQz-3_r7xiv(?E&C(!AoaC;Lb; zgeXBO9$wa#JW)&mxOnMj}uh&w9`6e~3 zbT7#=Y9gnZ&}aT=;agwq`oR05JrXXHX}9!od>gs*frF5%8AJ6pOK!btYVE})Zn4(-l;ycBo^XB22Oh~J4E@yM$;4_m-r;51FVLy{?wt5bh?rFeBOUazt2(YW*IjHmaYrV zJNfiBSh~B0vmUC{4vv>g|MW#oe^WcxqVL9-Plo!Q?XI7NwWh2yr*n*)9H&L?u3(foUi_!X6_hJsA7!Hp`N$;bK|6<0a zF1VUhNFgUNN7{!-|yC|}-Z!7Octc`n_x zrda<2t$Bw&`)1-}zm=I7X%FxX8d(^->6kJXbM|ee|4E!J&Tkp1jqa@2!W&Qm)dp4v8@@W9H;zmj|Ca`&Tx_}e*+aN`QmXmX_ za^mk#AHhd5$eU7L`IIs)DelcA+_2d!U{peTx()r^O`;(v$9a=FQVDBG=#+S}vY7W$ zj%1S*!{oNW`t(6y$nKU(eX|6*HmC2EdP}8tz-}_mL?q3cLlrkMeIIv!^W5de59@bM zea}7pkv;*kpZ?d#YEt?L4ODwisP2)fRKi(X_w2C-V`tw`B9uN>OX6dTn342Mo?V7veu@m4wAVD=}KKOV(&ftDCRJ zG!jD|0_WuVumAA{O@f%;wT)8n=fi^5uCEhCE5b2otlF2?_(mRQJKKPS(i=l*l4Bhuh(9x^d zmYmo+a7*Gr3LVE7KjJ}#A|cW67Q;dtTx#}B_#2ho#)(MBM}ISW?a2ZPKAJKA+8%AE z&yT&KTizY#DZCpq@O}2vo4p@xyT2_W^Vlk*U5c{PeDmDAjIW$?r~TVCkr+ zwoX3-olcd=$s)e5|8RR#CydWL9dE#uQHl)n5PUGg) z)@i)vW&0-oDqt7Karzd;lE2=P9-%n9Q!uYz z6i{NnXGti%2yrb)gky*!v3?89X_sw?n-qDUUm>t$rN@ZDG*+3?zx%tds9p=Q+a^7a<*Q8?z4HUV zK0AFWfka<_cWHGAM!~_<&~3gM>_5m@==K4{-zJ*x*3nVu3<|;Gk z^!w@&u3x1;_xzqccW716=LBD+ab$}NIef9|3?Bc2?Qr7j{Ss8RQAru!t^0g`Q3WPM z`bOdt>-p?C!&5)r9MKCScArOf&HTjc7)M@w$ux!>C2WRdtiY7i^rX{Tg6wdxJ9ksp z%_H?MNo`p+cfzS&`~>O=`-R{%~m zl_~a|S<&W!RcpbvJr#Q~KL*o@Azl%>G*6inJ;) z)5-zpOb^LTELqJYcFc6;JZ(3$ZzYA@8wVX(3)S^^3S~pk9VAVEjczHw4d+ulAXUi` z6_Xf{+PI}xH6=CATWU7Oyt|pWqU1&Waq4}v{@=J01IfPkn4JjyBkgrmmJB*)R<@QA zlfZ-c<>q6>loG4YMl~e|tZBRPX7AmHR1}^&mB9A~$Lf>{^n0vm#Fi_K+apsTcd~MD;>i)~ue%^wDGygII{L!oSnWIA zvnAR89wxT^@yAt_mc-71>i(S^oxJC%&c5;&HH~wzvaU{e0R*Uq&Pj2uD^ysWzY7t#(tuG zXqqvmJ(zcsY$hcvxZ}Eu_Pm;G=^yDhod!VZdqsZ`Z+U-B4N~zy#~x~fYq7tAu3ZPw zB>iZl0VI@frw`UxQ{Wk125ht~LtJ0d^uJ$?g%f~{$k)nyTgHk@(TMkGBKFMdy^Diz zUM|t6nz(0SLHB2HpXzU$P_k{E!L-is{kBfc;KUzkoinL- zF}&|X2QD}KAMu}D-iO5dvEuyz@qUcuz2rNwdHoxa_^W|*3Vn~hOKjSHkMToS7N=V> zyna0KPUqSa#FhzThdv+Q(HA{Zk__L9H1tR%{)S$ux|NfFa)xht_}&k-J`X`9KT^i{ z#=aL{x@Q}NhLfZEheq`ajVjqNW10LRo(@=X_)T+`z#nr+1_Rmk&yj#Z?E0sGBet-I z=!ToQTexWt3%8v&>;J-+Jv<`||E2$t_B)mCt;jci3{0}Oh}?T(O^Ns3eJb$MvCp8a zq?s}TyL$OzvjUp}o8|v+DN0;jjQ@XQNn$Hp-H`aJc`slY z5(Pzjr}g(v(4axlVKX>$alPG?C@li z&Km1Y8*oNJsbnTmH{h)eZimqyM49kIduEXPQ4^8)&kx;xj={$ydMgJ+<5-`_G_`eS zvaV0OqEDdp)q#i4SIXy^xz-jZ&MxLZJ1WZ(7Z$OOK_AiNz;Xi&tqKx%KP%YzpnzHSXht%gC=QH&3Cs+~>LX zTU>kk(0``zjg_AFCYKL&uj^A)_Ihok=XJgOv_AabDbGUa{uP%Gb+79wcXh4HCkY3u zc^}MO`^tX_X}UgNNL-;y=@frE*Na?7*JRWAae6*+yytBj=XvE^>&9XXobP#UTxDF_ zzUp~5bJcM@OuDx&^}HQi|K$1`*E3vOxE|s95m(c%JZ~npyMOg__fv@XuL;EI^234; zKfybgk5eXa)dsAJ&7ODXecV4}uR88i#IJe;$g}8r@?!~YEc+@p-gt*)*NV-DT zs?PXO53<*?F9tkase$&20(GSZ1iUpT1iYDC1Kd^i`GB{s)Ltb(T@y%iF$xNT^_+sS5=l9R}PqP>Xrj!-ijcjsC@@^gi_S{&#@ljd+k-SMlL* z1A^Y~xO}L4T?^c`>-eD8_43pD@PDT~)1dooE+6V%*HCwLt;;6~2f*cD`^x{?3Eg@3 z5^;qt;ZgiLuHSGSTbfPh$LaajVL`8U=>NU`|Hgwh+DzAc+D}(4SHDltmJgq7+g@-b z*L&n)MJlcDV;o4g+J%Ca7tqJbZ97(gdy0Mv8hODQM5e84WZmfDLi zzI4M_lRv(rh_4{zXD`iWCu@+bA+m0L|>3`44W)#PwTe5@y5 zNe|vRQND9}msQ2XXDo52hE?|xO;P0& z)ITE=w7&XCpOzdcuzjhKv`Say(#C_ez585+)W8kN*HY2a2l{D4SHD`ne!;P>f}?sN z@|H2R)Il=5k$iQB@qU@`!k3zO51X&HBY0_si5I)O>Ru{q7kRdk=X_gMbWFU*Ig7%z zi$mnOE|W5Nzq=J%jZP>FQ-@FQzYVB{H;J^XNP9f@`bnRt-)$rAWJRc5;-Rw_1t+T? z82rn4UeXs`YUwJeqIKgv&RP`i2nK)bh#3trgUP;D_&F@)df_s>N9V*t)xG-!XV4)L zKhq(V+$-VQLHa0XC0xM0%06>(usR;DSrod?$eHQmedv2DNVCZC1sNN&D14UTOK?Yq zfZ$|zt2QVFT`l>_5cX#+Zs-nzxF#MBUTy_$R4-G%Cerm`_uQ!#e_3w*S{=?RSHD|G zTgR~(EFXy8675bqVi*j_Yd554kdWR8a$>QUrFX5blvuIn=N1>etJsa{nf}uA8 z4!f1xU8HR~+ViHt6O*=s&e7xS#UWT7ie%GDzDm(2+m7?RZ@D%Z9S_%1HwdY>grGal zwUkgxD<>1l(*|SAhBw<+kxBR{T6*~SYkO6ZzMZsDD)6esUxzG`7ShMk=wHt;CDZ;j zy&5ug2~M$nK{EX~c*?%$c}Mwm%4xgM62HvKUcon9_A@Qtv{$!|cW=&iZGym|S6rL_ z)TM>T8jrN*xZ)(w`!+gDGS?9_`ofHJPQTU#e_cRbjP4Z*1&QxEDvjCq&>fUvsKNiwwmA%H1rB4w$_A8!u6L`Aj zcjI_d=%qsW8OVR`$Ja2x*SG=JE+Vg%2$iZv$tixLpyt%u1pniTEc~_BF zR-N)Ll5L@WUV_@sYFVjt!-JVi)eXd~B;`qH*d=Xl;M#t`~O zZXXRD=8F*>U;NV8we395`$&ZsDyzEpl;AT3%Bt!WI<9Adh6is6sBRYCi& z7W#FdcacU_YmclY&8kc2?^bT>&?RSC(WT$qn&~3rvl49k=G)}+CVSpJHecE3oN+WW zkTU8HAXy17_N|-ZdAOmBo;cH_J=2W2!51B7r`yJmcGWcYIyt-=pBIN1Rv_n!3^|sD z`K0Yr?{@Q|s~p~rAUT51yTm9$$+W)0yrqG0PI$9C&Xt{L=xe_086>a)rl*z zA@gLoEcmZH8NMnj(5m|i@2Hq*{*b1Uga)7~O#HPL@cv+6jsIT2c+I1c53!s1J@WRM})4fwd zhZf=mMiX4_#v-g5@i@$zuiH9#0XCyAvUM|fYtfn4h6*4U*-QDW$iMSj*i_ONrj4@s zGrW1U5M9;1G`_Yg|8mcJ$>qm%P#ZC(m^KRiF__;X%Cm+%TW&%=_L8TaJZOqyG_h${ z<=H`=rtc$*t_>GUk1mp}%7Bh`857FSqq>#!hBrU(yxEz$8TrfWd%>3rum;{re@r2N z-3s(F_J);v>L%S?7CNqnwb39kY}#QdX_wtjdt_wHlx1Yy=xxc^D@+zOhH8lM=a8UQ zAA6kqD^{|9LhV@Ddy2KKG?Zg=O!O6ZWv|e8{rj_x4IgGhsP_x{2ri-r19jghx|$=~*O z>YUG~-28Q+d4=+iGWzgs@~?XZdCM<9*M^xAx-eXz3iPA13q(78IHnK0+2MK9Gkm1| z;vtFFnYnyaU!G6eK07_{yO}zeG1}C@x1&NA6zVf0dtrwcAfNlI;}7fp*s$xa@8C1y<3?+KNH;BI5KKv0o+dBmj!|o3$SfuuO`S@N&d36 z0q>tBK5g0lVsv9|?=6AQt%Yc-?G^gh!37bAZt77mo+6@L{rjT-UkrF}9OakUjUTH5 zp=cqVntBVz6max;Kj0mj->#-z%-C2fo~}J)Uv%6iI*Nl{#Sz`=k;VFrPw4 z9a(_xQN2PxD%3wS^0Wq8yct37|8aI*uD{jrwUYjFZXpz-jGo&?{uP(8j!_`Ln1TbIAVncV{Vh8uYt0(4JVG6N^`xyMEyJ_zkA^_*V`R}r$clQ^|=CQlIj#yiKPY)H#hvtv`I0b|V;&h+n^8ybhi8s^8mA@x&Z zQ@tV6T3Wmzifo>1Bm4wITIV#*y1b$BDju6hLN;{BaBs-;xwB_C%mKrkxv_>Jqt6|G zVoPl5^vf-phMALRG*6w)4Cugr$B)vug*9C3w+39f`IJsS@m%TsblXU`To2r@#KGY};rA(0x)Qxr>V72-mH~6i z*>*o`d_ygLGAVufqTJ`!*Xsy+?Zo*%J=0G%LN30EJAy_=RbQDyKECs~R~`+2`n7}a z3-;FhS2{hv)Irgy-<_nBy7Yfaqw6vU{rJtK%l#>heoPTfdjILeq#Gc;=YA?zzj<7_ z^_WRLN?^L`!89pT52;rm{48`dLA}k&r^z8E_NH3xkVlKT5nSLbngAN zB86)R%h#-SQTP(z3c`|4h1DKg2%qV~R{~2AD6P@xc><`P>K))e)27V2jGpKILS7H= zZX*137d>A~*k2n__-SQ;dBXq-zXcS3weF$tr$FhiZ7BSC!v6Y&!fe^itWzjlLwGIz zW~Ow6)DyD55R!Z@&-IIP1qn|jtote#)+d5XXi%*+2;Vn={u+Y9Ny7g6fWki^?EC!{ zzK^i)+gJEerN>55e^L0)gnd80!fc_+`05pYo3QVTS2zS8e80QGhY|Mu=?V`g?EB3X zo=DjDjVt_h!oKfY;p++e{%wVCCG7jK6~3FW@1Is!Cqnx^Xoa67?E8`xevz>6BUU&? z*!Ke~{4Qbrth^wx$ffT6@L_~~zpT=i688P93ZF{Y_m3*f(OVgxr^4qGUO*C>oKV=C zMmUziANH;w+>{f(hVcBH@DjqlPgMB6r}XDoAE&~1688O=3d?Wr`yUm4jIi%(RQNf< zz7J919fa3Sv3^2@-&6W&))%O-&O7k^eG1D*@B8!=KAEuZqf_`C!oF`!;Y*a?`Og%N z5%&FJ3V)NZ@8?qZ$9lfd`l}TFHDTY+q_EbGd|#5ne^LHU>jP5wAB26Mj=~=(%s?g| zjlzBDa=!mX;V%;QeJcu&B<%Z56s{xe`#}`GjIi(PQ208+zVAZem4tO%Af^hT9^O5K zeIJFMYpuukLny5GE`6VZ!XFa$eFO?0jv?UB`4!fhjz3pdcm!d8KCbYEg#CH6!i@^M zd9lLt3H$S0g}+018}vpUy|*j9n}h24@08xnCl&rHVSm1-u*cx*&)*dOf(BzZ7gM;B zus;V-crsysKBaJsu--`*vBUzhNPF5$m+32*Nb{!f>1PsTp~r}}Em#s4Y%1;YMZ z>r*WJly`all`i3$F5z>#gr|22&s5mWpM-xNVShgKDO$9Hus^@i^W}v7IgG+TBka## z6xLddKX+07KN0qSs?W28{W*!AzfRbngD4!rhVthh3VTh{n;Ry7ZB}eDQ-h{ijSWMl zdo7I$&uDIF@FSbO`ni)^V>2dCpW4#U*wE54eRh+grcZ5boZA}nlz#Tq=`&}|X_#y# z6q6g~H-M-iHu-Cl=p5YH6N2WatR*G7y?6ipiqT^v0%>62$S%%0nPl{dA%-Z0xeGc=3&x#7mC(;6C0N^>`v zJk1#bCeNJOI3qXpjHxZL$;=iTnwd9J+otBZO+&s^)-6eML#(xVPHvi^E{(VhiBlUV zPg6@|v7GAaJ!kHm$SbIo!aW=@`VRjk3L zVT&5vu`+F#GPh}{H@&Hq>b6XtF2?(TmX?N-y;*aN>@y9v%|E=%n?AScs>w~wv#y*P zYnW_i+A|tkTV^8ZtQQjFb$Y!c^W@wrs(VhK*)aX`$#WX!HPS03^DYLd zrBUl$NS$KV)JCtqA=WTGHrWLc=GgR^RNSb9$@O!Z8)mo;?DE-u*F1I3WeqKkf?;%n zsr8dh_c9N>mdj@~+3+-+3@+Izs0E`5nj5ZYrK`XgLtQ5GmnO%qYVx^%Y8Gj^iT9cs z8ZNgveDXw`A$ZoD%bKRfL^lmK_ev@>x0(EsPAeq&)q{o24Occa$E-?m^o_8Jt)*c` zYa@KLv8R;zu}=HB=%I?H!_#_}WdzZas*5V+Qkm9r(W+ayiyxlbW^-7fhYTB@i%UfeJ=GyYvAO1&ZyP6%C8jUWnA<#WYID6W6kcBBj9JZecheNJ zr_P$wI2VHG{PZ0wNi$oTrcQUwGVGL0VW?j?NdKOGd90a#nKm%uH*aop{j|BQbLveW zoIZ69{itEatoenCMiWq<7H{sH1~mE{qmFDpR%b^15SKaA?U*#RxgkS=;X+pdu!1Ye z$czoS{BS(`QU=MsQk|MfHBB}2+d5NI$9Bhw++s2r^CC?@hgnT-c*~@6=$q!YtbQ|hj5jkHnyrB#t>sNN zwgM_gWBg?eL%T+toD)GoG<{1>jBh&7kf=9<$~PZSNzz!er`BIN3*u}!=haPaY?yOd zY-R>YYz8V|>a@m&;WqnhqguVD*i554jJnlub9t92yrGJm-8x5Ov|o!RqfV@%vT+c6 zGQBh>#bwh>c`hc$O7a+VsfU1}ykRy2iBEZb!;Gn|jp%dH+TzX5mMRQpkjPkFCS;5E zjjo*1G=7@lA)7)`v8l~~tm$SADa(zPt6CUlXLNmN8qk!An6hKrn0zK*Hl-PwTIaO3 zppugP+5(spsFq=OjGeI2`(6 z%E?Ta1>fh=^QFv51)K0K3oibmg}nz`c$S0rIQWBM#KWUconoKgDJWltgO`8F;y-GH zg+Co-)74i2sn`9Zf$;MWz#z`VEiU}LgYP@ox7McnEHKFaoKsym>fpH!#`L_6Jy0%u zmxIakZ26DX+49>iu;KEHExgddYaP7R!CyQ0goCF}B0ufd69=ixAij|ge`dq|?*Nj&&cP{y@GWo{*Ht9Y_#DKPXHGpM-G1GFE;%uLGbi(o4{Q0XO<-gR^#_td${w+b`UtsND_}+JL z$svSWSicoSPFH^h2>!lD0Kt2#Ao&LflK)zKB+9?0#DN_>@BJx$mEJL=yiX0ZFvxpZ;^#16ume|-!lXOsOF;O2go79GZkEz@0F|zs zcZQViZ-S)zw}bEV-jMMBgqIqEi=gieo9{;s?sBl`%Qn7LkbXYN!FmV34%gHpLo8FALd{=PD_XJSk|8lT#JmDqiZ9&S} z4pcn{P5>rYF9E8&OB|f(V5fsWcJOCFmG{*PfYg6AP<$JYqh0vwCs{nFUt-}4K&5M# zN|m9t+!S7Bdo!XC=K}63HK$SO~^7EsYjtFbBs!vpK z8SgCs^?ZpS`By3)UGxhVe%C$!K=JT7!1|)n4|4EapweIL!c!E6o@N*J_yuS`vKUz8 zV6lVp>F9Z12N`BexW9uX4wgDNz`?-|mN_`w!Ey&H9E>_xPi-Rj1yv@Ot4&LS9 zDhKa%aE*g&9bD(&Mh72u@NoyXIQX=KTOEAC!EFw{;$X_b9S-hv@NEZoIrxEt3L6;{ga zsACh)5itf%bWrbE;gIgVZ!NF|~zT#lY z!5t3nbntBlcRBchgDfE#zG)p-{i(>oVh43Lxat26_H(emgC!1Xomc4wI5^nBG6%JX zSI^5GtZ*>uV3mWl4vulK&cSgGPIPdRgHs%=cW|bIjSe)<*EH#+#RgO5A7#lfc?-0I*94sLVs z6$eue?r?CYgKs;y%fSyE)WENH2|K9uYlVv){D0XyAHXWB`v0Hj?hXb_?v$w$r(E=k zBPMJ*b?B4RRwG7%Mp$%dQmU*itJNQc{$8?07QQBh%0QPDT*M?}gu$DaU|Z=s@5 zQca}X1PhB06x;9pdCvRnKKIZ50YfdG&z|RX&gXp2=lprj^JmY$n?NR#Nn|qVC4FQH znM$US8Du7zMP`#ZWG6w?uDRrVvX-nT7m|y~CUOb6 zlw3wGCs&Xw$yMZPat*nTTu(NWo5^kDc5(-~liWq_CR@n8WGlI!JU|{K50ghp70dNc z#*y)40x8b{NdF~~$)uO`ktt*8BlF1uaw<8EoIw_mC1e>{ zMf%CP>z|AxWxXYnUQ(X35Pb@nN~Vz+WG0zKW|KK& zE}2Klvu5JAfSgKBBWI9BWC>YDR*`;Ep63vM^T}GWo?J*SCY#75w=oncPfnBe#<~$erXaayQvR?j>8v z{p11iAbFTPO3K4T(l2f@j+EzsL@)123lqsCGMV&}J~D-r=XxYx8ks?6l38RnnM3B1 zd1O9WKu#s6ku%65Qr^Foa?8jn(of3sLXtk8tR?Hoh2&zgiCjW1C6|%Q$ra>EauvCn zTtluS*OSfUW^x<3o!mk0BzKX!$rf@i*-Gvw50D4R!{kv?9^sPyaFcOlJefesb4y~E zL?)A7(nqF{sbm_NLCW(@;wOugXM-i4L*|lsWIkCyP9>+2Gsq%Ro_7*|Wn>lUC+Cv$ z$y&0WTu3e^o5&^PQgRu&oLoV!Bv+BE$u;CUay{8hZYH;p+sPf|PI4Eyn`|NXlC9)^ z@&I{|JWL)X<^4hFFE<%S#*+zTBAG-cllFZscoep24Y7r*n#TC$#8NG>Lu$R*@bav8atTtTiRSCOm9HRL*S zJ=sidCbyB>$sOcQau>OqY$5lOt>k|40C|u+OdciWkxhI3lW}A`nLs9zNn|qVC4FQH znM$US8Du6Y-xQE?vq^b5QQ~+5$z~pzPZp3q&ECy2jPGL6h2Gs!G6o6I3|$viTjEFh&?e_3Yki#kr`wrnMG!kIb<%GN9L0S^iu99n$@ye0Sx+t` z7n4oo5^^cIj9gBxAXk#B$kpT;aviyzY$i98+sN(Y4ss{Ci`-4NkbB8iazA;1JV+iU zkCO5trM>>iI5M70AQQR%fSgKBBWI9B zWC>YDR*`;kE;*m9CF{wBLu$R*@bav8atTtTiRSCOm9HRL*SJ=sidCbyB>$sOcQau>OqY$5lO zt>k|40C|u+Odcf_z9(a^e=?4YClkm-QoffX_Q|A|^pPoKDw#%RkeOr_nN8-9xnv%h zPZp3<$!X*avWP4p%g8FyPtGOhleJ_$xsY5;HjzunrQ|YlIk|#dNve!CXk6_5-HzIl6>;*1EKr`vM_~ACDX_ZGLy_Av&kGXm&_yc$pUgJIgOk_7Lg@n z8Cga8$+_fwvX-nT7m|y~CUOb6lw3wGCs&Xw$yMZPat*nTTu(NWo5^kDc5(-~liWq_ zCR@n8WGlI!JU|{K50ghpbtcz88AryG31lLfL?)A7(nqF{@(n2&4{2lunMr1m*<=ox zOXiXJWC1yqoJP(di^vkPjI1L4uA=i=X$!2mhxsBXT?jU!PyU5*S3%QqUCHIpD$b;lz z@+c`USlR2Jl<$K{Jf2J-6Uihpne>uAQoi9N`BTX>GK0({Be z8Du7zMP`#ZWGwh^poh6Y(5_u#A-FFC;F{NeGj0pIewi z%6)r@%YApD+z%J}a6eR-PtGUhey-@{zN#=A_sxW5q}=zDxZHmersBSeQ0^xQ<^GQ_ z4%gd-x#U7p?gNNkuG0&BxGpO!BIWwC#N|4$Fb>!4gc;;qQm!kCUas#6^D)4L^GUgW zB=JQ2-!Cj6<$8j|lkxwcQ2y@~%Kx9j1pJ>MEFMsWS{y3{? z5lXDvoO;iF)9>BX=pUgLP4gu`oek>+n-sd}&?YPJXHUbY5PWwl7Ru8w9SFRb-n^mB zb!emOpFi?6$j^q=?Xf%!BN13MIQ^w(kzcj##G+}@V9zhyBM)u%`iBK}1YX>5IHvCP z{%B@m;PA^WXk%iWdyuh7@OwM4$rj$-KTVN$8}NP>_z=xmw#xp z)rHXv+bHGGW>*)Ltd+Kivy_!_{_{F*@^YBfy*J&{@R@(Nx7RNE5u&wik0PwcMW^|i zVW|6{Z6&PJ+hsiM%cyIg?w=Z%?{i~>!a|R$hGu_E-M-p|%dW}BF1&85wV++P&{Mzm z0}NPM)AItGW^LGaTHPDgq0Md>Z*oaDf$l?_6NGVS#CPg8CG7jomj0^kx5zhZD|Wke zTU|1O>VE~rzQ1VITP|qZJ}<5@NPjjiuysqVj7ha%s~r8?9zu$m_K8vBK6T${-~5!3 zcq_ZhpKDXtjo4H8@3mz?o6NKu&@lOit@E3}{HAZV{NO{xm$~Ju-@X36t>Xi>=_mdJ zw!_c_tQLjCoIPb@X}3#9m7FKYbS`EbsyZfl4m1rhw8+jcyD%K`BEDa{Q2NL*aaR}d z{o2m#qztLwrSu_oI8=2^k|y&wQtV}t@7AekN@i3?wXLNG5rI zW~vU_OVbX~Ir}9Jogn=n{US8|g2Np4`oSq43A2LHjygHZl;rtXF$X{##_e*%UjoBU ze`Q!7Wzd_+w8O*=o%&<>KCJO0l<%=RC;1+#bBeKhAgGDKD8u2~o@9*4_t!2ACfn^A z6BeHs7QZblUK|!TUq-=KYV5C%;B#*FS3k-NjmE^~+hJ<@^qKNOqUrw1vdV{xtL5t{ z9lHBNV*bjSsw!H@_gYG-?fP0cRLeMXVTI=iv7+u0VvySJ;Gv6tib3SU`IA@l2#>k+ z%HEwzq^I@xTw)nli8+@T6t)f~<2ahMsK6K3@SK05XYEkW+D+Fyi+XvU`~sGB^L_Cy z|K)XuPxD_pr|g;rNvQulmern1QoKk%YL1~RBGFcFjghSP zY?{?{Xp`4J>d>YHPs8KTc-G$S+Rzez5q9RP?u~H+c0pkwu;Gn<19r7ti&LS1R<#V< z(9+MgXiI_CK6gpnYHwws_NeZpY8Fsx~cD>^5a7;%Xza~dnoI4?JOkGR=4J~Jc=GFE(ue9mGpnYsz zi?yNU{80NOM_IaDU6%Ia?kM*H`k9Od>-GOy~FQd@JztfsnF z%dLPtfNn^)r+gO}CZP;^usBMy?3|*csL;FCr*kK>YX;gQoPMw}RWh1LO zcarzN_4of>H|ZZUb!7{42i+mSj|bX6Zkju&K%zN=@^zxUkDY<6a$uf-nLa+Htx5$q z3@R5)9Aqo6Gg%p1B7S24-yJ)VzZxLtQqp|qIoAX^uyc~*yG+9|i=AvdGRZrl z&dEeChEmQoy0c4#jrcR?Na8QrInw2{1MKN3QxN0gL#7)sOITKeOe@o$#xxL z&U2&`RMwosNFRuu)Ia0(h6|eu^g2Dn$04I~xg)=+k488qIR|o1^38p-zGa(`Z`=+S1CDQr>oXR9$r2|t`eSIN zvpc?Hs1*<6d!95>$}2A5qlg@HSz5Z+F?DzSB0c?zOl{u%^@}o8Q6_WF5g)R)m3m4N zr^uN{{35?Ep`rQFJFd3R;UB#@{iS^ao5se=X@mOomDrt+-B@$LdNr_P9Otm-mv%B@F@Ryck}OEr~4=$ zvYLI=C&kb89lyEax(&OPj$gX%?f-EncpowhRg-QvqbVCHKi`ONOY#Gj9iPtZ(8&My(iavwQZ8`H|5X=~ zw+YeVUeNyk>9R}5I(B7VvoFiQCD>@!V#j81SLW@0UzWoal7X^tR{-l-Mo)0Ud7Qi9 zCI6HKS6z4e#Qd7@G0DtED;`Y_IOI_ib`NquD+ zj#;|hjP4bpbWCQHUksgd-_x00_<4@lMcem;pXY3Flqo?Dg^2T<%}A3n%w+0!9Td)e z&nh%X>MOdg&T|eRy(i~6^39wk*mifGvl!(%w`dIqzYu{RtlS)XPb>dY>D8|ut1d>azGo@_(1uXavmjLEt;b(3_llkLS!#!eVA z(h#YFPPQX+{FePj`0=(1c5>V>lksQbhEDy7AM;on_SHsQAjH?P@g?-qve_8d1IJvJ z*{dT~dV1!SSJ-2?`w_gGyL`PSQ?OTcULVJoCGES1dARN~Lv9)3T3sN|=i9Jv5N^C= zeI|g*L4J2uLrs2Tbu4U((s4nd-_{&oiu4$miX&1x?hC>&LwqcF19}%?X*_~uJvGO- z4%Y?R>o(`1 z$HM>E-+1ccQQNVvdY+IcETob$;!V5r;S=pkL;D(vkdFRGVb@C!Vqo0j+OQ{Xz(y!6 zWK2X|9+Q=`&GU;%KF?1!02f%>tW6Cs;mRR~Ql{s#--d781N7nMUshmi!0+?UYVxdw z%gI(C)n~6+)Hn&oaRHn-**BcAhU!wUjy#{&^Y{{2A$w7v zO)?`iBar9|Y?RgBIszkZEGqe^TW$~|ExGRR7EZx@)}}gK6Kj}*+Al(_@DHcAZcFUG zq$b#;NwZ`nHN51hUyeNn)+5GUW9~O=j|_VFTKnqa%X{A4c$uu|hRHB^cVjd5Jf8Y{ z5SD)F7_gq7z?BpYZ7d3y)f6+|m)Q1qoX(l;qRLbMRXf|66)4jB2ev$2lIMxlSSc9L zfmhppB^m51ogwb+;Tu!e>dA89(sYZf(cjOFnznr|=-=3*|C97Kw6)>w#wl)3{d*`5 zsWDm4dY#5dOZ9#t~;co35WNFWOc20$D&NMMUSIU&_ zS8s&QI$_J~*Y^JVcDlGhoAAL~IExeOtY;st2VH39@5Dy$7r32>fu*i^ZqC|CsM98tD1l zJ7@)lc}BDy$M4^h9Y))qkOiY81*4-O9_AR;sckU`*nXao4e8}K-rXdlqvqUqH`ybj z;dy8myb&)ex_%@!FX@76jFSmg+a9=`)nvvT21(oJFlz07++uHG(*JFnpI7^C`%1z24}pf3!`rbrVqi*x-H(yU_`;ZAoZ}{l7`u*$82~^Ln1RUpkaq zScLz8?(HIMtxXUTP8F+4|}Mz zz!t36jKFULW!QtQ9q3uxCJ%D7ZfK2p`Hi^be(36492P!V_rYUxaEHg$_#irI*Mj$- zMKKS5s-fL~Ut^AMXy6a1zdNw2ZqH*I4&wotTBNECE&Z(>o?p~USj8m&TF%V^I4+@) zSgU!yq4ou;!1E}t`7P{tUV6DD&VAOt)AaV=&|Xu3!UCLZ7rY_=UN%06J4xdPY?3jD0B(E@*wi*zjwJSe1^t_|NF8#g zxctiz&R&Gv@hQ40FGyAPp(?LQRnBjlk6Z!m=#62xsn+(~6 zF0jczVWqpK0tLJ4-iX=oMpEO0xJl)#${BXG#0hTO*B=h{dVPhBwY{e6U}reUhUzU9v7s`w{25|7$+obo!y!qulaf$u( zlUFrQcRXUH`}vML1HYXzIq)*ZF>X|1|CE2u+t{e`>;95}F^I#qs{3^UHo#QbKhefQqE;|_ z`1f+0kn^^M*uh0RPHnNzt8g6M_kE5FIZOMxy%?;~n($1|#PizQw@e&{ZKPio4w_$tO=HFI#_KH{NGj8xlfm~B>2BR0p0$Z_ zafyTKHdu8>5^COgx)w>llD1>BPC~hOaI7t+HY-l~eRxXiUG(wGZ=%SvC4$Sy3-&a_ z_T@M0HjWD%iJO#!UB-gpE$jPnKHz!s+tAwE$;&N2(5D3Q^vMtO z89@UQJ!`MS&fyMy3R^R$u_m_dn=+_*JP+2>>;Jy9+TNNy`@U?>Yg_wec|1>i7VfY% za2wJ*U59jRuHMEe7Czl?w=PchInd?THOtOFu&dRpk60K4a;|wh&!sUc);)|Y7$wO# zo$}Nl#-1JdQrqHDJMA|gev$4)r^Si8JfA!LIqmcX?Be(R0PDTE-Pe$SgPm#5l$gfr zaTZb`_YXI`H*EM0`)uehaRXkl{?#U@mil*#ARFT1=dFU>AxMyVeC*eQjBiEcL;uePEZJKT#XDzH=Dq z$xKI^?f&hoT|U-B_iH{JMO(RlgG+SkyC|94lj&E~)m1ymZOP`g4%Nga>aLxXJh<)a zvI6EHZe>Z@;$WJ)?J-Hy+a=bE@9E`8w3}cL&!?~k?b8bOw@weX|8!|zmbeIMzh~`i zE0BoJY@GoIp0yKkSbKNCfrS&THczm;#u}?F4b7;Xl;CZ9R~oPDQ9CKoYI_rLXM>&% zR(kNhOH5Owwrr+*-`S{l_zG&lI>h$Uwhi@&vVLxR7hB4oqcnUa^6lGVJCrhlEgmL0 zejMTo&73FZUlBjf0rby9&@Ql>Hy8U!yIqwC>^rT=IpM&Sgi{7DPFj42VzT|7MH7?d z3>>4-KJ&oIkM}850=t)_d)ix?1onZA$G-*p_e&L*`E~<~miZ1yY>lr)VrzVdCAQwT zSFp<03N*a7)xPQEsecRmr3F{Zb#PC^pAcR&IsVW_?Bp-N=KgNI?;wm1puV1l;ZWHB zME+vp2+uDbx&Z%7E}9f)wI14#(3l!i^XUb95|F*7X3@kn`?+SHr~XgK(%2-Iw6N35 z#lb8OG3a8mu?vQ(AiWvN{H-}|`$7eFVReVS)dx1T4Z`VJZr$q^n%{_X`9N#yGZxJgsEz&ifhB)BeE$C8&?GgK4`g3)Aj&5}i zhDz0KaF2bl`XAPB^rPqgxLHzPY`b-DVnqH9`_L`@@C-312T`o*IPrvYGenc@?F5@& zQrkPSv(@_%V<)9Y*gX?zC$)&MYY5tHm7ko#Venp2p+7NBrSN#Ei`-4@7=HYZ0rl}= zjJ6%Zu1q)P?=IOFxv@!Y!B40+R*jtX>@d~V3V(Xtv=t&~zoGL#@E1OBg08Ds#$q#U zWbVu^+^31lU1jH-gt*K`XX1wP6?v0xbcP?rJn|KEnR7Xt_)5g>8SOFYLeUkWAA2*; zg%2~wAuMwO2C2-=SU1ww@-{>GEc&Hk^A5zL%}bF#TrWDa9-Wjoyv*E$_DEW1lr%5w zWtOny`ymFkbFRW|E16f~^0d5tRDxN)R<#gw31+9Q3FlIuLYlZq59g40rJiw=>qS19 zMK807%iB&eCs1e7L?>UslUe-8Y~u3eJ(=YTiY8qsy6}4RRs8EHTV~UjCcYFpnTycB zCS54Hv!UzF{BziU9`jtx(c003_SRyq3Y*0?3H>K;u$fun(Pm@oOp8{Q=ysqSGk0dw znSL9}&&3;QBQgH~^A|Bcg1HcLv^+zoKf>`Qas1X~jXeG5EuHPHsPuaaz5E%{A}@aS zx~8nK+FLvqzv_ygm8`75*zd3x;||l(3U8(tKeO#E$M1Qonu>=iDj%-!R#tmUEAT_1 z__a{Kx3WrpOIwUmW{>pBuWRDRnDOJ&6@_Kq;_B+k>Z@QPKL>7CLw;cNfeQO~OC#;d zOHrGO2fQ;2tMKE$65>y$;&*598|Ot{f29|{py@Tga@o}lPy2#7+7d)e$v||P{h;ea9ngIs_ZGYf_$5UgKk)S0 z0qcgk*jt`(-|=KjgDd6&7dzqlL0vroTU}f>I^yXNQC8b;BPnt;?sKM(&Ipb6!AnZ^ z(+p^qlJ1r%8}r}It0V}cx%L$Pv|IfJIF2GCHfJUIaTv4jBwxh1bdgMHW{~TsZ70D| znBy>aXO{sR@h`(pCh?b#D<@`>a%D=xEO)NWwD>|ixr+Uz)KAP!{jv}ifAUn6Ott4I z^&1_umtrUBlSpHC%h1TX;9@6Fq6wvZnP$Q++THw_NE16V)xyp>nKZe&Bw^EDvD;-5 zp*QWFjj*%5siW}=OwdVtv8i{oH~i^TU5Ql8sxmpGICA$|w3!>868vP+g2D@jw#0O@t`6Gy;Kp5+Wq!eSo{lN@fBh5 zpNGY_gvDhaYbIGQf5mL}WAX&hA(IG7daR?%BPNMMPeNue*RlMnxOwQ(e&odd@#@)rwAAtY*}-4E4u-T1 zUy9Q&!Pyb#uX}5cHDzU`6|*X_9zKiN!WjIi5bNV1^s{g=b^tDHymeSV5|6_MXq|z# zMTLl8$@mu;e}?=s`A6*ZB>yZ7WefZB*+T3)9}%93Uz-M9XWPkOKzVZX5%M$S*T^4|K9udkJ|~a#lk(Lx7dG0z zf)>h@N!}+$^=-EauvCn zTtluS*OSfUW^x<3o!mk0BzKX!$rf@i*-Gvw50D4R!{kvCyC8dgxJfy;ko6N!%4JN6 z%lV-&iA*NFq+ElO^b}I=-AP>jw-;uRvOkl!TzeE|lR0EAnMdZ61>{t68aab3B1_0J zvWoPRbIJK+Em==4Bo~uS&ml1-X)3MXn~-kn70xWHY&$+(vFEcaS^DUF2@Eh1^TFlKaU6 ze!%F_~(E?*xLCXvac zm-LY-WGb0PW{{a=7MV@vkn)DClp|j`6MAu;B5z2|CFOid;&T2YOu}(YD93G~9A|}N zGSZ`dk)pFVsxHgC@>2Wp^d7uXl`8+}W6H3XDR_GYC-si$3yyH-LASyxz<;oAW#QdT zH{J(K#_}3`Z^o@|!F3w9nx@jRbg8je#;6Hc-izyplJ7RmvA71}#`U8auu$rLg!`*G zSWZx%hP6_)SX!zMn(68@SWZ-*!!izcR$`Fj>sZF9Z$dLbeHY7txY8*9@Bakzwd$8x z4pJMij91TNd763&%faf8Sl+7sfu%>ik7a^#TW-98=fUy}brzOG@H_TywC5r$&s3wa zJWE}Q<=JX1mPu+nmglHkEQhMwu*_HYV|lJB!}2!uIF`4ouVOh_eH+UH^#d%E)lacJ zPd$xgj@pFf`RX@V4pTcZL@f2Hg_W*;4~Ijy1sDI$}nWld&ws*8$yF2jxhOS5*jKq#nU?gnAr)VpKi!r>Q5QxmbM>%W>)}&Wvcoce7e;EC3 zT?3o5RW`yiRW6pJRX&zu)Kut`)IC_9qwd3Us49fMNL64t3HSKiDor(DnXVRNd8t~0 z35ut`HQ@E=HidrW{Lu;X`TyF0VkZCRA2c zmRI8X!G!9dJ?Ti`7J=R^qR`9JgI2%FPql&Q=p^DvC>IRaV1tUR8Bzr5~(D zxk$}HO{;NRC8u}}N_+q%sOuh>hm0sXw-jz4D4SPRGFx5eFDb38LWUcPE2|%nYTQs( z_&{Y@sT6TTB~pRv;^K$Y4K)uIRu}q95vVS&d8njR<-!^>?h6TODk>{gZt?xq#Sg38 z(rT1hQK)V#$9IHE3(KaXSIZ0G>&6PSsnlOwgwX7n)ur}*Af)FPmXsCFDUHxpqXsDE zrb0ABI)74ODKtO@`mqqiT9AS!70xRxnVyG~lEUiB*(J77NqKQKMoHcXl~-7a*utUorlQ{l%rzZ!VmNUb-1wD}6V8Vomkz(m9e!g|pXhE=7HAhSSOl>1%O6 zudt%Luv*=sZYff?6hAz@ps;j$UQMyO<)KP-OPRW*Qr-H1jEP&zrcW#>eW(gr(s_mI*4gES6=1%~pQ-YTRDQ9_pQZ9k z3Llt_^?*PnM!wzl{8E))sq$y5+lwE>idMJRAOU;e$yk|Kizse#VNG=*y1TkiO-2ej zUsek^M~a?YT2X=?Q@wN@q)sKkgcGwytGUe6qnUJP@`ZVqXIxe z>HYXXRt1QwlZ6kIs5@kHknueQsZ)_MwQ9DSI=f0ut(mE&K3t^kD#d>3?lN_EmAZSj z**6%lJ%zeN7CP?y#p+*c0k6$vO8lay&Lu3Ig(lV4?hyv|JxZ z!E7iuVfYHbZF0`CH#IYY_Jl8cb~(AirWj6cOtF~S;RUxb z?7otHw$w}NE>kn+7R+*8O0Gr8btoxcuG6=}SRVgxZyzR4<;P$ab;Km=Lr%fWI%z;S z#fy95n31Pl))|6oIp$idsKH4Hcu@z;F3d5Q-I!xB_ru&Da~$RYmCN@UQtQd+NJaO;) zn%kqDee5HoW4efZ*l+!sZ895md|U<)Cod`I@-jxT%I#?*Y@FM)q{(~@X&YhjXNND* ziH%ISY;TWyJA#GS-E1PDu@joQNwWNkAk$C>E)pciu)TuEH^b;}Vx3kDL;M7$Z> zy-?zLpfp_8hs5s#vk{-mcoo=;csApYgVH&&iHrRbP`*%Y;@?9&4RKSS|3y5*k^Wo6 zXCUqcCI9PSE#mo%{}XIM{M(G{`)?gzVl+3u{Gne3@tb>Ke%z2NEH5^9(rRW_O_#fK z)i}%+8yn~zxZn2Z)ZqCX7#dB-S4BGRu61ZGi?F#gLetGhOXke3Dx6t7y{vS$sd!0* z#&HvHOosdy9h^G8R+1k5Yb94)k;zX-cmMA9Lisurrq2GiwiCk^I!EZ(4KwM8$`}@j zCHtxV2*qI@U~2~AXdfxhfBIWcj-5Fu=eki>^ z=Hs8F{jroG2oJ`8jEVT~Fb@A44zXi#IIlSyp(LbA`q@Z7$JU*Vc(C{O^4Yt{9E$$Yb(`GrL<0UB-A^!J25>=HMDmxR>LNU(dF7 z=STX)$PIQaa&g_{CWz#mgyYoBQR{XKu8-y8O4jYjjsKvqEWmt6hcD3#$F-y3xUw@9 z%e(MD$Z%X4(Pc?^8m{t5>^|yDEvDP?8IGl-%)qs$`yn$O)I^xDdPgsoWGodmI zUv&BBgy&lLys9O6FPk_O-AaQlTns zaoaJ`lp}R8z9QqsSI5WlLyRp1)P!}fBnnx`H?=u>vAM$O07;d1q;9ed1P z*4oPj>Tz5As!r8ou2T*6@(J~%T8L1@C$QRTXaR&A! zTfVHmf@{sDJx+dAeGSipMW4T}mZ@)`72j0f!vAlQ>nVHb#~GN&ce;@k_+IDn$airy z{CMPhs%!baTB(kA{(<@-M7Dz;svkj)*I#e)uj;b2A9tDBn{rN;t=^iP%m2aq9w$n~ z?@!cfhm_-qvlAyjgMYXBe^_c+1OB|vWGy`Z!uB3qnvxCIsbdk7yPUayfpUU6XXux> zH>IUqJ#EV~>KU~jz3`0sU&ybbiW_;#Vc}NK9;eKTnm_t6DOz2^|F@91v_M4aRua|! z@z(m}=a<%mw*RcKwbP7ifnpI{XHv@zQAF2X*6y=vV;546xBND%Ut>OY`8D$QUSx#o zGW)uxx2O{*TU9jK(#e*mx58~IQl3-CE6?LDbEv$aUQpZB|Jm|_qej2MTLV3n-zqIT zND~(touTNYg)ep~<+u;tTX|WDi0_^DQupJBwR{$Jh(1P7ZjD0s4LyyOt5TraUc~?65R)o82|Lre3x`|lc<8bmWtO8<5h>r4XTn0GH8eJ+eDP>> znt#RHBjF-`bdGR8Chwc-P1OodZ4qL0hLIN0G~w1d?$k=jZ=$qTTcms~qSbYglsE0x zwS~3O)Y?#LAh{&|RutK%_IKmqZS^-ux%zvUh)2;GhNpKH5BFre1ntG++wgn<%fDgP zB3fM&&A086MQh}3b z5;l2)VW(ebYB}C*dRHC9{4Vl|NJzq(2W_2{6O==aa8PSPhj9luT#hJ__Z;#*!X}6C zs4eB{gD^1~!|?RZ;?eD$T3z}F>fg5L@{gh>I&S#ykXmZ3_TsF))I#!!u04u4Z6%Bw zdk(QI(YY)aXm0o#8jYdRcgN`VPOX&b#_eU7<;Lu?V(q2qbWLQ5=K$@x1?wLRyI@R0 zF|4(*?Po=bE;lq^c&xwGAD-f@P%#?A(A49LNe$wx0Vub>HIP!SBqlY{9Ekda*K|OH zM(QCR#Bz`oDe+cNw71hj+9|rh)?noKSlx^E(7j!#MKs@{6K~;`qD$y#<>{!|U@O5E zt(SOEPVcbPHH*F!`!hPV9AfpYB*OohR$_>ldd4be*=L2=NRG3uq$qMW^v1*S^Bn6O zc#~O{&al(Bq?l9_cE+`bP%qkUDDs_a4RuI4-cl81U$twtk{XB}Yn>+Kpl< zBdtpyqfeletI>`%tHWcgz7RZLPQU5a$6GG7K3Z~__3@Gn>!T*+%G5~qZYHcL@t`g; zJ=FTxVkg>vSN?k2o}jN|YumBp3YOV7{e5h8Dp!|VB3DGnl~&J0A3M7%J=2O5ol`Hz zS|1m2);buz%DVcLoa%x9z#ho5vU<>}YpiRJLB?6xJX0HQeH2CRhTzRrOC-3hM+;4~ zIupDe$Fv+vBwFrrb)D6{TyKd;jUs*AV0ACKR&FPym#Z7C&cvjZtDCHwI?X@HIysVO z<=Lv$+Fp36}CvI=TjH6%5^N9jj;`_gEs+ zD8aBPK~jS0Iwn>o{a%Ldv+lE|N0AxUv5S-u%xy{xWuetKVoJH+GBVQ=k(gc@eQ5cj zHF}yTmoJ@Yk3YGA(^^>q}`zfgCPsJ{>LiLL+EhWl?7Fl8=v2gFWn{figkM|6;G+M#; zQu-=Xf%iDHm=a99qKh_t*7}^K+uTGROAnY5kCzo)tk=-B+Ot^X`t3|({B`%<)<-@4 z^VS!vlU2vyNco~Yc9vjyvdZqOa=v7R%9pKBai+>xa;8e$nJ!^xx`ca^9?icWB{*lP zfphN8|5vQ9SW78iwZ3Y74f1u!GDx)gf5QruaQ~sH--u{mv~;|Eg*KGi`$p-LZ$Xw@ zW$G!+BF^-0TUsPtM9PbyN!n*DSne`IMXQHGH=qUpL6d7@wyKCG=phkk6WvgOBCFl4Oa zU~R_f|s?b3{I-Pf`d8!bZ+6Q4hWrE|SR3;#c> zYguD;EkCzJWbdj&Kex^f>9Jt_f~^&uiRqAYX;Mrpg7MylOgZ8`SYmIzX!~G0PKBI3 z5Z;@zSCBbe-&x$OqhNY(atCvr?9lOzCua}#EPSHd=Pb1+zB}6s_9So5Z8|HZbA5E* zo!f_}MB68x3|;hkcdcD(^k$#&6H-DLI_h`b@|8aWecI=v4gJd*GK=Ukbh{V)doqZ4vzE{*1NW`d{l; z*0Uj3f}5=k)<$a+uhHr&wZSX6awTW8wb|;D`z3Qd#PZ+iLkd!&cZ=ZAyON^5=J$K}ga$0Kq* zRj$YeugdCBFz&qKs=w(eOOq}%$0WmGj#*K!=gKwZ$e#RgG{3caFXgKDc|PnMo%QaA zU9VH+_q+!>TZdigo##!?u*qZY&b48eZjW$WW3(reN>`I_cVYbR zzKdg>XwklRSs!1~S4YgX0O$5&!pGKU!Cp6hj+a4?p`q@^=I^cJk@Beb=Z>c>rmqdV zy90PUwf}u5_ZN?+{*if2OQJKQoM^pu;&r>Np2{D4Y}r$fr|dq;J)pmT%)`^uCD=4p9uUmUg zNz@*A!`f?0cm4AhD^es+C5ku|JBmpbN`Wg6QM|X)B3E{+wwzO@k7;WeRQPF zij=pkx2$~*39UcAeby@p{w9S9N&c>$O_nR}U8VPRT5-g?0H(zKA$JRmR{v&(#NNi8 z1ATu%V&VN};wGPyf9vt+H(pL2<-Ujfnu(FWTYt9>V0JR7(faO}?^y4^%K=|*g9+-i6W-%!dH4A&Tl6F zUWv$ekF~sKMauiuvB^;@R6ejiu>RdEX}6+@!cRw=`i9bS9sAd-v?rH6#o%Wp`%+x4 z7>Jp4Se7EOok}^b()Dviis=K%X~M_K{;m@(aju{Ya1F3yhLN?@rN>3oA`UsldY~&( zL_f%-#rb`>XyJI5Q!8I=yTtyko2kiZuD+GQ@ITlVDMv!V@^nlzrZzpL`0%(AAg4!_ zGh9O;XFw7mr@PLCh%TCc=N(K*?=Bwd!)fjOHka0i+MbF<_CWOY*ITWuX}!M9S~qL^ zELWsBYjL(K>6qkHzUcjSs$Wj^OY|Oyu01tgPW4Ol9*C|zHC|3^zl3``*8X)KQ=Q@7 zeVx|iysXc^B5O)I$MxSWLtX#f();^TADu_?RibjwtFHNd?H#xoq7D3G7_{{ zhhMIY_S=-_x}s^d&io#w#3Zca&SiMs=)bM@@zN%{x|U#{b{6`0wf9tQd)5Q;9A#%~ z+~|Aesqd_$9)0IM(z9vziDG04TC<+_AP3rh~&-x3;h4AKwz`s2>22Xn$PNI#S>@9*jHsF&`jPa@BXs_pKn z(4M8A=Q_`Ie9!jkQR?&|nx4gVUiscm9C}giEXE>l@EtV|~qFi6=Uwzl?Q(>sUp%{6be>OW*de&viUft}b$E>8zF`T;0jV z5f&Fa#$RWCPn15zb?j2EM!G(6g2c2Z+}|iyYKIt`6Uj?lCsszgPOOY^^{u42j$LFu zq`M;JM6RE{_I0T%C{os?*!F^&6C2W=b&I4NiC@+W!Ltdj%fsY&`{xQ*&*e&2P;|MO zuCd1;!8%`c68Ch$Qk|izUB@R`uHK2WY{}`2e;DCwT-VxCu7trFXzjJGYbfPPhYXFr zr!<~TX*zzbYh0KZJHu>OxR?~p@vdW)39bpQiLRWJD7wbixtwyntLGy5Z*YZ5uB#^! z?6VtPp>mV!qb9++o(gr}1Cw0GBjqa3b+aqab<0VUn^9ipa;wWJruF%*p2=;lNHIP- zV#0U0?r=@PtfjNMiT+MkZza^*R9B=pE$(uO+!Tvk`{f~5SszODG96l1xh)m0&ctDh-u(E zZltC06q#~jHPO~*Z*|?>3qKj@RW6a?5&s+Zwk^kEe`422UweyeVNagYh|Cq#nBTJM z4bAUV^@hFiZ)`*Tm*dy8x)+nTH|*YPq{S*6HKh#cNwW-6r-awRc#)QbwPNktj1lJ8eWdmpYFdCS5DA(&q7_-JbG%+Jcn9E_tdpE)I-l= zU3-k4+B46gR?$6mtqt|ivsl+2qo?-FbEs8xPu**yZ8f2uqs8KSv|kG?Jv2`=uU+dx z^N0HGEEbxlYyZ(wL-Ti5N~k_GPc*Mx>q7H~`tB?inx||3(NaV6cUDTMJ~WT~5~Pf! zXwP1sXq|aF{aBxl*ZE{AHI}9E=wwi9Y{c4#&Kt~cY{Y}ksWnC)PHm<0>r!>DU=4!t z&`>ZIv^8ZqHIZRccjLiOES=%VoLUpi-?yQs)zcmQ9Id3jI%73u^_BmV?boy?oL$#L zth=)4E?u7B?<#-jx5UEh){}Vj{~v-myDq)E)b48EUH)TFH!V1J4_)On-alIWq^tK* z?UHtO-j1$%;n>rHfS+Zvp;FkxM96YGwhwX(Z> zJx_P`PG_Y>>bv(Jna8Q=K7U_YNSmGQ?#r@H`Ia6C_O>1cA7-ye4NUpYG3gAO^q$h0 z_f)vE9_VRro(wxv$LM95)V^Z$Qa>DRU$wC-zaLIZPkyPL^+C_Sy7E!5?5q{Xu0MIL zieAT)SN@4FDSC@OUfLg8XGM8OKKz~e&g0>CmOpOs&Rh21kz(%EpW=UJ4|F$*|C_&l zCwppTxnkV0{rblZ7&s{Yw85T))6W=^c;;DWC!I6&+~o7lALbo?!G*qyMqHdSa^%QQ zj7q&^^q92tOE1f~{E90x$6j@H)-~6T%N{>r!o-~GuD>Do#v5*$l$ST*<_QySxi$Z` z+b0*?G3Cywcinx@w0rNnVS4YU8NJVP(sLBvKa*2Yaq+ANN=hGmsI0uAvg(u7v;8%5 z9-e!mG4GME=~KO)rca;$=|>-{tzGbVU46q7Pc966=GH}v8$bKGTkWao*3W<8i?=Sh z^-G9-8S__`e)VfQ1(u+a2D&v!WyTAqBpB zoaNr|z3;F5!L2{M^+&6I{69Zg{nMZI#@+v0bL*`?U;B%7zr6M7XV(Akubyq*urVV0 zN#A1rlMCF`UE?-S|8>L~IJpX`;fGy^liT7`rJd@5Q$2912Tt|CsUA4h1E+f6R1ci$ zfm1zjss~Q>z^NWM)dQz`;8YKs>VZ=|aHe$;i(M& zNj>oVe^O&kwWZfR@caPfQZfxt7HLBbI4@qu&m_+#&mzwt&mm7IPtzPeAYOUl0la~< zgaeXjmq5GNc-7M0-ab4w{sz(#4j9Vx{YyfPow@c z>QA%v@b^=l?{uc0&h*onPkl?Lt8L_?Rez}+N6p6#%IO?yV{yNtG2G)NV?UKp! z$SRT(?1|bQU3|@P3lK5{tS6B`AhO5VLy&H zGKS;$+;|K=OyHS*a0tiO5VQl?+J~6&?$Y^(Fu$ZfPWut$MPxQPP6#`h#IINL0`h8d z1bHTT899_3LtaUqPmUrd+C({jkotnJk+R(&egSzkIf6WMu};5?@u5eK+V*1@zmhy( z#uNOU&-f^EBB`2L-UcDs8K>p8KnKj)(X` zdR$0;5ACGh7UF4$TO0=#_pcWGNIiuzS=^sm-0z-4zvobY4)dME{Ue^^v-2soM=@P7 zzheCq{V0=<^-$bzr!!wV{iV|`o%yb0{7S~hG2b}q#~D5Sj$^sw==Uz#-9@{*Xm=OW z?_>IXOuvu%!Hf?c7;Cq4Fzp7j{K3YK{#>+o(cVRS*Fe2qT+HWU|G0QOak0Kyt?Tqi8>h_M>P&iuD=Ae4|+YDAwn4=DVEsm(%`o`njC> zE;shfe>uy&f_7Ih{}uFi1@m3Od{;1EGVPOTpG^B?mYd9cKHB+c=VQ8$_C8}r|33O3 z!+c|yZw&3nF#j0#TPD*pnV#8SulG!@-%Ml2a=f(n(%wsZFYUdw8%w*ftj}2b8OwZQ zjUDSfmghTTdA>82^&de$BL?d2bp-Q|FzNI&g8oOayaa6jGm@1`VEzQw@9h5l>~Vc| zf7weZb#{N*3o7NIornHC^ygvyJoFn!yZ+oi^fz(Zr|^6(h58h>D~0X4g!)Sc>-JpA z_@yj2iSZ=H`!U{+@yi&$jPYTN4>NK0%P`hw7~4IJ<8&DNYZ%*g5$!HwdoH4%i@0C9 zi1rt;oQvr10>&?({RJ%d0`}7d^m_sGXVCs)L$1$@neSrSUCer2Oh3cOSmujmd9lnF z%X02!`rXvuO}o2U&fWBXx3OnCuA$vE%y$j_TtoY7XnzgsF^Tq*Xg`VelW0GU@oBW1 zM!RYBa~;#Kqy9SDU1!qiC)benxvXz4?Iw`}=w|@!cPq%R|z$XfDo@LWqDM+Tg$kGlhsNtfoiJpK=WADITAo-)Dj#P6Uz zXx9zn|7>&8)0zsq1^fJYFZ>V3c9@BrhIU;Zx|O8ymkH`o8^C`ZmKPDeR%9wGfU z;8o3`IPsA9ITA-{RO@2hBc74w}%KW8!hEbe#C=5b&s^ABbEd5oXOcnsrb8`9r-#xM0*hRm16^gF1( zgZevIzdY*msLwNcj{A6~$5Vd`x3GP;FkSlhXpQdYU3Y7)2h*4@jrM8WUeZ{< zY^G<^&rM9fiTazE?zpMes5&@Wa=kVKbiKEO*;Kgq<$jp zC(?eRNvHh?_TxRYzlZks7(MN#FntRBOrhNrlTQ07^nZ4L*^1>jInd?+H@CkSJx96@mOq~Q@g~mn8>qj5@j}LDkmnn+U(aX$^J#x4)9%_{$|E+XZ&{B-NyKBj8A1;F@7)C=e;cVUZ&qmfA<c|E<*DZ^(T2 z)6e}J#{;;Z8$$hnp@ZykJe1?mj$nbI(molSjrlPgASJ#T{59q+jBf?EVSbMB=fM{+ zZ)f}+@E@4}$@q2H6uyf2mzaMwO#A#f{4Ya%J!UE6JK#pln;8EB_%qBq7+(sm!~7!V zgVcQw+=BTP#+QT5m|tc5Yv9wE4>0}|xB>G!jDHFIIp%*cKI43)3Ne2jv()Ja&_9QH z#Bd#-ggQTj`4f!)8sWcS9>uu2VdBKAyeT=w_m>t{cr!*{Ir`E|E+44_N{ya9uiRgF zKj^R4EHNQ}@m#+eT~z2VRHN^oJzI^guGEp4mF4Bd6-cY7^cRo5;g<ne8u}DRt=S zbS@0B8t}{IddeUT+zg-zwjG*lPo3Faj8yqgp*y=&*hsm0FR4^E!n-Ze=*de;Iii(w z37L{zmcnJ!j!DvFzJ@djV`1l~3}#8att>nE!7OlUS8TK{UYZ> z5_kIB1-q%xnaTJwaYLuxt=?%jdSQ&+qM#-wq$ZN?EK%ZSE$KWl9c$CXW0gJ%A^rl+ z$y{#ThX|_+bbPd!zOB^KAv&Io=yKE}3l$Z6RW-A^czVsuqR}(ebQ7MA(e^;`rQwQn zhoZW8W@UBJY=>rM;q2nF;@PvO&o1`QR%0@*xXkOA(lgTVGG}IbM!MIVX6yAbJuU5u zj0~^$(n~MZ3h#`8k6o8{z2z7)R#?yF>3`9c9;+$%Rr*2F%8u!dJEu&p+aI?m$LDQm z_AERP>${=3ac=vgk1i_kCGQ(px6x{Nu5n)bqZOXDuE3G{=6P>tJ?nYmOR&rO!1Lr& zU|>Vt>*G9Ye=0r$?|9ZeH}*&%-skz;S0(L;XYC`_sCZxFgI3`Ex;L6@->>yFd_hwF zS^IwMoD@Nf=gG&hHUn>&!XEo#Q+jjV=D2(An||-6#~K8kB`73R52$0j*h!c{QnSdd@$Ct_V(DiJxEN3b@kY)$RFGb6xYGHb3@qvzo%n`)*iyciH~k@b5PMFA@KTYgW{~nOXBK6p-ih ziTk=%cfeYA1{%^f6rMe6?{=AP`8jIRcy|n(#26>HiIW4K`X9qS>!9b!c~aT;YTx^u z=gCx8SPd7dfq(K;+ZW-X zY2~$^hEE}&dqP*#3b@wEb<(y^N*Qb9lDNV^Nv_RQo_dyB*K8qLb69e;ZTz6auI|k= zPlMcqa26SZB4y{(<`swbdaZji%hT}bu!3VzFt$O}c32$J&g*G7P5YZ>deRk$StmQ7 zwjCXI(!OP#7AcF6VcnTVH>B;`qRW93F-Zt)8+o|xb5MmhT@D9rbC7_J zZ}@^#ahG_~eG`MCPZNVXOaXF@$o4p-ZM^o@VH^u%IVEmOk%X{yAod}y$gX8Gu3$4JNsib6-G zPBl76z>rACv@);>!7{Sp?Gm?4#{C0Zrxt;Nf9N>2GwrO7pVQt=3eg}pl~V|VJ=&?t#4`Hxc1>TDcVi_z&(?9 zC+#mRMqZ9dwWdiD=vQ!xG^~T7S;zYjR3h(K)cq`#*LSq$iMO)so$YSWk$x&V?Jr>Z zB#@t1rHM5AI;8FL1;LzUl#jO!(y>3z9pz;mVFM}(`5#MBM>-9Cx+7Jf>%M|K(^|e5 z=V|)43{*1kcLjDV9AO|ivQhVO68MZIOck3*mEmp&)`)H0_+MVUUbgk`p zXkANZu)RL(#$=1Mi-O7)_}?9E(rs7{K2GdkKPOgVG32BEi8%+v(yoE2L*}^`5c`06 z1b6R(z%BVXfxvyrE1KHRsZh$70wb!QfiHF2LGE1x4oCgm`3rsX>ii4tspH>m?`IsN z-p}+taO-=N3}G1T_~-f^b0>>rZgZP*6xye6asmbW-KuiAf*a$#6Efe#sL=!o<8p93gs$E88{YwweF9`M@>Y~Rl~e)g$#jHKgvWb(($ z@_f+!u>Aesf9OQy;QIZjG&^^+v1)2q#z4kO-(6)05g&}MGTfUN z4JV4>i9&WWRV2diqB?pkk%8B~!tIQ%Fx=5&W~%JOR>N(sGu%!vbejhaE0PI*%xYA| z*8LwryOEiR%!m4F?uec?)7xez{f86dW#;G_u`6MYE=GUFV%LB3fWCL!gnT@2i(l;6u_I^%$`}^os$74+lRV8gYtn z42?r05dImg01@AVtRs;wbD_J?hzmW1x}7r+$BAD&#jU~7x8MyTv11#4(K~IPfk19x zT^v_%zEZ?0D1u55`;)@-$RKBlAF7?oa!BlvN#BY|~`>}($yJPo@-rk0uQ5m=;Z zA2}={4}+oE@5-E${jPTIT(Fz`eodvC*NTGz4LR*%$Ctp;KNv`M9?jIF5#lTnU+we{ z_kHuN==sp7v+IK*eqpCaiW505!q>1;e@8ZfBb~c5C35JGfIfO !N4BfBxjN`q%2 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

    pcre   Introductory page
    pcre-config  Information about the installation configuration
    pcre16   Discussion of the 16-bit PCRE library
    pcre32   Discussion of the 32-bit PCRE library
    pcre-config  Information about the installation configuration
    pcreapi   PCRE's native API
    pcrebuild  Options for building PCRE
      Building PCRE
    pcrecallout   The callout facility
      Some comments on performance
    pcreposix  The POSIX API to the PCRE library
      The POSIX API to the PCRE 8-bit library
    pcreprecompile   How to save and re-use compiled patterns
      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_free_study  Free study data
    pcre_free_substring   Free extracted substring
    pcre_get_stringnumber   Convert captured string name to number
    pcre_get_stringtable_entries  Find table entries for given string name
    pcre_get_substring   Extract numbered substring into new memory
    pcre_get_substring_list   Extract all substrings into new memory
    pcre_info  Obsolete information extraction function
    pcre_jit_exec  Fast path interface to JIT matching
    pcre_jit_stack_alloc   Create a stack for JIT matching