pcre-8.35.tar.bz2

This commit is contained in:
Sergei Golubchik 2014-06-05 13:44:44 +02:00
commit 8cc5973f1a
107 changed files with 21420 additions and 4077 deletions

View file

@ -8,7 +8,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
Copyright (c) 1997-2013 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-2013 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-2013 Zoltan Herczeg
Copyright(c) 2009-2014 Zoltan Herczeg
All rights reserved.

View file

@ -1,6 +1,126 @@
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
-----------------------------

View file

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

View file

@ -24,7 +24,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
Copyright (c) 1997-2013 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-2013 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-2013 Zoltan Herczeg
Copyright(c) 2009-2014 Zoltan Herczeg
All rights reserved.

View file

@ -350,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 \
@ -578,6 +582,8 @@ EXTRA_DIST += \
testdata/testoutput1 \
testdata/testoutput2 \
testdata/testoutput3 \
testdata/testoutput3A \
testdata/testoutput3B \
testdata/testoutput4 \
testdata/testoutput5 \
testdata/testoutput6 \
@ -616,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.

View file

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.14 from Makefile.am.
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
@ -981,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
@ -1017,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 \
@ -1041,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 \
@ -2883,9 +2886,10 @@ distcheck: dist
&& 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 \
@ -2988,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 \

View file

@ -1,6 +1,17 @@
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
-----------------------------

View file

@ -85,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 <prefix>/share/doc/pcre, where
<prefix> 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
<prefix>/share/doc/pcre, where <prefix> 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
@ -372,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,
@ -987,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: 05 November 2013
Last updated: 17 January 2014

View file

@ -69,447 +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 -----------------------------" >>testtry
(cd $srcdir; $valgrind $pcregrep -n "^$" ./testdata/grepinput3) >>testtry 2>&1
echo "RC=$?" >>testtry
echo "---------------------------- Test 102 -----------------------------" >>testtrygrep
(cd $srcdir; $valgrind $pcregrep -n "^$" ./testdata/grepinput3) >>testtrygrep 2>&1
echo "RC=$?" >>testtrygrep
echo "---------------------------- Test 103 -----------------------------" >>testtry
(cd $srcdir; $valgrind $pcregrep --only-matching "^$" ./testdata/grepinput3) >>testtry 2>&1
echo "RC=$?" >>testtry
echo "---------------------------- Test 103 -----------------------------" >>testtrygrep
(cd $srcdir; $valgrind $pcregrep --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1
echo "RC=$?" >>testtrygrep
echo "---------------------------- Test 104 -----------------------------" >>testtry
(cd $srcdir; $valgrind $pcregrep -n --only-matching "^$" ./testdata/grepinput3) >>testtry 2>&1
echo "RC=$?" >>testtry
echo "---------------------------- Test 104 -----------------------------" >>testtrygrep
(cd $srcdir; $valgrind $pcregrep -n --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1
echo "RC=$?" >>testtrygrep
echo "---------------------------- Test 105 -----------------------------" >>testtry
(cd $srcdir; $valgrind $pcregrep --colour=always "ipsum|" ./testdata/grepinput3) >>testtry 2>&1
echo "RC=$?" >>testtry
echo "---------------------------- Test 105 -----------------------------" >>testtrygrep
(cd $srcdir; $valgrind $pcregrep --colour=always "ipsum|" ./testdata/grepinput3) >>testtrygrep 2>&1
echo "RC=$?" >>testtrygrep
echo "---------------------------- Test 106 -----------------------------" >>testtry
(cd $srcdir; echo "a" | $valgrind $pcregrep -M "|a" ) >>testtry 2>&1
echo "RC=$?" >>testtry
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
@ -518,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
@ -542,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

View file

@ -31,6 +31,11 @@
# 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.
@ -458,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
@ -467,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
@ -492,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
@ -989,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

6
pcre/aclocal.m4 vendored
View file

@ -1,4 +1,4 @@
# generated automatically by aclocal 1.14 -*- Autoconf -*-
# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
@ -250,7 +250,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[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.14], [],
m4_if([$1], [1.14.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@ -266,7 +266,7 @@ 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.14])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]))])

30
pcre/config.guess vendored
View file

@ -2,7 +2,7 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2013-06-10'
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
@ -1260,16 +1260,26 @@ EOF
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
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
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 ;;

View file

@ -236,7 +236,7 @@ sure both macros are undefined; an emulation function will then be used. */
#define PACKAGE_NAME "PCRE"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "PCRE 8.34"
#define PACKAGE_STRING "PCRE 8.35"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "pcre"
@ -245,7 +245,7 @@ sure both macros are undefined; an emulation function will then be used. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "8.34"
#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
@ -337,7 +337,7 @@ sure both macros are undefined; an emulation function will then be used. */
/* #undef SUPPORT_VALGRIND */
/* Version number of package */
#define VERSION "8.34"
#define VERSION "8.35"
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

17
pcre/config.sub vendored
View file

@ -2,7 +2,7 @@
# Configuration validation subroutine script.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2013-04-24'
timestamp='2013-10-01'
# 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
@ -257,7 +257,7 @@ case $basic_machine in
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | clipper \
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
@ -265,6 +265,7 @@ case $basic_machine in
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
@ -324,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
;;
@ -372,7 +373,7 @@ case $basic_machine in
| 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-* \
@ -381,6 +382,7 @@ case $basic_machine in
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
@ -794,7 +796,7 @@ case $basic_machine in
os=-mingw64
;;
mingw32)
basic_machine=i386-pc
basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
@ -830,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)
@ -1546,6 +1548,9 @@ case $basic_machine in
c4x-* | tic4x-*)
os=-coff
;;
c8051-*)
os=-elf
;;
hexagon-*)
os=-elf
;;

62
pcre/configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for PCRE 8.34.
# Generated by GNU Autoconf 2.69 for PCRE 8.35.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='PCRE'
PACKAGE_TARNAME='pcre'
PACKAGE_VERSION='8.34'
PACKAGE_STRING='PCRE 8.34'
PACKAGE_VERSION='8.35'
PACKAGE_STRING='PCRE 8.35'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@ -1415,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.34 to adapt to many kinds of systems.
\`configure' configures PCRE 8.35 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1485,7 +1485,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of PCRE 8.34:";;
short | recursive ) echo "Configuration of PCRE 8.35:";;
esac
cat <<\_ACEOF
@ -1553,7 +1553,7 @@ Optional Packages:
--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)
@ -1654,7 +1654,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
PCRE configure 8.34
PCRE configure 8.35
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -2411,7 +2411,7 @@ 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.34, which was
It was created by PCRE $as_me 8.35, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -3275,7 +3275,7 @@ fi
# Define the identity of the package.
PACKAGE='pcre'
VERSION='8.34'
VERSION='8.35'
cat >>confdefs.h <<_ACEOF
@ -17022,9 +17022,9 @@ _ACEOF
# Versioning
PCRE_MAJOR="8"
PCRE_MINOR="34"
PCRE_MINOR="35"
PCRE_PRERELEASE=""
PCRE_DATE="2013-12-15"
PCRE_DATE="2014-04-04"
if test "$PCRE_MINOR" = "08" -o "$PCRE_MINOR" = "09"
then
@ -17561,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"
@ -17574,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"
@ -18468,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
@ -18865,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
@ -18912,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
@ -19024,13 +19046,13 @@ esac
# (Note: The libpcre*_version bits are m4 variables, assigned above)
EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \
$NO_UNDEFINED -version-info 3:2:2"
$NO_UNDEFINED -version-info 3:3:2"
EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \
$NO_UNDEFINED -version-info 2:2:2"
$NO_UNDEFINED -version-info 2:3:2"
EXTRA_LIBPCRE32_LDFLAGS="$EXTRA_LIBPCRE32_LDFLAGS \
$NO_UNDEFINED -version-info 0:2:0"
$NO_UNDEFINED -version-info 0:3:0"
EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \
$NO_UNDEFINED -version-info 0:2:0"
@ -20085,7 +20107,7 @@ 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.34, which 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
@ -20151,7 +20173,7 @@ _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.34
PCRE config.status 8.35
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View file

@ -9,17 +9,17 @@ 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, [34])
m4_define(pcre_minor, [35])
m4_define(pcre_prerelease, [])
m4_define(pcre_date, [2013-12-15])
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:2:2])
m4_define(libpcre16_version, [2:2:2])
m4_define(libpcre32_version, [0:2: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])
@ -248,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
@ -461,7 +461,8 @@ 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"
@ -686,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
@ -739,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], [

View file

@ -85,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 <prefix>/share/doc/pcre, where
<prefix> 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
<prefix>/share/doc/pcre, where <prefix> 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
@ -372,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,
@ -987,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: 05 November 2013
Last updated: 17 January 2014

View file

@ -154,8 +154,11 @@ 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 <b>pcredemo</b> section, are concatenated, for ease
of searching. The sections are as follows:
the descriptions of the <b>pcregrep</b> and <b>pcretest</b> programs are in files
called <b>pcregrep.txt</b> and <b>pcretest.txt</b>, respectively. The remaining
sections, except for the <b>pcredemo</b> section (which is a program listing),
are concatenated in <b>pcre.txt</b>, for ease of searching. The sections are as
follows:
<pre>
pcre this document
pcre-config show PCRE installation configuration information
@ -182,8 +185,8 @@ of searching. The sections are as follows:
pcretest description of the <b>pcretest</b> testing command
pcreunicode discussion of Unicode and UTF-8/16/32 support
</pre>
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.
</P>
<br><a name="SEC4" href="#TOC1">AUTHOR</a><br>
<P>
@ -201,9 +204,9 @@ two digits 10, at the domain cam.ac.uk.
</P>
<br><a name="SEC5" href="#TOC1">REVISION</a><br>
<P>
Last updated: 13 May 2013
Last updated: 08 January 2014
<br>
Copyright &copy; 1997-2013 University of Cambridge.
Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.

View file

@ -166,6 +166,9 @@ man page, in case the conversion went wrong.
<br>
<br>
<b>int (*pcre_callout)(pcre_callout_block *);</b>
<br>
<br>
<b>int (*pcre_stack_guard)(void);</b>
</P>
<br><a name="SEC5" href="#TOC1">PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES</a><br>
<P>
@ -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
<a href="pcrecallout.html"><b>pcrecallout</b></a>
documentation.
</P>
<P>
The global variable <b>pcre_stack_guard</b> 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.
<a name="newlines"></a></P>
<br><a name="SEC7" href="#TOC1">NEWLINES</a><br>
<P>
@ -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 <b>pcre_malloc</b>,
<b>pcre_free</b>, <b>pcre_stack_malloc</b>, and <b>pcre_stack_free</b>, and the
callout function pointed to by <b>pcre_callout</b>, are shared by all threads.
callout and stack-checking functions pointed to by <b>pcre_callout</b> and
<b>pcre_stack_guard</b>, are shared by all threads.
</P>
<P>
The compiled form of a regular expression is not altered during matching, so
@ -489,7 +502,10 @@ documentation.
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.
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 <b>pcre_stack_guard</b>.
<pre>
PCRE_CONFIG_MATCH_LIMIT
</pre>
@ -1008,6 +1024,8 @@ have fallen out of use. To avoid confusion, they have not been re-used.
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)
</pre>
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.
@ -1265,12 +1283,15 @@ information call is provided for internal use by the <b>pcre_study()</b>
function. External callers can cause PCRE to use its internal tables by passing
a NULL table pointer.
<pre>
PCRE_INFO_FIRSTBYTE
PCRE_INFO_FIRSTBYTE (deprecated)
</pre>
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 <b>int</b>
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 <b>int</b>
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>
<P>
If there is a fixed first value, for example, the letter "c" from a pattern
@ -1293,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.
<pre>
PCRE_INFO_FIRSTCHARACTER
</pre>
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 <b>uint_t</b>
variable.
</P>
<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.
<pre>
PCRE_INFO_FIRSTCHARACTERFLAGS
</pre>
Return information about the first data unit of any matched string, for a
non-anchored pattern. The fourth argument should point to an <b>int</b>
variable.
</P>
<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
<br>
<br>
(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
starts with "^", or
<br>
<br>
(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set
(if it were set, the pattern would be anchored),
<br>
<br>
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.
<pre>
PCRE_INFO_FIRSTTABLE
</pre>
@ -1508,44 +1560,6 @@ above). The format of the <i>study_data</i> block is private, but its length
is made available via this option so that it can be saved and restored (see the
<a href="pcreprecompile.html"><b>pcreprecompile</b></a>
documentation for details).
<pre>
PCRE_INFO_FIRSTCHARACTERFLAGS
</pre>
Return information about the first data unit of any matched string, for a
non-anchored pattern. The fourth argument should point to an <b>int</b>
variable.
</P>
<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>
<P>
If there is no fixed first value, and if either
<br>
<br>
(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
starts with "^", or
<br>
<br>
(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set
(if it were set, the pattern would be anchored),
<br>
<br>
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.
<pre>
PCRE_INFO_FIRSTCHARACTER
</pre>
Return the fixed first character value in the situation where
PCRE_INFO_FIRSTCHARACTERFLAGS returns 1; otherwise return 0. The fourth
argument should point to an <b>uint_t</b> variable.
</P>
<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.
<pre>
PCRE_INFO_REQUIREDCHARFLAGS
</pre>
@ -2899,9 +2913,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC26" href="#TOC1">REVISION</a><br>
<P>
Last updated: 12 November 2013
Last updated: 09 February 2014
<br>
Copyright &copy; 1997-2013 University of Cambridge.
Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.

View file

@ -37,8 +37,10 @@ man page, in case the conversion went wrong.
<b>pcregrep</b> 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
<a href="pcresyntax.html"><b>pcresyntax</b>(3)</a>
for a quick-reference summary of pattern syntax, or
<a href="pcrepattern.html"><b>pcrepattern</b>(3)</a>
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>
<P>
@ -748,9 +750,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC14" href="#TOC1">REVISION</a><br>
<P>
Last updated: 13 September 2012
Last updated: 03 April 2014
<br>
Copyright &copy; 1997-2012 University of Cambridge.
Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.

View file

@ -1003,7 +1003,9 @@ matches "foobar", the first substring is still set to "foo".
<P>
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.
<a name="smallassertions"></a></P>
<br><b>
Simple assertions
@ -2990,19 +2992,22 @@ 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
<b>pcretest</b> example:
output from <b>pcretest</b>:
<pre>
re&#62; /(*COMMIT)abc/
data&#62; xyzabc
0: abc
xyzabc\Y
data&#62; xyzabc\Y
No match
</pre>
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 <b>pcretest</b> program. It causes
the PCRE_NO_START_OPTIMIZE option to be set when <b>pcre_exec()</b> 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.
<pre>
(*PRUNE) or (*PRUNE:NAME)
</pre>
@ -3221,9 +3226,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC30" href="#TOC1">REVISION</a><br>
<P>
Last updated: 03 December 2013
Last updated: 08 January 2014
<br>
Copyright &copy; 1997-2013 University of Cambridge.
Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.

View file

@ -29,13 +29,13 @@ man page, in case the conversion went wrong.
<li><a name="TOC14" href="#SEC14">ATOMIC GROUPS</a>
<li><a name="TOC15" href="#SEC15">COMMENT</a>
<li><a name="TOC16" href="#SEC16">OPTION SETTING</a>
<li><a name="TOC17" href="#SEC17">LOOKAHEAD AND LOOKBEHIND ASSERTIONS</a>
<li><a name="TOC18" href="#SEC18">BACKREFERENCES</a>
<li><a name="TOC19" href="#SEC19">SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)</a>
<li><a name="TOC20" href="#SEC20">CONDITIONAL PATTERNS</a>
<li><a name="TOC21" href="#SEC21">BACKTRACKING CONTROL</a>
<li><a name="TOC22" href="#SEC22">NEWLINE CONVENTIONS</a>
<li><a name="TOC23" href="#SEC23">WHAT \R MATCHES</a>
<li><a name="TOC17" href="#SEC17">NEWLINE CONVENTION</a>
<li><a name="TOC18" href="#SEC18">WHAT \R MATCHES</a>
<li><a name="TOC19" href="#SEC19">LOOKAHEAD AND LOOKBEHIND ASSERTIONS</a>
<li><a name="TOC20" href="#SEC20">BACKREFERENCES</a>
<li><a name="TOC21" href="#SEC21">SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)</a>
<li><a name="TOC22" href="#SEC22">CONDITIONAL PATTERNS</a>
<li><a name="TOC23" href="#SEC23">BACKTRACKING CONTROL</a>
<li><a name="TOC24" href="#SEC24">CALLOUTS</a>
<li><a name="TOC25" href="#SEC25">SEE ALSO</a>
<li><a name="TOC26" href="#SEC26">AUTHOR</a>
@ -339,7 +339,8 @@ but some of them use Unicode properties if PCRE_UCP is set. You can use
<P>
<pre>
\K reset start of match
</PRE>
</pre>
\K is honoured in positive assertions, but ignored in negative ones.
</P>
<br><a name="SEC12" href="#TOC1">ALTERNATION</a><br>
<P>
@ -382,11 +383,13 @@ but some of them use Unicode properties if PCRE_UCP is set. You can use
(?x) extended (ignore white space)
(?-...) unset option(s)
</pre>
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.
<pre>
(*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)
@ -397,7 +400,28 @@ newline-setting options with similar syntax:
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.
</P>
<br><a name="SEC17" href="#TOC1">LOOKAHEAD AND LOOKBEHIND ASSERTIONS</a><br>
<br><a name="SEC17" href="#TOC1">NEWLINE CONVENTION</a><br>
<P>
These are recognized only at the very start of the pattern or after option
settings with a similar syntax.
<pre>
(*CR) carriage return only
(*LF) linefeed only
(*CRLF) carriage return followed by linefeed
(*ANYCRLF) all three of the above
(*ANY) any Unicode newline sequence
</PRE>
</P>
<br><a name="SEC18" href="#TOC1">WHAT \R MATCHES</a><br>
<P>
These are recognized only at the very start of the pattern or after option
setting with a similar syntax.
<pre>
(*BSR_ANYCRLF) CR, LF, or CRLF
(*BSR_UNICODE) any Unicode newline sequence
</PRE>
</P>
<br><a name="SEC19" href="#TOC1">LOOKAHEAD AND LOOKBEHIND ASSERTIONS</a><br>
<P>
<pre>
(?=...) positive look ahead
@ -407,7 +431,7 @@ limits set by the caller of pcre_exec(), not increase them.
</pre>
Each top-level branch of a look behind must be of a fixed length.
</P>
<br><a name="SEC18" href="#TOC1">BACKREFERENCES</a><br>
<br><a name="SEC20" href="#TOC1">BACKREFERENCES</a><br>
<P>
<pre>
\n reference by number (can be ambiguous)
@ -421,7 +445,7 @@ Each top-level branch of a look behind must be of a fixed length.
(?P=name) reference by name (Python)
</PRE>
</P>
<br><a name="SEC19" href="#TOC1">SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)</a><br>
<br><a name="SEC21" href="#TOC1">SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)</a><br>
<P>
<pre>
(?R) recurse whole pattern
@ -440,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)
</PRE>
</P>
<br><a name="SEC20" href="#TOC1">CONDITIONAL PATTERNS</a><br>
<br><a name="SEC22" href="#TOC1">CONDITIONAL PATTERNS</a><br>
<P>
<pre>
(?(condition)yes-pattern)
@ -459,7 +483,7 @@ Each top-level branch of a look behind must be of a fixed length.
(?(assert)... assertion condition
</PRE>
</P>
<br><a name="SEC21" href="#TOC1">BACKTRACKING CONTROL</a><br>
<br><a name="SEC23" href="#TOC1">BACKTRACKING CONTROL</a><br>
<P>
The following act immediately they are reached:
<pre>
@ -482,27 +506,6 @@ pattern is not anchored.
(*THEN:NAME) equivalent to (*MARK:NAME)(*THEN)
</PRE>
</P>
<br><a name="SEC22" href="#TOC1">NEWLINE CONVENTIONS</a><br>
<P>
These are recognized only at the very start of the pattern or after a
(*BSR_...), (*UTF8), (*UTF16), (*UTF32) or (*UCP) option.
<pre>
(*CR) carriage return only
(*LF) linefeed only
(*CRLF) carriage return followed by linefeed
(*ANYCRLF) all three of the above
(*ANY) any Unicode newline sequence
</PRE>
</P>
<br><a name="SEC23" href="#TOC1">WHAT \R MATCHES</a><br>
<P>
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.
<pre>
(*BSR_ANYCRLF) CR, LF, or CRLF
(*BSR_UNICODE) any Unicode newline sequence
</PRE>
</P>
<br><a name="SEC24" href="#TOC1">CALLOUTS</a><br>
<P>
<pre>
@ -526,9 +529,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC27" href="#TOC1">REVISION</a><br>
<P>
Last updated: 12 November 2013
Last updated: 08 January 2014
<br>
Copyright &copy; 1997-2013 University of Cambridge.
Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.

View file

@ -138,6 +138,9 @@ following options output the value and set the exit code as indicated:
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
</pre>
The following options output 1 for true or 0 for false, and set the exit code
to the same value:
@ -373,6 +376,7 @@ sections.
<b>/N</b> set PCRE_NO_AUTO_CAPTURE
<b>/O</b> set PCRE_NO_AUTO_POSSESS
<b>/P</b> use the POSIX wrapper
<b>/Q</b> test external stack check function
<b>/S</b> study the pattern after compilation
<b>/s</b> set PCRE_DOTALL
<b>/T</b> select character tables
@ -534,7 +538,10 @@ below.
The <b>/I</b> modifier requests that <b>pcretest</b> output information about the
compiled pattern (whether it is anchored, has a fixed first character, and
so on). It does this by calling <b>pcre[16|32]_fullinfo()</b> 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>
<P>
The <b>/K</b> modifier requests <b>pcretest</b> to show names from backtracking
@ -568,6 +575,14 @@ successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the
JIT compiled code is also output.
</P>
<P>
The <b>/Q</b> modifier is used to test the use of <b>pcre_stack_guard</b>. 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
<a href="pcreapi.html"><b>pcreapi</b></a>
documentation for details).
</P>
<P>
The <b>/S</b> modifier causes <b>pcre[16|32]_study()</b> 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 <b>/S</b>.
@ -1134,9 +1149,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC17" href="#TOC1">REVISION</a><br>
<P>
Last updated: 12 November 2013
Last updated: 09 February 2014
<br>
Copyright &copy; 1997-2013 University of Cambridge.
Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.

View file

@ -1,4 +1,4 @@
.TH PCRE 3 "01 Oct 2013" "PCRE 8.33"
.TH PCRE 3 "08 January 2014" "PCRE 8.35"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH INTRODUCTION
@ -158,8 +158,11 @@ 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
@ -188,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
@ -210,6 +213,6 @@ two digits 10, at the domain cam.ac.uk.
.rs
.sp
.nf
Last updated: 13 May 2013
Copyright (c) 1997-2013 University of Cambridge.
Last updated: 08 January 2014
Copyright (c) 1997-2014 University of Cambridge.
.fi

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
.TH PCREAPI 3 "12 November 2013" "PCRE 8.34"
.TH PCREAPI 3 "09 February 2014" "PCRE 8.35"
.SH NAME
PCRE - Perl-compatible regular expressions
.sp
@ -116,6 +116,8 @@ PCRE - Perl-compatible regular expressions
.B void (*pcre_stack_free)(void *);
.sp
.B int (*pcre_callout)(pcre_callout_block *);
.sp
.B int (*pcre_stack_guard)(void);
.fi
.
.
@ -286,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 <a name="newlines"></a>
@ -337,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.
@ -465,7 +476,10 @@ documentation.
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.
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
@ -991,6 +1005,8 @@ have fallen out of use. To avoid confusion, they have not been re-used.
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.
@ -1248,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
@ -1271,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
@ -1498,38 +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 in the situation where
PCRE_INFO_FIRSTCHARACTERFLAGS returns 1; otherwise return 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.
.sp
PCRE_INFO_REQUIREDCHARFLAGS
.sp
@ -2900,6 +2914,6 @@ Cambridge CB2 3QH, England.
.rs
.sp
.nf
Last updated: 12 November 2013
Copyright (c) 1997-2013 University of Cambridge.
Last updated: 09 February 2014
Copyright (c) 1997-2014 University of Cambridge.
.fi

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
.TH PCREPATTERN 3 "03 December 2013" "PCRE 8.34"
.TH PCREPATTERN 3 "08 January 2014" "PCRE 8.35"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE REGULAR EXPRESSION DETAILS"
@ -1004,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 <a name="smallassertions"></a>
@ -3028,19 +3030,22 @@ 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
@ -3255,6 +3260,6 @@ Cambridge CB2 3QH, England.
.rs
.sp
.nf
Last updated: 03 December 2013
Copyright (c) 1997-2013 University of Cambridge.
Last updated: 08 January 2014
Copyright (c) 1997-2014 University of Cambridge.
.fi

View file

@ -1,4 +1,4 @@
.TH PCRESYNTAX 3 "12 November 2013" "PCRE 8.34"
.TH PCRESYNTAX 3 "08 January 2014" "PCRE 8.35"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE REGULAR EXPRESSION SYNTAX SUMMARY"
@ -309,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"
@ -354,11 +356,13 @@ 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)
@ -370,6 +374,29 @@ 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"
.rs
.sp
@ -457,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
@ -508,6 +512,6 @@ Cambridge CB2 3QH, England.
.rs
.sp
.nf
Last updated: 12 November 2013
Copyright (c) 1997-2013 University of Cambridge.
Last updated: 08 January 2014
Copyright (c) 1997-2014 University of Cambridge.
.fi

View file

@ -1,4 +1,4 @@
.TH PCRETEST 1 "12 November 2013" "PCRE 8.34"
.TH PCRETEST 1 "09 February 2014" "PCRE 8.35"
.SH NAME
pcretest - a program for testing Perl-compatible regular expressions.
.SH SYNOPSIS
@ -113,6 +113,9 @@ following options output the value and set the exit code as indicated:
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 0 for false, and set the exit code
to the same value:
@ -330,6 +333,7 @@ sections.
\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
@ -483,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
@ -513,6 +520,15 @@ 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.
@ -1135,6 +1151,6 @@ Cambridge CB2 3QH, England.
.rs
.sp
.nf
Last updated: 12 November 2013
Copyright (c) 1997-2013 University of Cambridge.
Last updated: 09 February 2014
Copyright (c) 1997-2014 University of Cambridge.
.fi

View file

@ -99,6 +99,9 @@ COMMAND LINE OPTIONS
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 0 for false, and
set the exit code to the same value:
@ -316,6 +319,7 @@ PATTERN MODIFIERS
/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
@ -462,7 +466,9 @@ PATTERN MODIFIERS
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.
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 con-
trol verbs that are returned from calls to pcre[16|32]_exec(). It
@ -493,26 +499,31 @@ PATTERN MODIFIERS
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
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
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,
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,
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
@ -523,40 +534,40 @@ PATTERN MODIFIERS
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
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
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
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
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-
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
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-
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-
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
@ -567,48 +578,48 @@ PATTERN MODIFIERS
/W REG_UCP ) the POSIX standard
/8 REG_UTF8 )
The /+ modifier works as described above. All other modifiers are
The /+ modifier works as described above. All other modifiers are
ignored.
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
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 mis-
take; 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 modi-
take; 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 modi-
fiers. If an input line for pcretest starts with the string "< forbid "
the following sequence of characters is taken as a list of forbidden
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 Uni-
code 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
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
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 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.
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)
@ -669,7 +680,7 @@ DATA LINES
(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
\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()
@ -678,7 +689,7 @@ DATA LINES
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
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()
@ -691,102 +702,102 @@ DATA LINES
\<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 hexa-
decimal digits inside the braces; invalid values provoke error mes-
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,
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
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,
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-
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
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-
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
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
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
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
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
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
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
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.
If a data line contains the \D escape sequence, or if the command line
contains the -dfa option, the alternative matching function is used.
This function finds all possible matches at a given point. If, however,
the \F escape sequence is present in the data line, it stops after the
the \F escape sequence is present in the data line, it stops after the
first match is found. This is always the shortest possible match.
DEFAULT OUTPUT FROM PCRETEST
This section describes the output when the normal matching function,
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
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
@ -800,10 +811,10 @@ DEFAULT OUTPUT FROM PCRETEST
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
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
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)/
@ -815,11 +826,11 @@ DEFAULT OUTPUT FROM PCRETEST
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.
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
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/+
@ -827,7 +838,7 @@ DEFAULT OUTPUT FROM PCRETEST
0: cat
0+ aract
If the pattern has the /g or /G modifier, the results of successive
If the pattern has the /g or /G modifier, the results of successive
matching attempts are output in sequence, like this:
re> /\Bi(\w\w)/g
@ -839,32 +850,32 @@ DEFAULT OUTPUT FROM PCRETEST
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
"No match" is output only if the first match attempt fails. Here is an
example of a failure message (the offset 4 that is specified by \>4 is
past the end of the subject string):
re> /xyz/
data> xyz\>4
Error -24 (bad offset value)
If any of the sequences \C, \G, or \L are present in a data line that
is successfully matched, the substrings extracted by the convenience
If any of the sequences \C, \G, or \L are present in a data line that
is successfully matched, the substrings extracted by the convenience
functions are output with C, G, or L after the string number instead of
a colon. This is in addition to the normal full list. The string length
(that is, the return from the extraction function) is given in paren-
(that is, the return from the extraction function) is given in paren-
theses after each string for \C and \G.
Note that whereas patterns can be continued over several lines (a plain
">" prompt is used for continuations), data lines may not. However new-
lines can be included in data by means of the \n escape (or \r, \r\n,
lines can be included in data by means of the \n escape (or \r, \r\n,
etc., depending on the newline sequence setting).
OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
When the alternative matching function, pcre[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
(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:
@ -874,11 +885,11 @@ OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
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).
(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
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.)
@ -894,16 +905,16 @@ OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
1: tan
0: tan
Since the matching function does not support substring capture, the
escape sequences that are concerned with captured substrings are not
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
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$/
@ -912,30 +923,30 @@ RESTARTING AFTER A PARTIAL MATCH
data> n05\R\D
0: n05
For further information about partial matching, see the pcrepartial
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-
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
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
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
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
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
@ -948,7 +959,7 @@ CALLOUTS
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
ever a change of latest mark is passed to the callout function. For
example:
re> /a(*MARK:X)bc/C
@ -962,104 +973,104 @@ CALLOUTS
+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
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)
The callout function in pcretest returns zero (carry on matching) by
default, but you can use a \C item in a data line (as described above)
to change this and other parameters of the callout.
Inserting callouts can be helpful when using pcretest to check compli-
cated regular expressions. For further information about callouts, see
Inserting callouts can be helpful when using pcretest to check compli-
cated regular expressions. For further information about callouts, see
the pcrecallout documentation.
NON-PRINTING CHARACTERS
When pcretest is outputting text in the compiled version of a pattern,
bytes other than 32-126 are always treated as non-printing characters
When pcretest is outputting text in the compiled version of a pattern,
bytes other than 32-126 are always treated as non-printing characters
are are therefore shown as hex escapes.
When pcretest is outputting text that is a matched part of a subject
string, it behaves in the same way, unless a different locale has been
set for the pattern (using the /L modifier). In this case, the
When pcretest is outputting text that is a matched part of a subject
string, it behaves in the same way, unless a different locale has been
set for the pattern (using the /L modifier). In this case, the
isprint() function to distinguish printing and non-printing characters.
SAVING AND RELOADING COMPILED PATTERNS
The facilities described in this section are not available when the
POSIX interface to PCRE is being used, that is, when the /P pattern
The facilities described in this section are not available when the
POSIX interface to PCRE is being used, that is, when the /P pattern
modifier is specified.
When the POSIX interface is not in use, you can cause pcretest to write
a compiled pattern to a file, by following the modifiers with > and a
a compiled pattern to a file, by following the modifiers with > and a
file name. For example:
/pattern/im >/some/file
See the pcreprecompile documentation for a discussion about saving and
re-using compiled patterns. Note that if the pattern was successfully
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
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
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. 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-
A saved pattern can be reloaded into pcretest by specifying < and a
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> </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
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
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
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
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
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 test-
ing 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
The ability to save and reload files in pcretest is intended for test-
ing 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,
pcre(3), pcre16(3), pcre32(3), pcreapi(3), pcrecallout(3), pcrejit,
pcrematching(3), pcrepartial(d), pcrepattern(3), pcreprecompile(3).
@ -1072,5 +1083,5 @@ AUTHOR
REVISION
Last updated: 12 November 2013
Copyright (c) 1997-2013 University of Cambridge.
Last updated: 09 February 2014
Copyright (c) 1997-2014 University of Cambridge.

View file

@ -1,7 +1,7 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2012-06-26.16; # UTC
scriptversion=2013-10-28.13; # UTC
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
@ -160,7 +160,7 @@ give_advice ()
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'automa4te' program to be rebuilt."
echo "the 'autom4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)

View file

@ -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-2013 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 34
#define PCRE_MINOR 35
#define PCRE_PRERELEASE
#define PCRE_DATE 2013-12-15
#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
@ -491,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. */

View file

@ -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-2013 University of Cambridge
Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -491,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. */

View file

@ -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-2013 University of Cambridge
Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -311,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 */

View file

@ -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-2013 University of Cambridge
Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -547,6 +547,8 @@ static const char error_texts[] =
"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
@ -3070,8 +3072,11 @@ 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_uint32 *set1, *set2, *set_end;
const pcre_uint8 *set1, *set2, *set_end;
pcre_uint32 chr;
BOOL accepted, invert_bits;
@ -3202,12 +3207,12 @@ for(;;)
if (base_list[0] == OP_CLASS)
#endif
{
set1 = (pcre_uint32 *)(base_end - base_list[2]);
set1 = (pcre_uint8 *)(base_end - base_list[2]);
list_ptr = list;
}
else
{
set1 = (pcre_uint32 *)(code - list[2]);
set1 = (pcre_uint8 *)(code - list[2]);
list_ptr = base_list;
}
@ -3216,41 +3221,53 @@ for(;;)
{
case OP_CLASS:
case OP_NCLASS:
set2 = (pcre_uint32 *)
set2 = (pcre_uint8 *)
((list_ptr == list ? code : base_end) - list_ptr[2]);
break;
/* OP_XCLASS cannot be supported here, because its bitset
is not necessarily complete. E.g: [a-\0x{200}] is stored
as a character range, and the appropriate bits are not set. */
#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 */
invert_bits = TRUE;
/* Fall through */
case OP_DIGIT:
set2 = (pcre_uint32 *)(cd->cbits + cbit_digit);
break;
set2 = (pcre_uint8 *)(cd->cbits + cbit_digit);
break;
case OP_NOT_WHITESPACE:
invert_bits = TRUE;
/* Fall through */
invert_bits = TRUE;
/* Fall through */
case OP_WHITESPACE:
set2 = (pcre_uint32 *)(cd->cbits + cbit_space);
break;
set2 = (pcre_uint8 *)(cd->cbits + cbit_space);
break;
case OP_NOT_WORDCHAR:
invert_bits = TRUE;
/* Fall through */
invert_bits = TRUE;
/* Fall through */
case OP_WORDCHAR:
set2 = (pcre_uint32 *)(cd->cbits + cbit_word);
break;
set2 = (pcre_uint8 *)(cd->cbits + cbit_word);
break;
default:
return FALSE;
}
/* Compare 4 bytes to improve speed. */
set_end = set1 + (32 / 4);
/* Because the sets are unaligned, we need
to perform byte comparison here. */
set_end = set1 + 32;
if (invert_bits)
{
do
@ -3551,7 +3568,9 @@ for(;;)
if (list[1] == 0) return TRUE;
}
return FALSE;
/* Control never reaches here. There used to be a fail-save return FALSE; here,
but some compilers complain about an unreachable statement. */
}
@ -3623,7 +3642,7 @@ for (;;)
break;
case OP_MINUPTO:
*code += OP_MINUPTO - OP_UPTO;
*code += OP_POSUPTO - OP_MINUPTO;
break;
}
}
@ -4062,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++;
}
@ -4105,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
@ -4148,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++;
@ -4173,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 */
{
@ -4228,6 +4251,7 @@ else
*uchardptr = uchardata; /* Updata extra data pointer */
}
#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
return n8; /* Number of 8-bit characters */
}
@ -4449,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;
@ -4783,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
@ -4798,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. */
@ -4927,6 +4961,7 @@ for (;; ptr++)
*class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP;
*class_uchardata++ = ptype;
*class_uchardata++ = 0;
xclass_has_prop = TRUE;
ptr = tempptr + 1;
continue;
@ -5109,6 +5144,7 @@ for (;; ptr++)
XCL_PROP : XCL_NOTPROP;
*class_uchardata++ = ptype;
*class_uchardata++ = pdata;
xclass_has_prop = TRUE;
class_has_8bitchar--; /* Undo! */
continue;
}
@ -5403,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. */
@ -5412,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));
}
@ -6580,7 +6619,10 @@ for (;; ptr++)
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. */
@ -6617,7 +6659,6 @@ for (;; ptr++)
if (refsign >= 0)
{
recno = 0;
while (IS_DIGIT(*ptr))
{
recno = recno * 10 + (int)(*ptr - CHAR_0);
@ -7994,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;

View file

@ -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-2013 University of Cambridge
Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -1473,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:
@ -1742,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:
@ -2012,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:
@ -2210,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);
}
@ -3466,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)
{
@ -3474,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++;
}
@ -3509,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++;
}
}
}
@ -3557,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
@ -3589,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; }
}
}
@ -3597,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;
}
@ -3665,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 ||

View file

@ -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-2013 University of Cambridge
Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -134,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
@ -237,8 +237,8 @@ if (caseless)
{
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++;
@ -254,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;
}
}
@ -2103,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);
@ -2147,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);
@ -2290,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);
@ -2444,7 +2444,7 @@ for (;;)
{
SCHECK_PARTIAL();
}
else if (RAWUCHARTEST(eptr) == CHAR_LF) eptr++;
else if (UCHAR21TEST(eptr) == CHAR_LF) eptr++;
break;
case CHAR_LF:
@ -2691,16 +2691,22 @@ for (;;)
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) break;
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;
}
if (count < 0)
length = (md->jscript_compat)? 0 : -1;
else
length = md->offset_vector[offset+1] - md->offset_vector[offset];
}
goto REF_REPEAT;
@ -3212,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
@ -3252,7 +3258,7 @@ for (;;)
if (fc < 128)
{
pcre_uint32 cc = RAWUCHAR(eptr);
pcre_uint32 cc = UCHAR21(eptr);
if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH);
ecode++;
eptr++;
@ -3521,7 +3527,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
cc = RAWUCHARTEST(eptr);
cc = UCHAR21TEST(eptr);
if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
eptr++;
}
@ -3539,7 +3545,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
cc = RAWUCHARTEST(eptr);
cc = UCHAR21TEST(eptr);
if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
eptr++;
}
@ -3556,7 +3562,7 @@ for (;;)
SCHECK_PARTIAL();
break;
}
cc = RAWUCHARTEST(eptr);
cc = UCHAR21TEST(eptr);
if (fc != cc && foc != cc) break;
eptr++;
}
@ -3583,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;
@ -3600,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 */
}
@ -3614,7 +3620,7 @@ for (;;)
SCHECK_PARTIAL();
break;
}
if (fc != RAWUCHARTEST(eptr)) break;
if (fc != UCHAR21TEST(eptr)) break;
eptr++;
}
if (possessive) continue; /* No backtracking */
@ -4369,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);
@ -4411,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:
@ -4521,7 +4527,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
cc = RAWUCHAR(eptr);
cc = UCHAR21(eptr);
if (cc >= 128 || (md->ctypes[cc] & ctype_digit) == 0)
RRETURN(MATCH_NOMATCH);
eptr++;
@ -4538,7 +4544,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
cc = RAWUCHAR(eptr);
cc = UCHAR21(eptr);
if (cc < 128 && (md->ctypes[cc] & ctype_space) != 0)
RRETURN(MATCH_NOMATCH);
eptr++;
@ -4555,7 +4561,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
cc = RAWUCHAR(eptr);
cc = UCHAR21(eptr);
if (cc >= 128 || (md->ctypes[cc] & ctype_space) == 0)
RRETURN(MATCH_NOMATCH);
eptr++;
@ -4572,7 +4578,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
cc = RAWUCHAR(eptr);
cc = UCHAR21(eptr);
if (cc < 128 && (md->ctypes[cc] & ctype_word) != 0)
RRETURN(MATCH_NOMATCH);
eptr++;
@ -4589,7 +4595,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
cc = RAWUCHAR(eptr);
cc = UCHAR21(eptr);
if (cc >= 128 || (md->ctypes[cc] & ctype_word) == 0)
RRETURN(MATCH_NOMATCH);
eptr++;
@ -5150,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:
@ -5689,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);
@ -5715,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);
@ -5772,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
{
@ -5935,8 +5941,8 @@ for (;;)
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
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
@ -6783,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++;
}
@ -6818,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++;
}
}
@ -6829,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 */
@ -6897,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; }
}
}
@ -6905,7 +6901,7 @@ for(;;)
{
while (p < end_subject)
{
if (RAWUCHARINCTEST(p) == req_char) { p--; break; }
if (UCHAR21INCTEST(p) == req_char) { p--; break; }
}
}

View file

@ -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 */

View file

@ -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-2013 University of Cambridge
Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -316,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]) \
) \
)
@ -330,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]) \
) \
)
@ -582,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
@ -600,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) */
@ -776,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. */
@ -895,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
@ -980,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
@ -1874,8 +1813,9 @@ table. */
/* 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 */
@ -2341,7 +2281,7 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
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, ERR78, ERR79,
ERR80, ERR81, ERR82, ERR83, ERR84, ERRCOUNT };
ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERRCOUNT };
/* JIT compiling modes. The function list is indexed by them. */

File diff suppressed because it is too large Load diff

View file

@ -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)
@ -326,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_" },
@ -371,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" },
@ -629,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" },
@ -959,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);
@ -1031,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);
@ -1092,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;
@ -1173,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;
@ -1211,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
@ -1242,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
@ -1273,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
@ -1305,10 +1327,10 @@ 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) {
@ -1317,7 +1339,7 @@ static int regression_tests(void)
}
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
@ -1339,10 +1361,10 @@ 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) {
@ -1351,7 +1373,7 @@ static int regression_tests(void)
}
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
@ -1373,10 +1395,10 @@ 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) {
@ -1385,7 +1407,7 @@ static int regression_tests(void)
}
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
@ -1581,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);
@ -1596,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);
@ -1611,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);

View file

@ -644,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, " [");
@ -653,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
{
@ -666,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)

View file

@ -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-2013 University of Cambridge
Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -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;

View file

@ -879,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. */
@ -1257,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)
@ -1273,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
@ -1282,31 +1302,35 @@ 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:

View file

@ -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 */

View file

@ -12,7 +12,7 @@ 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-2013 University of Cambridge
Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -1298,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:

View file

@ -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
@ -170,7 +170,9 @@ static const int eint[] = {
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 */
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 */

View file

@ -233,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)
@ -317,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)
@ -406,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)
@ -533,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) \
@ -756,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))
@ -897,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
@ -927,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
@ -957,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
@ -1015,6 +1041,7 @@ 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 const unsigned char *last_callout_mark = NULL;
@ -2200,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 *
*************************************************/
@ -2883,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");
@ -2892,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");
@ -3231,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
@ -3439,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);
@ -3739,6 +3785,21 @@ while (!done)
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 (;;)
@ -4282,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)
@ -5192,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)
{
@ -5208,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);

View file

@ -44,9 +44,11 @@
/* #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 */
@ -106,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

View file

@ -59,9 +59,11 @@
|| (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) \
@ -75,10 +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
@ -102,12 +106,16 @@
#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__) && !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__)
@ -275,7 +283,9 @@ typedef signed int sljit_si;
typedef unsigned long int sljit_uw;
typedef long int sljit_sw;
#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
@ -353,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
@ -367,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
@ -383,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
@ -420,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

View file

@ -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,15 +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 IS_JAL 0x04
# define IS_COND 0x08
# define PATCH_B 0x10
# define PATCH_J 0x20
# define PATCH_B 0x10
# define PATCH_J 0x20
#endif
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
@ -215,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))
@ -234,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))
@ -343,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
@ -418,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;
@ -534,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() \
@ -548,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; \
}
@ -600,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();
@ -617,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();
@ -631,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
@ -670,7 +709,7 @@ static char* freg_names[] = {
(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
@ -684,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 \
@ -704,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 \
@ -941,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, ", ");
@ -983,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, ", ");
@ -1225,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) {
@ -1340,24 +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.c"
# 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,
@ -1371,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) {

View file

@ -265,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;
@ -478,11 +484,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
/* Register output: simply the name of the register.
For destination, you can use SLJIT_UNUSED as well. */
#define SLJIT_MEM 0x100
#define SLJIT_MEM 0x80
#define SLJIT_MEM0() (SLJIT_MEM)
#define SLJIT_MEM1(r1) (SLJIT_MEM | (r1))
#define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 4))
#define SLJIT_IMM 0x200
#define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8))
#define SLJIT_IMM 0x40
/* Set 32 bit operation mode (I) on 64 bit CPUs. The flag is totally ignored on
32 bit CPUs. If this flag is set for an arithmetic operation, it uses only the
@ -494,12 +500,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
is specified, all register arguments must be the result of other operations with
the same SLJIT_INT_OP flag. In other words, although a register can hold either
a 64 or 32 bit value, these values cannot be mixed. The only exceptions are
SLJIT_IMOV and SLJIT_IMOVU (SLJIT_MOV_SI/SLJIT_MOV_UI/SLJIT_MOVU_SI/SLJIT_MOV_UI
with SLJIT_INT_OP flag) which can convert any source argument to SLJIT_INT_OP
compatible result. This conversion might be unnecessary on some CPUs like x86-64,
since the upper 32 bit is always ignored. In this case SLJIT is clever enough
to not generate any instructions if the source and destination operands are the
same registers. Affects sljit_emit_op0, sljit_emit_op1 and sljit_emit_op2. */
SLJIT_IMOV and SLJIT_IMOVU (SLJIT_MOV_SI/SLJIT_MOVU_SI with SLJIT_INT_OP flag)
which can convert any source argument to SLJIT_INT_OP compatible result. This
conversion might be unnecessary on some CPUs like x86-64, since the upper 32
bit is always ignored. In this case SLJIT is clever enough to not generate any
instructions if the source and destination operands are the same registers.
Affects sljit_emit_op0, sljit_emit_op1 and sljit_emit_op2. */
#define SLJIT_INT_OP 0x100
/* Single precision mode (SP). This flag is similar to SLJIT_INT_OP, just
@ -525,10 +531,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
/* Set Equal (Zero) status flag (E). */
#define SLJIT_SET_E 0x0200
/* Set unsigned status flag (U). */
#define SLJIT_SET_U 0x0400
/* Set signed status flag (S). */
#define SLJIT_SET_S 0x0400
/* Set unsgined status flag (U). */
#define SLJIT_SET_U 0x0800
#define SLJIT_SET_S 0x0800
/* Set signed overflow flag (O). */
#define SLJIT_SET_O 0x1000
/* Set carry flag (C).
@ -575,7 +581,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op);
/* Notes for MOV instructions:
U = Mov with update (post form). If source or destination defined as SLJIT_MEM1(r1)
U = Mov with update (pre form). If source or destination defined as SLJIT_MEM1(r1)
or SLJIT_MEM2(r1, r2), r1 is increased by the sum of r2 and the constant argument
UB = unsigned byte (8 bit)
SB = signed byte (8 bit)
@ -602,7 +608,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
/* Flags: I - (never set any flags)
Note: see SLJIT_INT_OP for further details. */
#define SLJIT_MOV_UI 11
/* No SLJIT_INT_OP form, since it the same as SLJIT_IMOVU. */
/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOV. */
/* Flags: I - (never set any flags)
Note: see SLJIT_INT_OP for further details. */
#define SLJIT_MOV_SI 12
@ -626,7 +632,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
/* Flags: I - (never set any flags)
Note: see SLJIT_INT_OP for further details. */
#define SLJIT_MOVU_UI 19
/* No SLJIT_INT_OP form, since it the same as SLJIT_IMOVU. */
/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOVU. */
/* Flags: I - (never set any flags)
Note: see SLJIT_INT_OP for further details. */
#define SLJIT_MOVU_SI 20
@ -656,7 +662,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
/* Flags: I | C | K */
#define SLJIT_ADDC 26
#define SLJIT_IADDC (SLJIT_ADDC | SLJIT_INT_OP)
/* Flags: I | E | S | U | O | C | K */
/* Flags: I | E | U | S | O | C | K */
#define SLJIT_SUB 27
#define SLJIT_ISUB (SLJIT_SUB | SLJIT_INT_OP)
/* Flags: I | C | K */
@ -851,8 +857,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile
/* Set the destination of the jump to this label. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);
/* Only for jumps defined with SLJIT_REWRITABLE_JUMP flag.
Note: use sljit_emit_ijump for fixed jumps. */
/* Set the destination address of the jump to this label. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target);
/* Call function or jump anywhere. Both direct and indirect form

View file

@ -1379,54 +1379,57 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm));
return -1;
}
return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
return 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 (!(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 & 0xf,
RM((arg >> 4) & 0xf) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7)));
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 (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
return 0;
}
/* See getput_arg below.
@ -1439,10 +1442,10 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_
return 0;
/* Always a simple operation. */
if (arg & 0xf0)
if (arg & OFFS_REG_MASK)
return 0;
if (!(arg & 0xf)) {
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;
@ -1469,7 +1472,7 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_
#define TEST_WRITE_BACK() \
if (inp_flags & WRITE_BACK) { \
tmp_r = arg & 0xf; \
tmp_r = arg & REG_MASK; \
if (reg == tmp_r) { \
/* This can only happen for stores */ \
/* since ldr reg, [reg, ...]! has no meaning */ \
@ -1497,7 +1500,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3;
max_delta = IS_TYPE1_TRANSFER(inp_flags) ? 0xfff : 0xff;
if ((arg & 0xf) == SLJIT_UNUSED) {
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)) {
@ -1530,11 +1533,11 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
return SLJIT_SUCCESS;
}
if (arg & 0xf0) {
if (arg & OFFS_REG_MASK) {
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)));
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;
}
@ -1555,7 +1558,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
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));
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;
}
@ -1564,14 +1567,14 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
if (imm) {
argw = -argw;
TEST_WRITE_BACK();
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & 0xf, imm));
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 & 0xf, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
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;
}
@ -1583,7 +1586,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
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)));
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;
}
@ -1591,7 +1594,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
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]));
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;
@ -1600,14 +1603,14 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
return SLJIT_SUCCESS;
}
if ((arg & 0xf) == tmp_r) {
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 & 0xf, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0)));
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;
}
@ -1653,7 +1656,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 <= TMP_REG3) {
else if (FAST_IS_REG(dst)) {
dst_r = dst;
flags |= REG_DEST;
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
@ -1672,9 +1675,9 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i
}
/* Source 1. */
if (src1 <= TMP_REG3)
if (FAST_IS_REG(src1))
src1_r = src1;
else if (src2 <= TMP_REG3) {
else if (FAST_IS_REG(src2)) {
flags |= ARGS_SWAPPED;
src1_r = src2;
src2 = src1;
@ -1720,7 +1723,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i
/* Source 2. */
if (src2_r == 0) {
if (src2 <= TMP_REG3) {
if (FAST_IS_REG(src2)) {
src2_r = src2;
flags |= REG_SOURCE;
if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
@ -2026,9 +2029,13 @@ static void init_compiler(void)
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
@ -2056,18 +2063,18 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
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)));
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 & 0xf)) {
if ((arg & REG_MASK)) {
if (!(argw & ~0x3fc))
return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & 0xf, reg, argw >> 2));
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 & 0xf, reg, (-argw) >> 2));
return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & REG_MASK, reg, (-argw) >> 2));
}
if (compiler->cache_arg == arg) {
@ -2083,29 +2090,29 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
}
}
if (arg & 0xf) {
if (emit_set_delta(compiler, TMP_REG1, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED) {
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 & 0xf, 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 & 0xf, imm));
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 & 0xf) {
if (arg & REG_MASK) {
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]));
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));
@ -2128,11 +2135,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
op ^= SLJIT_SINGLE_OP;
if (GET_OPCODE(op) == SLJIT_CMPD) {
if (dst > SLJIT_FLOAT_REG6) {
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_FLOAT_REG6) {
if (src & SLJIT_MEM) {
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src, srcw));
src = TMP_FREG2;
}
@ -2141,9 +2148,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
return SLJIT_SUCCESS;
}
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_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_fr, src, srcw));
src = dst_fr;
}
@ -2184,14 +2191,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
compiler->cache_argw = 0;
op ^= SLJIT_SINGLE_OP;
dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst;
dst_fr = FAST_IS_REG(dst) ? dst : TMP_FREG1;
if (src2 > SLJIT_FLOAT_REG6) {
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_FLOAT_REG6) {
if (src1 & SLJIT_MEM) {
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w));
src1 = TMP_FREG1;
}
@ -2238,7 +2245,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, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3)));
/* Memory. */
@ -2257,7 +2264,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))
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))
@ -2398,26 +2405,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
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)
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);
@ -2425,6 +2414,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
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;
}
@ -2446,7 +2451,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
op = GET_OPCODE(op);
cc = get_cc(type);
dst_r = (dst <= TMP_REG3) ? dst : TMP_REG2;
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));
@ -2455,7 +2460,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
}
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) {
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;
@ -2493,7 +2498,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
PTR_FAIL_IF(!const_);
reg = (dst <= TMP_REG3) ? dst : TMP_REG2;
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));
@ -2503,7 +2508,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
#endif
set_const(const_, compiler);
if (reg == TMP_REG2 && dst != SLJIT_UNUSED)
if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
return const_;
}

File diff suppressed because it is too large Load diff

View file

@ -207,7 +207,7 @@ static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, s
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)
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));
@ -238,33 +238,33 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh
if (jump->flags & IS_COND) {
SLJIT_ASSERT(!(jump->flags & IS_BL));
if (diff <= 127 && diff >= -128) {
jump->flags |= B_TYPE1;
jump->flags |= PATCH_TYPE1;
return 5;
}
if (diff <= 524287 && diff >= -524288) {
jump->flags |= B_TYPE2;
jump->flags |= PATCH_TYPE2;
return 4;
}
/* +1 comes from the prefix IT instruction. */
diff--;
if (diff <= 8388607 && diff >= -8388608) {
jump->flags |= B_TYPE3;
jump->flags |= PATCH_TYPE3;
return 3;
}
}
else if (jump->flags & IS_BL) {
if (diff <= 8388607 && diff >= -8388608) {
jump->flags |= BL_TYPE6;
jump->flags |= PATCH_BL;
return 3;
}
}
else {
if (diff <= 1023 && diff >= -1024) {
jump->flags |= B_TYPE4;
jump->flags |= PATCH_TYPE4;
return 4;
}
if (diff <= 8388607 && diff >= -8388608) {
jump->flags |= B_TYPE5;
jump->flags |= PATCH_TYPE5;
return 3;
}
}
@ -272,15 +272,6 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh
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;
@ -289,7 +280,7 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump)
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);
modify_imm32_const((sljit_uh*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);
return;
}
@ -425,6 +416,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
return (void*)((sljit_uw)code | 0x1);
}
/* --------------------------------------------------------------------- */
/* Core code generator functions. */
/* --------------------------------------------------------------------- */
#define INVALID_IMM 0x80000000
static sljit_uw get_imm(sljit_uw imm)
{
@ -502,7 +497,6 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl
#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
@ -516,7 +510,7 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
arg1 must be register, TMP_REG1, imm
arg2 must be register, TMP_REG2, imm */
sljit_si reg;
sljit_uw imm, negated_imm;
sljit_uw imm, nimm;
if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
/* Both are immediates. */
@ -530,6 +524,10 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
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);
@ -537,30 +535,27 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
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. */
Although some clever things could be done here, "NOT IMM" does not worth the efforts. */
break;
case SLJIT_ADD:
negated_imm = (sljit_uw)-(sljit_sw)imm;
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 (negated_imm <= 0x7)
return push_inst16(compiler, SUBSI3 | IMM3(negated_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 (negated_imm <= 0xff)
return push_inst16(compiler, SUBSI8 | IMM8(negated_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 (negated_imm <= 0xfff)
return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(negated_imm));
if (nimm <= 0xfff)
return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(nimm));
}
imm = get_imm(imm);
if (imm != INVALID_IMM)
@ -572,63 +567,59 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
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 & 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;
}
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);
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));
}
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));
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, 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;
@ -638,50 +629,32 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
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));
}
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));
}
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));
}
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));
}
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));
}
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));
}
break;
default:
SLJIT_ASSERT_STOP();
break;
@ -708,6 +681,8 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
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:
@ -834,7 +809,7 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
s = store
*/
static SLJIT_CONST sljit_uw sljit_mem16[12] = {
static SLJIT_CONST sljit_ins sljit_mem16[12] = {
/* w u l */ 0x5800 /* ldr */,
/* w u s */ 0x5000 /* str */,
/* w s l */ 0x5800 /* ldr */,
@ -851,7 +826,7 @@ static SLJIT_CONST sljit_uw sljit_mem16[12] = {
/* h s s */ 0x5200 /* strh */,
};
static SLJIT_CONST sljit_uw sljit_mem16_imm5[12] = {
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 */,
@ -870,7 +845,7 @@ static SLJIT_CONST sljit_uw sljit_mem16_imm5[12] = {
#define MEM_IMM8 0xc00
#define MEM_IMM12 0x800000
static SLJIT_CONST sljit_uw sljit_mem32[12] = {
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 */,
@ -911,69 +886,71 @@ static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sl
/* 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_si other_r, shift;
SLJIT_ASSERT(arg & SLJIT_MEM);
if (SLJIT_UNLIKELY(flags & UPDATE)) {
if ((arg & 0xf) && !(arg & 0xf0) && argw <= 0xff && argw >= -0xff) {
flags &= ~UPDATE;
arg &= 0xf;
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 (flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
return 0;
}
if (SLJIT_UNLIKELY(arg & 0xf0)) {
argw &= 0x3;
tmp = (arg >> 4) & 0xf;
arg &= 0xf;
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
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)));
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(tmp) | (argw << 4)));
FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4)));
return -1;
}
if (!(arg & 0xf) || argw > 0xfff || argw < -0xff)
return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
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]) {
tmp = 3;
shift = 3;
if (IS_WORD_SIZE(flags)) {
if (OFFSET_CHECK(0x1f, 2))
tmp = 2;
shift = 2;
}
else if (flags & BYTE_SIZE)
{
if (OFFSET_CHECK(0x1f, 0))
tmp = 0;
shift = 0;
}
else {
SLJIT_ASSERT(flags & HALF_SIZE);
if (OFFSET_CHECK(0x1f, 1))
tmp = 1;
shift = 1;
}
if (tmp != 3) {
FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - tmp))));
if (shift != 3) {
FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - shift))));
return -1;
}
}
@ -996,12 +973,13 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags,
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))
sljit_sw diff;
if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM))
return 0;
if (!(arg & 0xf)) {
if ((sljit_uw)(argw - next_argw) <= 0xfff || (sljit_uw)(next_argw - argw) <= 0xfff)
if (!(arg & REG_MASK)) {
diff = argw - next_argw;
if (diff <= 0xfff && diff >= -0xfff)
return 1;
return 0;
}
@ -1009,17 +987,19 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_
if (argw == next_argw)
return 1;
if (arg == next_arg && ((sljit_uw)(argw - next_argw) <= 0xfff || (sljit_uw)(next_argw - argw) <= 0xfff))
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)
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_si tmp_r, other_r;
sljit_sw diff;
SLJIT_ASSERT(arg & SLJIT_MEM);
if (!(next_arg & SLJIT_MEM)) {
@ -1029,69 +1009,76 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji
tmp_r = (flags & STORE) ? TMP_REG3 : reg;
if (SLJIT_UNLIKELY(flags & UPDATE)) {
flags &= ~UPDATE;
if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) {
/* Update only applies if a base register exists. */
if (arg & 0xf) {
/* There is no caching here. */
tmp = (arg & 0xf0) >> 4;
arg &= 0xf;
/* There is no caching here. */
other_r = OFFS_REG(arg);
arg &= 0xf;
flags &= ~UPDATE;
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 (!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;
}
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;
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;
other_r = 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));
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;
}
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));
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) {
if (!((argw - compiler->cache_argw) & ~0xfff))
return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | (argw - compiler->cache_argw));
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, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
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 & 0xf) && (arg == next_arg);
next_arg = (arg & REG_MASK) && (arg == next_arg) && (argw != next_argw);
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));
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) {
@ -1103,7 +1090,8 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji
FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
compiler->cache_arg = SLJIT_MEM;
if (next_arg) {
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;
@ -1270,11 +1258,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
op = GET_OPCODE(op);
switch (op) {
case SLJIT_BREAKPOINT:
push_inst16(compiler, BKPT);
break;
return push_inst16(compiler, BKPT);
case SLJIT_NOP:
push_inst16(compiler, NOP);
break;
return push_inst16(compiler, NOP);
case SLJIT_UMUL:
case SLJIT_SMUL:
return push_inst32(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
@ -1321,7 +1307,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
compiler->cache_arg = 0;
compiler->cache_argw = 0;
dst_r = (dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REG3) ? dst : TMP_REG1;
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
op = GET_OPCODE(op);
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
@ -1454,7 +1440,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
compiler->cache_arg = 0;
compiler->cache_argw = 0;
dst_r = (dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REG3) ? dst : TMP_REG1;
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))
@ -1505,9 +1491,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
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) {
@ -1550,7 +1533,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 FPU_LOAD (1 << 20)
@ -1564,20 +1552,21 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
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)));
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 & 0xf) && (argw & 0x3) == 0) {
if ((arg & REG_MASK) && (argw & 0x3) == 0) {
if (!(argw & ~0x3fc))
return push_inst32(compiler, inst | 0x800000 | RN4(arg & 0xf) | DD4(reg) | (argw >> 2));
return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | DD4(reg) | (argw >> 2));
if (!(-argw & ~0x3fc))
return push_inst32(compiler, inst | RN4(arg & 0xf) | DD4(reg) | (-argw >> 2));
return push_inst32(compiler, inst | RN4(arg & REG_MASK) | DD4(reg) | (-argw >> 2));
}
SLJIT_ASSERT(!(arg & 0xf0));
/* Slow cases */
SLJIT_ASSERT(!(arg & OFFS_REG_MASK));
if (compiler->cache_arg == arg) {
tmp = argw - compiler->cache_argw;
if (!(tmp & ~0x3fc))
@ -1591,20 +1580,20 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
}
}
if (arg & 0xf) {
if (emit_set_delta(compiler, TMP_REG1, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED) {
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 & 0xf) | 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 & 0xf) | imm));
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));
}
}
@ -1612,13 +1601,9 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
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))));
}
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));
}
@ -1649,7 +1634,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
return push_inst32(compiler, VMRS);
}
dst_r = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst;
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;
@ -1668,9 +1653,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
break;
}
if (dst & SLJIT_MEM)
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw);
return SLJIT_SUCCESS;
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,
@ -1687,7 +1672,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
compiler->cache_argw = 0;
op ^= SLJIT_SINGLE_OP;
dst_r = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst;
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;
@ -1712,9 +1697,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
break;
}
if (dst & SLJIT_MEM)
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw);
return SLJIT_SUCCESS;
if (!(dst & SLJIT_MEM))
return SLJIT_SUCCESS;
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw);
}
#undef FPU_LOAD
@ -1733,7 +1718,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 (dst <= REG_MASK)
return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3));
/* Memory. */
@ -1752,7 +1737,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 (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))
@ -1846,7 +1831,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
{
struct sljit_jump *jump;
sljit_si cc;
sljit_ins cc;
CHECK_ERROR_PTR();
check_sljit_emit_jump(compiler, type);
@ -1885,25 +1870,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
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)
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));
}
return SLJIT_SUCCESS;
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,
@ -1912,8 +1895,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
sljit_si type)
{
sljit_si dst_r, flags = GET_ALL_FLAGS(op);
sljit_ins ins;
sljit_uw cc;
sljit_ins cc, ins;
CHECK_ERROR();
check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
@ -1925,7 +1907,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
op = GET_OPCODE(op);
cc = get_cc(type);
dst_r = (dst <= TMP_REG3) ? dst : TMP_REG2;
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));
@ -1936,11 +1918,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
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;
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) && dst <= TMP_REG3 && dst == src) {
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));
@ -1956,18 +1940,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
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;
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_REG1, srcw));
src = TMP_REG1;
FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
src = TMP_REG2;
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 (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));
@ -1993,7 +1984,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
PTR_FAIL_IF(!const_);
set_const(const_, compiler);
dst_r = (dst <= TMP_REG3) ? dst : TMP_REG1;
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value));
if (dst & SLJIT_MEM)
@ -2003,12 +1994,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
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_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;
sljit_uh *inst = (sljit_uh*)addr;
modify_imm32_const(inst, new_constant);
SLJIT_CACHE_FLUSH(inst, inst + 3);
SLJIT_CACHE_FLUSH(inst, inst + 4);
}

View file

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

View file

@ -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);
}

View file

@ -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(32)" 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,7 +448,23 @@ 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;
@ -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
@ -1121,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));
@ -1150,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;
}
@ -1185,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;
}
@ -1229,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;
@ -1241,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;
@ -1309,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. */
@ -1322,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));
@ -1357,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) \
@ -1467,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. */
@ -1631,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;
}
@ -1714,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
@ -1770,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);
@ -1779,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;
}
@ -1853,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)
@ -1877,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));

View file

@ -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;

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View file

@ -87,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)
@ -190,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;
@ -311,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) {
@ -465,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;
}
@ -516,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;
}
@ -540,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;
}
@ -566,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 {
@ -658,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)
@ -689,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) {
@ -708,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)
@ -943,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))
@ -963,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;
}
@ -980,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;
}
@ -1031,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;
@ -1043,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;
@ -1114,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)
@ -1127,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);
}
@ -1269,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));
@ -1285,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));
@ -1305,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);
@ -1327,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;
@ -1368,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_;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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
@ -245,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));
@ -301,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);
@ -311,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. */
}
@ -393,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;
@ -402,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) {
@ -420,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 {
@ -495,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);
@ -524,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);

View file

@ -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) {

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
#! /bin/sh
# test-driver - basic testsuite driver script.
scriptversion=2012-06-27.10; # UTC
scriptversion=2013-07-13.22; # UTC
# Copyright (C) 2011-2013 Free Software Foundation, Inc.
#
@ -44,13 +44,12 @@ print_usage ()
Usage:
test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
[--expect-failure={yes|no}] [--color-tests={yes|no}]
[--enable-hard-errors={yes|no}] [--] TEST-SCRIPT
[--enable-hard-errors={yes|no}] [--]
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
END
}
# TODO: better error handling in option parsing (in particular, ensure
# TODO: $log_file, $trs_file and $test_name are defined).
test_name= # Used for reporting.
log_file= # Where to save the output of the test script.
trs_file= # Where to save the metadata of the test run.
@ -69,10 +68,23 @@ while test $# -gt 0; do
--enable-hard-errors) enable_hard_errors=$2; shift;;
--) shift; break;;
-*) usage_error "invalid option: '$1'";;
*) break;;
esac
shift
done
missing_opts=
test x"$test_name" = x && missing_opts="$missing_opts --test-name"
test x"$log_file" = x && missing_opts="$missing_opts --log-file"
test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
if test x"$missing_opts" != x; then
usage_error "the following mandatory options are missing:$missing_opts"
fi
if test $# -eq 0; then
usage_error "missing argument"
fi
if test $color_tests = yes; then
# Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
red='' # Red.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -207,7 +207,7 @@ correctly, but that messes up comparisons). --/
CDBABC
\x{2000}ABC
/\R*A/SI8
/\R*A/SI8<bsr_unicode>
CDBABC
\x{2028}A

View file

@ -907,6 +907,9 @@
/\U/I
/a{1,3}b/U
ab
/[/I
/[a-/I
@ -4045,4 +4048,18 @@ backtracking verbs. --/
/[a[:<:]] should give error/
/(?=ab\K)/+
abcd
/abcd/f<lf>
xx\nxabcd
/ -- Test stack check external calls --/
/(((((a)))))/Q0
/(((((a)))))/Q1
/(((((a)))))/Q
/-- End of testinput2 --/

View file

@ -1,6 +1,6 @@
/-- Tests for the 32-bit library only */
< forbid 8w
< forbid 8W
/-- Check maximum character size --/

View file

@ -1,6 +1,9 @@
/-- 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

View file

@ -716,4 +716,10 @@
/^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 --/

View file

@ -788,4 +788,6 @@
/^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 --/

View file

@ -1484,4 +1484,13 @@
\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 --/

View file

@ -829,4 +829,10 @@ of case for anything other than the ASCII letters. --/
/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/8WBZ
/[RST]+/8iWBZ
/[R-T]+/8iWBZ
/[Q-U]+/8iWBZ
/-- End of testinput7 --/

View file

@ -8,7 +8,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
/(?(?C1)(?=a)a)/S+I
@ -27,7 +27,7 @@ No options
No first char
No need char
Subject length lower bound = -1
No set of starting bytes
No starting char list
JIT study was not successful
/abc/S+I>testsavedregex
@ -36,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
@ -165,7 +165,7 @@ 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++

View file

@ -8,7 +8,7 @@ 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

View file

@ -361,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
@ -388,7 +388,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
/\H/SI
Capturing subpattern count = 0
@ -396,7 +396,7 @@ No options
No first char
No need char
Subject length lower bound = 1
No set of starting bytes
No starting char list
/\v/SI
Capturing subpattern count = 0
@ -404,7 +404,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
/\V/SI
Capturing subpattern count = 0
@ -412,7 +412,7 @@ No options
No first char
No need char
Subject length lower bound = 1
No set of starting bytes
No starting char list
/\R/SI
Capturing subpattern count = 0
@ -420,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
------------------------------------------------------------------

View file

@ -481,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
@ -519,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}
@ -539,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
------------------------------------------------------------------
@ -558,7 +558,7 @@ 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
------------------------------------------------------------------
@ -577,7 +577,7 @@ 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
------------------------------------------------------------------
@ -597,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
------------------------------------------------------------------
@ -799,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}
@ -825,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}
@ -845,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
@ -855,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
@ -863,7 +863,7 @@ Options: utf
No first char
Need char = 'x'
Subject length lower bound = 4
Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 x
Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 x
/\sxxx\s/I8ST1
Capturing subpattern count = 0
@ -871,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
@ -883,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
@ -917,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
@ -925,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
@ -933,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
@ -941,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
------------------------------------------------------------------
@ -974,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
------------------------------------------------------------------

View file

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

View file

@ -228,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
@ -274,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}
@ -292,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}
@ -304,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}
@ -330,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
@ -348,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
@ -360,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
@ -378,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
@ -534,18 +534,18 @@ MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789AB
------------------------------------------------------------------
Bra
a*
[b-\x{200}]?+
[b-\xff\x{100}-\x{200}]?+
a#
a*+
[b-\x{200}]?
[b-\xff\x{100}-\x{200}]?
b#
[a-f]*
[g-\x{200}]*+
[a-f]*+
[g-\xff\x{100}-\x{200}]*+
#
[g-\x{200}]*
[g-\xff\x{100}-\x{200}]*+
[a-c]*+
#
[g-\x{200}]*
[g-\xff\x{100}-\x{200}]*
[a-h]*+
Ket
End

View file

@ -339,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
@ -378,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}
@ -398,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
------------------------------------------------------------------
@ -417,7 +417,7 @@ 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
------------------------------------------------------------------
@ -436,7 +436,7 @@ 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
------------------------------------------------------------------
@ -456,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
------------------------------------------------------------------
@ -666,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}
@ -692,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}
@ -712,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<bsr_unicode>
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
@ -736,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
@ -744,7 +744,7 @@ Options: utf
No first char
Need char = 'x'
Subject length lower bound = 4
Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 x
Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 x
/\sxxx\s/I8ST1
Capturing subpattern count = 0
@ -752,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
@ -764,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
@ -803,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
@ -811,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
@ -819,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
@ -827,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
------------------------------------------------------------------
@ -860,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 --/

View file

@ -337,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
@ -376,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}
@ -396,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
------------------------------------------------------------------
@ -415,7 +415,7 @@ 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
------------------------------------------------------------------
@ -434,7 +434,7 @@ 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
------------------------------------------------------------------
@ -454,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
------------------------------------------------------------------
@ -663,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}
@ -689,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}
@ -709,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<bsr_unicode>
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
@ -733,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
@ -741,7 +741,7 @@ Options: utf
No first char
Need char = 'x'
Subject length lower bound = 4
Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 x
Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 x
/\sxxx\s/I8ST1
Capturing subpattern count = 0
@ -749,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
@ -761,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
@ -800,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
@ -808,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
@ -816,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
@ -824,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
------------------------------------------------------------------
@ -857,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 --/

View file

@ -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}

View file

@ -178,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
@ -190,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
@ -202,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
@ -210,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
@ -231,7 +231,7 @@ No options
No first char
No need char
Subject length lower bound = 1
Starting byte set: \x09 \x0a \x0b \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
@ -512,7 +512,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
/(?i)[abcd]/IS
Capturing subpattern count = 0
@ -520,7 +520,7 @@ Options: caseless
No first char
No need char
Subject length lower bound = 1
Starting byte set: A B C D a b c d
Starting chars: A B C D a b c d
/(?m)[xy]|(b|c)/IS
Capturing subpattern count = 1
@ -528,7 +528,7 @@ Options: multiline
No first char
No need char
Subject length lower bound = 1
Starting byte set: b c x y
Starting chars: b c x y
/(^a|^b)/Im
Capturing subpattern count = 1
@ -591,7 +591,7 @@ No options
First char = 'b' (caseless)
No need char
Subject length lower bound = 1
No set of starting bytes
No starting char list
/(a*b|(?i:c*(?-i)d))/IS
Capturing subpattern count = 1
@ -599,7 +599,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
/a$/I
Capturing subpattern count = 0
@ -666,7 +666,7 @@ No options
No first char
No need char
Subject length lower bound = 1
Starting byte set: a b
Starting chars: a b
/(?<!foo)(alpha|omega)/IS
Capturing subpattern count = 1
@ -675,7 +675,7 @@ No options
No first char
Need char = 'a'
Subject length lower bound = 5
Starting byte set: a o
Starting chars: a o
/(?!alphabet)[ab]/IS
Capturing subpattern count = 0
@ -683,7 +683,7 @@ No options
No first char
No need char
Subject length lower bound = 1
Starting byte set: a b
Starting chars: a b
/(?<=foo\n)^bar/Im
Capturing subpattern count = 0
@ -1642,7 +1642,7 @@ Options: anchored
No first char
Need char = 'd'
Subject length lower bound = 4
No set of starting bytes
No starting char list
/\( # ( at start
(?: # Non-capturing bracket
@ -1875,7 +1875,7 @@ 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
Starting chars: 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
@ -1937,7 +1937,7 @@ No options
No first char
No need char
Subject length lower bound = 1
Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20
Starting chars: \x09 \x0a \x0b \x0c \x0d \x20
/^[[:cntrl:]]/DZ
------------------------------------------------------------------
@ -3178,6 +3178,10 @@ 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
/a{1,3}b/U
ab
0: ab
/[/I
Failed: missing terminating ] for character class at offset 1
@ -3434,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
@ -3454,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
@ -3488,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
@ -3496,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
@ -3537,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
@ -3856,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
@ -4637,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!!
@ -4656,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
------------------------------------------------------------------
@ -4677,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
------------------------------------------------------------------
@ -4750,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*
@ -4893,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)
@ -5127,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)
@ -5607,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
<testsavedregex
@ -5642,7 +5646,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
<testsavedregex
@ -5677,7 +5681,7 @@ No options
No first char
No need char
Subject length lower bound = 1
Starting byte set: a b
Starting chars: a b
Compiled pattern written to testsavedregex
Study data written to testsavedregex
<testsavedregex
@ -5716,7 +5720,7 @@ No options
No first char
No need char
Subject length lower bound = 1
Starting byte set: a b
Starting chars: a b
Compiled pattern written to testsavedregex
Study data written to testsavedregex
<testsavedregex
@ -6431,7 +6435,7 @@ No options
No first char
Need char = ','
Subject length lower bound = 1
Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 ,
Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 ,
\x0b,\x0b
0: \x0b,\x0b
\x0c,\x0d
@ -6738,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
@ -6746,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
@ -6754,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
@ -6762,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
@ -6770,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
@ -6778,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
@ -6786,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
------------------------------------------------------------------
@ -6879,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
@ -6887,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
@ -6895,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
@ -6903,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
/((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
@ -9307,7 +9311,7 @@ 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
@ -10096,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
@ -10105,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
@ -10113,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
@ -10122,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
@ -10131,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
@ -10140,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
@ -10149,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
@ -10157,7 +10161,7 @@ Options: anchored
No first char
Need char = ':'
Subject length lower bound = 22
No set of starting bytes
No starting char list
/<tr([\w\W\s\d][^<>]{0,})><TD([\w\W\s\d][^<>]{0,})>([\d]{0,}\.)(.*)((<BR>([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/isIS
Capturing subpattern count = 11
@ -10165,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
@ -10173,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
@ -10181,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
@ -10189,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
@ -10197,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[\s]+href[\s]*=[\s]* # find <a href=
([\"\'])? # find single or double quote
@ -10210,7 +10214,7 @@ Options: caseless extended dotall
First char = '<'
Need char = '='
Subject length lower bound = 9
No set of starting bytes
No starting char list
/^(?!:) # colon disallowed at start
(?: # start of item
@ -10226,7 +10230,7 @@ Options: anchored caseless extended
No first char
Need char = ':'
Subject length lower bound = 2
No set of starting bytes
No starting char list
/(?|(?<a>A)|(?<a>B))/I
Capturing subpattern count = 1
@ -10450,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:
@ -10464,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
@ -10476,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
@ -10486,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:
@ -11080,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
@ -11088,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
@ -11369,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
@ -11377,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
@ -11385,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
@ -11393,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
@ -11711,7 +11715,7 @@ No options
First char = 't'
Need char = 't'
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:|<input\b.*?\btype\b\W*?\bimage\b|\bonkeyup\b\W*?\=/IS
Capturing subpattern count = 0
@ -11720,7 +11724,7 @@ No options
No first char
No need char
Subject length lower bound = 8
Starting byte set: < o t u
Starting chars: < o t u
/a(*SKIP)c|b(*ACCEPT)|/+S!I
Capturing subpattern count = 0
@ -11729,7 +11733,7 @@ No options
No first char
No need char
Subject length lower bound = -1
No set of starting bytes
No starting char list
a
0:
0+
@ -11740,7 +11744,7 @@ No options
No first char
No need char
Subject length lower bound = -1
Starting byte set: a b x
Starting chars: a b x
ax
0: x
@ -12436,7 +12440,7 @@ 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+
@ -12722,7 +12726,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 2
Starting byte set: a z
Starting chars: a z
aaaaaaaaaaaaaz
Error -21 (recursion limit exceeded)
aaaaaaaaaaaaaz\Q1000
@ -12735,7 +12739,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 2
Starting byte set: a z
Starting chars: a z
aaaaaaaaaaaaaz
Error -21 (recursion limit exceeded)
@ -12746,7 +12750,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 2
Starting byte set: a z
Starting chars: a z
aaaaaaaaaaaaaz
No match
aaaaaaaaaaaaaz\Q10
@ -12790,7 +12794,7 @@ Options: dupnames
First char = 'a'
Need char = 'z'
Subject length lower bound = 5
No set of starting bytes
No starting char list
/a*[bcd]/BZ
------------------------------------------------------------------
@ -13902,7 +13906,7 @@ No options
No first char
Need char = 'd'
Subject length lower bound = 1
Starting byte set: a b c d
Starting chars: a b c d
/[a-c]+d/DZS
------------------------------------------------------------------
@ -13917,7 +13921,7 @@ No options
No first char
Need char = 'd'
Subject length lower bound = 2
Starting byte set: a b c
Starting chars: a b c
/[a-c]?d/DZS
------------------------------------------------------------------
@ -13932,7 +13936,7 @@ No options
No first char
Need char = 'd'
Subject length lower bound = 1
Starting byte set: a b c d
Starting chars: a b c d
/[a-c]{4,6}d/DZS
------------------------------------------------------------------
@ -13947,7 +13951,7 @@ No options
No first char
Need char = 'd'
Subject length lower bound = 5
Starting byte set: a b c
Starting chars: a b c
/[a-c]{0,6}d/DZS
------------------------------------------------------------------
@ -13962,7 +13966,7 @@ No options
No first char
Need char = 'd'
Subject length lower bound = 1
Starting byte set: a b c d
Starting chars: a b c d
/-- End of special auto-possessive tests --/
@ -14125,4 +14129,24 @@ 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<lf>
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 --/

View file

@ -50,7 +50,7 @@ Options: anchored extended
No first char
No need char
Subject length lower bound = 6
No set of starting bytes
No starting char list
<!testsaved16BE-1
Compiled pattern loaded from testsaved16BE-1
@ -83,7 +83,7 @@ Options: anchored extended
No first char
No need char
Subject length lower bound = 6
No set of starting bytes
No starting char list
<!testsaved32LE-1
Compiled pattern loaded from testsaved32LE-1

View file

@ -62,7 +62,7 @@ Options: anchored extended
No first char
No need char
Subject length lower bound = 6
No set of starting bytes
No starting char list
<!testsaved32BE-1
Compiled pattern loaded from testsaved32BE-1
@ -95,6 +95,6 @@ Options: anchored extended
No first char
No need char
Subject length lower bound = 6
No set of starting bytes
No starting char list
/-- End of testinput21 --/

View file

@ -37,7 +37,7 @@ Options: extended utf
No first char
No need char
Subject length lower bound = 2
No set of starting bytes
No starting char list
<!testsaved16BE-2
Compiled pattern loaded from testsaved16BE-2
@ -64,7 +64,7 @@ Options: extended utf
No first char
No need char
Subject length lower bound = 2
No set of starting bytes
No starting char list
<!testsaved32LE-2
Compiled pattern loaded from testsaved32LE-2

View file

@ -49,7 +49,7 @@ Options: extended utf
No first char
No need char
Subject length lower bound = 2
No set of starting bytes
No starting char list
<!testsaved32BE-2
Compiled pattern loaded from testsaved32BE-2
@ -76,6 +76,6 @@ Options: extended utf
No first char
No need char
Subject length lower bound = 2
No set of starting bytes
No starting char list
/-- End of testinput22 --/

View file

@ -18,7 +18,7 @@ Failed: character value in \x{} or \o{} is too large at offset 8
/[\H]/BZSI
------------------------------------------------------------------
Bra
[\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffff}]
[\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffff}]
Ket
End
------------------------------------------------------------------
@ -27,12 +27,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{ffff}]
[\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffff}]
Ket
End
------------------------------------------------------------------
@ -41,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 --/

View file

@ -1,6 +1,6 @@
/-- Tests for the 32-bit library only */
< forbid 8w
< forbid 8W
/-- Check maximum character size --/
@ -65,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
------------------------------------------------------------------
@ -74,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
------------------------------------------------------------------
@ -88,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 --/

View file

@ -1,6 +1,9 @@
/-- 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
@ -90,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
@ -99,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
ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â
ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ

174
pcre/testdata/testoutput3A vendored Normal file
View file

@ -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 --/

Some files were not shown because too many files have changed in this diff Show more